Invite-Only Early AccessThink Throo GitHub App AI features (PR reviews, architecture checks) are currently in invite-only mode. Request access here.

Docmost Codebase Architecture

Components structure in docmost frontend/s/general

/s/general

In this article, we are going to review component structure in Docmost Frontend. We will look at

  1. /s/:spaceSlug route in App.tsx

  2. SpaceHome page

  3. SpaceHomeTabs component

  4. RecentChanges component

/s/:spaceSlug route in App.tsx

  1. When you visit this url - https://myworkspace-656033.docmost.com/s/general, you will see the below screen

  1. Lets locate this in the docmost codebase. If you visit docmost/apps/src/client/App.tsx

At line 70 you will find this below code 

<Route path={"/s/:spaceSlug"} element={<SpaceHome />} />

   considering the url which is myworkspace.dockmost.com/s/general here general is the space slug

SpaceHome page

You will find the spacehome page in pages/space/space-home.tsx .

We will analyze the components used and where they are imported from.

Below is the code written by the spacehome component.

return (
        <>
            <Helmet>
                <title>{space?.name || 'Overview'} - {getAppName()}</title>
            </Helmet>
            <Container size={"800"} pt="xl">
                {space && <SpaceHomeTabs/>}
            </Container>
        </>
    );

Helmet is imported as shown below.

import {Helmet} from "react-helmet-async";

The container is imported as shown below.

import {Container} from "@mantine/core";

So far we have seen that page imports components from features folder.

SpaceHomeTabs component

You will find space home tabs component in features/space/components/space-home-tabs. tsx

You will find the below code returned in space home tabs component.

<Tabs defaultValue="recent">
      <Tabs.List>
        <Tabs.Tab value="recent" leftSection={<IconClockHour3 size={18} />}>
          <Text size="sm" fw={500}>
            {t("Recently updated")}
          </Text>
        </Tabs.Tab>
      </Tabs.List>

      <Space my="md" />

      <Tabs.Panel value="recent">
        {space?.id && <RecentChanges spaceId={space.id} />}
      </Tabs.Panel>
    </Tabs>

Tabs,text,space are imported as shown below.

import { Text, Tabs, Space } from "@mantine/core";

Recent changes is imported as shown below

import RecentChanges from "@/components/common/recent-changes.tsx";

So far we have seen that page imports components from features folder, features folder if required imports components from components folder that is outside of the features folder

RecentChanges component

You will find recent changes in components/common/recent-changes.tsx

The below code is returned by the recent changes Component.

return pages && pages.items.length > 0 ? (
    <Table.ScrollContainer minWidth={500}>
      <Table highlightOnHover verticalSpacing="sm">
        <Table.Tbody>
          {pages.items.map((page) => (
            <Table.Tr key={page.id}>
              <Table.Td>
                <UnstyledButton
                  component={Link}
                  to={buildPageUrl(page?.space.slug, page.slugId, page.title)}

                >

                  <Group wrap="nowrap">
                    {page.icon || (
                      <ActionIcon variant='transparent' color='gray' size={18}>
                        <IconFileDescription size={18}/>
                      </ActionIcon>
                    )}
 <Text fw={500} size="md" lineClamp={1}>
                      {page.title || t("Untitled")}
                    </Text>
                  </Group>
                </UnstyledButton>
              </Table.Td>
              {!spaceId && (
                <Table.Td>
                  <Badge
                    color="blue"
                    variant="light"
                    component={Link}
                    to={getSpaceUrl(page?.space.slug)}
                    style={{cursor: 'pointer'}}

                  >

                    {page?.space.name}
                  </Badge>
                </Table.Td>
              )}
              <Table.Td>
                <Text c="dimmed" style={{whiteSpace: 'nowrap'}} size="xs" fw={500}>
                  {formattedDate(page.updatedAt)}
                </Text>
              </Table.Td>
            </Table.Tr>
          ))}
        </Table.Tbody>
      </Table>
    </Table.ScrollContainer>
  ) : (
    <Text size="md" ta="center">
      {t("No pages yet")}
    </Text>
  );

Since the top most uses mantine below are the components imported from @maintine/core.

import {
  Text,
  Group,
  UnstyledButton,
  Badge,
  Table,
  ActionIcon,
} from '@mantine/core';

PageListSkeleton

Page list skeleton is used as a loader when the data is being fetched and this is shown using the below code.

 if (isLoading) {
    return <PageListSkeleton/>;
  }

Page list skeleton is imported as shown below.

import PageListSkeleton from '@/components/ui/page-list-skeleton.tsx';  

Now we have seen that recent changes to components uses another component imported from Component/UI.

To summarize this analysis, what we found is that page imports components from Features folder and the components inside Features folder can import components from another folder called Components that's outside of the Features folder and this component inside Components folder can also use components located in component/UI folder.

References

  1. https://github.com/docmost/docmost/blob/main/apps/client/src/App.tsx

  2. https://github.com/docmost/docmost/blob/main/apps/client/src/pages/space/space-home.tsx#L8

  3. https://github.com/docmost/docmost/blob/main/apps/client/src/features/space/components/space-home-tabs.tsx#L8

  4. https://github.com/docmost/docmost/blob/main/apps/client/src/components/common/recent-changes.tsx#L22