Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conversion to static view from smart search view #533

Open
ev-sc opened this issue Jan 5, 2022 · 2 comments
Open

Conversion to static view from smart search view #533

ev-sc opened this issue Jan 5, 2022 · 2 comments

Comments

@ev-sc
Copy link
Contributor

ev-sc commented Jan 5, 2022

Description

The "convert to static view" button on the single view layout of a smart search view does not really implement a conversion. Instead, it just deletes everyone from that view, which is the opposite of what I would expect to happen. The button should really be labelled "clear and start a new smart search" or something like that. For a conversion, I would expect all of the people who match the current smart search parameters to be copied across to the new static view.

Relevant Job Stories

When I convert a smart search view to a static view I want the new static view to be populated with all the people who match the parameters of the existing smart search, so I don't have to add them manually.

When I use a smart search to create a view, I want to be able to take a snapshot of that view and save it by converting the smart search view to a static view, so I can manually add and remove small numbers of people who don't match/falsely match the smart search criteria.

Prerequisites

One or more API routes?

Requirements

TBC

Possible implementations

Design specifications

Open questions

@richardolsson
Copy link
Member

These are some great ideas! But how is this different from #532?

@richardolsson
Copy link
Member

I understand now that this is different in that #532 only concerns changing the label as a minor fix alternative for this bigger feature.

I think you've pointed out something that is really worth pursuing here. From my perspective, being familiar with the underlying data models and workings of the API, I would not consider this a bug. In fact it seemed logical to me that it would work this way. But it's clearly something that will stump users, so in that sense it is a defect and needs to be remedied somehow.

I just want to add some context, not to argue it should stay this way, but so that we can make informed decisions together about how to design the UX in a way that users will be able to make sense of, or at least communicate what actually happens when converting from one to the other.

What is a "static view"?

All views consist of columns and rows. The columns are configured on the view, and then people can be added as rows.

PUT /orgs/1/people/views/1/rows/123

HTTP/1.1 201 CREATED
PUT /orgs/1/people/views/1/rows/321

HTTP/1.1 201 CREATED

Fetching the /rows API endpoint will retrieve a row for every person that has been added to the view, with each row containing an array of values, one for each column.

GET /orgs/1/people/views/1/rows

HTTP/1.1 200 OK
Content-Type: application/json

{
  "data": [
    { "id": 123, "content": ["Clara", "Zetkin", true] },
    { "id": 321, "content": ["Richard", "Olsson", false] }
  ]
}

The "static" vs "dynamic" dichotomy has been introduced during R30. Until now, all views worked this way, which is what we now think of as "static views", i.e. you have to manually add people to the view for them to show up when /rows is fetched.

What is a "dynamic view"?

For as long as views have existed in Zetkin, there has always been a special way in the API that views could be used, which is to append a ?view_id=123 query string parameter when fetching the matches for a Smart Search (in a completely separate part of the API). That way, any Smart Search query could be retrieved "through a view", meaning that the people matching that query would be returned not as a normal list of person objects, but as if they were rows in the view, i.e. with the same values format as retrieving /rows from a view.

GET /orgs/1/people/queries/1/matches?view_id=1

HTTP/1.1 200 OK
Content-Type: application/json

{
  "data": [
    { "id": 123, "content": ["Clara", "Zetkin", true] },
    { "id": 321, "content": ["Richard", "Olsson", false] }
  ]
}

…instead of…

GET /orgs/1/people/queries/1/matches

HTTP/1.1 200 OK
Content-Type: application/json

{
  "data": [
    { "id": 123, "first_name": "Clara", "last_name": "Zetkin", "phone": "clara@zetkin.org" },
    { "id": 321, "first_name": "Richard", "last_name": "Olsson", "phone": "richard@zetkin.org" }
  ]
}

We used this API capability to build a UI in Gen2 where you could open a view (with or without rows) and then pick a Smart Search query from a list of the saved queries in your organization to load that query "through the view". But this concept had a big limitation, which was that the query-view relationship was not stored anywhere, so the user would have to always find and pick that same query every time they came back to the view. In some use cases this was not a problem, but in other use cases it was. That's where you'd really want a "dynamic view".

A dynamic view (introduced during R30) is a view with a Smart Search query attached to it. Retrieving the rows of a dynamic view (at the regular /rows API endpoint) will return a row for every person matching that Smart Search query at the time of retrieving it. From a user's perspective, a dynamic view does not have any statically defined rows.

Internally in the Zetkin Platform, the term "dynamic view" is not really used. A view is considered dynamic when there is a query. If there is a query, it will be used to determine the rows, otherwise statically added rows will be returned.

It's actually possible in the API to add rows manually to a view with a query (i.e. a "dynamic view"). They just won't be returned by /rows, because as long as there is a query configured on the view, the /rows resource will return the query matches as described above.

Converting from static to dynamic

Converting a static view to a dynamic view only means attaching a Smart Search query. It doesn't actually delete any previously added static rows, but because the view will now have a query, the API stops returning the statically defined rows and starts returning the query matches instead.

This means that converting from static to dynamic is not destructive. You could "undo" it by just deleting the query from the view again.

Converting from dynamic to static

Turning a dynamic view into a static view means deleting the associated Smart Search query. This causes the API to start returning any statically defined rows instead. If none had previously been added, the view will be empty.

This is destructive only in the sense that the query is lost. You could attach an identical query and get back the same results as before converting, but you would have to configure that query yourself and if it was complex that might be difficult. If you do attach a query again (identical or otherwise) any people that were previously "in the view" will return as if nothing happened.

Converting from static to dynamic and back again (and back again)

Imagine creating a "static view" (A) and adding some rows to it manually (B). When you convert it to dynamic (C), you do so by adding a query (D) but we don't actually delete the original rows. They're just no longer returned from the /rows endpoint.

Converting it back by removing the query (E) will cause those rows that were previously added (in step B) return at the /rows endpoint.

Attaching a query again that is identical to D will "undo" what happened in step E.

What about local data?

Views can have local data. Most view columns load in data from other parts of Zetkin (and that's the power of Views over something like spreadsheets) but some column types (the ones beginning with local_) actually store their data in the view itself. You use this to store data that is local to the domain of work in which the view is relevant, e.g. a checkbox for who's been contacted in a View built to track outreach to a group of people.

The local data is associated with the person in a way that means it's not lost (as long as the person still exists in the Zetkin database), even if that person is deleted from the view. This means that if a person is removed from a view (or in the case of dynamic views, no longer matches the query) and is then added back again, the local view data will be restored.

As a consequence, no act of conversion will ever cause local data to be lost.

Summary

  • No data is actually lost when converting a view from static to dynamic
  • Only the query configuration is lost when converting a view from dynamic to static

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

No branches or pull requests

2 participants