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

feat(ui): Saved Views #3366

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open

Conversation

jamie-rasmussen
Copy link
Collaborator

@jamie-rasmussen jamie-rasmussen commented Jan 10, 2025

Description

Internal Jira: https://wandb.atlassian.net/browse/WB-21701

Adds "Saved Views" to the UI. Views are saved as Weave objects. Table settings on the Traces and Evaluations pages like filters, sorting, page size, column visibility, and column pinning are stored in the view object.

New views can be saved, views can be updated, renamed, and deleted.

Some screenshots:

Screenshot 2025-02-03 at 4 12 51 PM Screenshot 2025-02-03 at 4 14 07 PM Screenshot 2025-02-03 at 4 12 56 PM

@jamie-rasmussen jamie-rasmussen force-pushed the jamie/hackweek-saved-views branch from 6aa510d to 2d95ee7 Compare January 10, 2025 06:06
@circle-job-mirror
Copy link

@jamie-rasmussen jamie-rasmussen force-pushed the jamie/hackweek-saved-views branch from 2d95ee7 to 52ee76a Compare January 10, 2025 16:45
@jamie-rasmussen jamie-rasmussen force-pushed the jamie/hackweek-saved-views branch 3 times, most recently from 1174218 to 7176507 Compare January 28, 2025 04:46
@jamie-rasmussen jamie-rasmussen force-pushed the jamie/hackweek-saved-views branch 6 times, most recently from f5192c2 to 49e0fb9 Compare February 4, 2025 01:02
@jamie-rasmussen jamie-rasmussen marked this pull request as ready for review February 4, 2025 14:21
@jamie-rasmussen jamie-rasmussen requested review from a team as code owners February 4, 2025 14:21
@tssweeney
Copy link
Collaborator

Starting to dive into review here. Noticing a bug: save a view with a sort applied, change views, change back to the view with the saved sort - it is applied briefly, then resets and drops the sort

@tssweeney
Copy link
Collaborator

Also, not blocking, but for me the interactions are very slow.

];

// Value of the object
type ViewDefinition = Record<string, any>;
Copy link
Collaborator

Choose a reason for hiding this comment

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

View definition is untyped?

}
const className = 'SavedView';
tsClient
.objCreate({
Copy link
Collaborator

Choose a reason for hiding this comment

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

As implemented, because SavedView is not defined on the server, this has no validation. This makes me a bit nervous that this critical data structure is enforced within this component. If you defined a builtin object, you could use useCreateBuiltinObjectInstance which would allow you to simply pass the relevant data:

    project_id: string;
    object_id: string;
    val: T;
    builtin_object_class?: string;

And have val be validated in typescript and enforced on the backend. This feels like a safer approach

tab: string;
};

const CallsPageLastView = ({entity, project, tab}: CallsPageLastViewProps) => {
Copy link
Collaborator

Choose a reason for hiding this comment

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

I would call this RedirectToLastView to emphasize that it is a redirect

const tsClient = getTsClient();
const fetchViews = useCallback(() => {
tsClient
.objsQuery({
Copy link
Collaborator

Choose a reason for hiding this comment

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

Similarly, this could be done with useBaseObjectInstances

return <Loading />;
}
if (!projectInfo) {
return <Alert severity="error">Invalid project: {project}</Alert>;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Here and elsewhere, it seems like we could have a nicer landing 404 / landing page when something is not found


newQuery.set('view', viewToLoad.object_id);
history.push({search: newQuery.toString()});
props.onRecordLastView(viewToLoad.object_id);
Copy link
Collaborator

Choose a reason for hiding this comment

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

will this line run in an unmounted? I am not sure if the execution order ensures this runs before the URL changes

.then(res => {
const newQuery = new URLSearchParams(history.location.search);
newQuery.set('view', objectId);
history.push({search: newQuery.toString()});
Copy link
Collaborator

Choose a reason for hiding this comment

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

same here regarding history

return 'Evaluations';
const currentViewDefinition = useCurrentViewDefinition(baseView);

const history = useHistory();
Copy link
Collaborator

Choose a reason for hiding this comment

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

it is always a bit of a smell to me when a component uses history below the main routing component (in our case Browse3). It means that CallsPage itself is now strictly dependent on the URL and cannot be embedded elsewhere. This particular case seems challenging to separate, so maybe we can punt on this comment. However, we should acknowledge the impact of this change

return {};
}
}, [query.filter, entity, project, tab]);
type CallsPageLastViewProps = {
Copy link
Collaborator

Choose a reason for hiding this comment

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

I would consider moving these helper components / hooks. It seems like we are putting a lot of logic in Browse3 which is highly calls-page specific

const {search} = history.location;
const newQuery = new URLSearchParams(search);
newQuery.set('filter', JSON.stringify(filter));
history.push({search: newQuery.toString()});
Copy link
Collaborator

Choose a reason for hiding this comment

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

I noticed in various places in this PR (and the compare anything project), that we are often doing history.push... with some locally constructed information. The impact of this is that the URL contract is no longer tightly defined, but rather implicitly defined throughout the various component implementations. The idea of weave-js/src/components/PagePanelComponents/Home/Browse3/context.tsx is to centralize all path construction such that we have a single interface definition for construction of URLs. This unification also allows the same URL to work in peek drawers as well as main views. Specifically, something like history.push(routerContext.callsUIUrl(entity, project, filter)); is "smart" enough to perform the appropriate URL update regardless of where it is rendered. It would be nice to keep all URL construction co-located for easier maintenance

@jamie-rasmussen jamie-rasmussen force-pushed the jamie/hackweek-saved-views branch from 49e0fb9 to 2de401e Compare February 6, 2025 16:59
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.

2 participants