Skip to content

Add Code Insights independent MVP

Warren Gifford requested to merge vk/insights-components-restructure into main

Created by: vovakulikov

Since code insights is going to have a bit bigger codebase before implementing a new functionality we need to arrange component structure and import approach.

This PR is about aligning some components and build an independent demo of insights pages which might be useful according to our plans to create new pages for code insights (see layouts of these new pages)

Storybook approach Of course, we can build a storybook story for this but I see a few limitations here

  • We can't run only insights demos by our global storybook approach (it takes some time to compile and run all our components stories, at some point, it would be a problem)
  • It a bit complicated to check pages routing inside one story (since we will have more than one page it's important)

Independent demo approach Ideally, it would be nice to have an independent demo without any parts of the app which directly don't relate to the current part of a product that the demo is about. Speaking about code insights, as a result, we want to run the app with an insight page only and nothing else (see screenshot below)

Screenshot 2021-04-08 at 23 28 22

Independent code insight demo (Notice we run only code insights UI)

For this kind of demo, I created a separate folder on the top level of our flat package structure.

/web
/shared
/wildcard
/sandboxes // <= new store of all independent demo of product
  /code-insight
     ... // <=  code of code insights demo

Mocking data The most interesting part of that approach we can mock everything which we need to render our app and run the frontend locally without a local backend.

A possible solution from this PR. We have to align how we use our fetch services to get data from different sources (backend, extension API)

Let's take a simple component that fetches data from the backend

function PageComponent {
     const views = useObservables(useMemo(() => getViewsFromBackend(), []));

    return (<div> {views} </div>);
}

So the problem with this code above we can't mock getViewsFromBackend call in our storybook story or demo. As a result, we have to run backend locally or mock this on network-level which might be complicated because we can use extensionAPI and in this case, we don't know what exactly we need to mock.

So as a possible approach to avoid this we can write something like this

// backend-api.ts
export class BackendApi {
  getViewsFromBackend() { /* .... fetch data from backend */}
}

export const BackendApiContext = createContext(new BackendApi());

// component.ts
function PageComponent {
     const { getViewsFromBackend } = useContext(BackendApiContext)
     const views = useObservables(useMemo(() => getViewsFromBackend(), []));

    return (<div> {views} </div>);
}

Now we can replace implementation of the BackendApi in our storybook story or demo

// component.story.ts

class MockBackendApi {
    getViewsFromBackend() { /* ... return mock data for demo */ }
}

const mockBackendApi = new MockBackendApi();

function PageComponentStory {
    return (
     <BackendApiContext.Provider value={mockBackendApi}> 
          <PageComponent />
     </BackendApiContext.Provider>
   );
}

So in this case we don't have to change our code if we want to create a story or demo for components which data fetching. Also, this approach provides a convenient way to test our components which have data fetching. This similar to what Apollo Client and MockedProvider provide (reference https://www.apollographql.com/docs/react/development-testing/testing/)

I don't want to suggest you do this across all code base. But just because this is not something super new (this is mostly just a context thing) we can probably try this approach on the code insights code base.

Resolve https://github.com/sourcegraph/sourcegraph/issues/19867

Merge request reports

Loading