Skip to content
MorganeLecurieux edited this page Jan 26, 2023 · 8 revisions

Welcome to the lago-front wiki!

Local environment setup

To install the full app, you can refer to the Lago Wiki

Stack

We are using the following stack and tools for this app :

Main libraries

Code formating & tests

Tools

  • GraphQL Codegen - Auto generate TS code from graphql schemas
  • Ditto - To deal with the translations
  • Storybook - Access all the design system component of the app

Development usefull commands

# Code formating
yarn lint

# Tests
yarn test

# Codegen to generate types from the api schemas
# (make sure the api is running)
yarn codegen
yarn codegen:watch # will run anytime a new file is saved

# Translations
yarn ditto # Pull new translations
yarn ditto:addNew # Register new project from Ditto
yarn inspectTranslations # Check if there are unsused or nudeclared translations

## Test
yarn test # Run all test
yarn test ./src/core/__tests__/whatever.test.ts # Run one test file
yarn test:e2e # Run E2E tests with Cypress (API must be running)

## Storybook
yarn storybook # Locally launch the storybook app

# Bundle analyser
yarn build:analyseBundle

Note : linter and tests are run during the pull request pipelines

Codegen

We're using the Graphql Code Generator to automatically generate TypeScript typings out of a GraphQL schema and typed react apollo hooks for queries, mutations and subscripitons.

Use

  1. Write your query in the gql tag from Apollo-client
  2. Run yarn codegen (or wait for the watcher to regenerate the code)
  3. Import your query or mutation from @/generated/grapqh
  4. Use it as the regular useQuery, useMutation hooks from ApolloClient without re-passing the gql.

Note : you can also import Typescript enums, fragment types, fragmentDoc from ~/generated/grapqh

Note (2): in order to be able to fetch newly added field from the api, you need to re-run the codegen command. A failing codegen will result in the app not working.

File structure

This list is note exhaustive, it display the main file structure and some necessary file explanations (file that could be globally usefull in the app)

├── .changelog
├── .github
│   ├── ISSUE_TEMPLATE
│   └── workflows # all github CI worflows
├── .storybook # only config files
├── .vscode # extension recommandations + snippets
├── __mocks__ # mocks used fo the tests
│   └── svgMock.js
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── CHANGELOG.md
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── Dockerfile
├── Dockerfile.dev
├── LICENSE
├── PULL_REQUEST_TEMPLATE.md
├── README.md
├── codegen.yml
├── cypress # config + all tests files for e2e tests
├── ditto # Translations files -Those files shouldn't be modified directly, use the ditto command lines
├── docker-compose.ci.yml # CI only, used for the e2e tests
├── globals.d.ts # global ts declaration
├── jest.config.js
├── materialUiTheme.d.ts # global ts declaration override for material ui
├── nginx
│   ├── gzip.conf
│   └── nginx.conf
├── package.json
├── renovate.json # conf for the Renovate bot (dealing with dependencies alert / update)
├── scripts
│   ├── InspectTranslationKeys.js # Script to check if some translations keys are unused or undefined (used in the CI)
│   └── MergeTranslationFiles.js # Translations comes with one file per project, this script merge them in one file (automatically done in the yarn:ditto command)
├── src
│   ├── App.tsx # Main component initializing ApolloClient, and the different providers
│   ├── formValidationSchemas # Files to validate complexe objects with YUP
│   ├── components
│   │   ├── RouteWrapper.tsx # Component that deals with the routes formatting
│   │   ├── UserIdentifier.tsx # Component used to identify the user if logged in
│   │   ├── designSystem # All components linked to the design system
│   │   │   └── index.ts
│   │   └── form # All form components
│   │       └── index.ts
│   ├── core
│   │   ├── I18nContext.tsx # i18n relative config (context + provider + hook)
│   │   ├── apolloClient
│   │   │   ├── reactiveVars # contains all the reactive var definitions
│   │   │   │   ├── authTokenVar.tsx # reactive variable allowing to get the auth token
│   │   │       ├── envGlobalVar.ts # Allow to access global env variables
│   │   │       ├── internationalizationVar.ts # Set the available translations and locale
│   │   │       ├── locationHistoryVar.ts # reactive variable to keep track of the history (and allow access to previous route infos + allow fallback)
│   │   │       ├── overwritePlanVar.ts # allow to keep/access overriden plan infos
│   │   │   │   └── toastVar.ts # reactive variable to deal with toasts
│   │   │   ├── cache.ts # Defines the apollo client cache
│   │   │   ├── graphqlResolvers.tsx # defines local graphQL schemas
│   │   │   ├── index.ts
│   │   │   ├── init.ts # apollo client main configuration
│   │   │   ├── errorUtils.ts # Utils to check in apollo client errors if certain error codes are present
│   │   │   └── cacheUtils.ts # apollo client utils (onLogOut, onLogIn, access localStorage functions...)
│   │   ├── formats
│   │   │   ├── formatCreditNotesItems.ts # Format credit note to match display
│   │   │   └── intlFormatNumber.ts # Number formatter with internationalization (currency available)
│   │   └── router # router config
│   │   │   ├── AuthRoutes.tsx
│   │   │   ├── CustomerRoutes.tsx
│   │   │   ├── DevelopperRoutes.tsx
│   │   │   ├── ObjectsRoutes.tsx
│   │   │   ├── SettingRoutes.tsx
│   │   │   ├── index.tsx # Expose all the routes previously defined
│   │   │   └── types.ts
│   │   ├── serializers # All serializer/deserializer needed in the app
│   │   │   ├── index.ts
│   │   │   ├── serializeAmount.ts
│   │   │   ├── serializeCreditNoteInput.ts
│   │   │   └── serializePlanInput.ts
│   │   ├── timezone
│   │   │   ├── config.ts # Config object to get name and offset of timezone, mapped with API enum
│   │   │   ├── index.ts
│   │   │   └── utils.ts # Access and format date with timezone
│   │   └── utils
│   │       └── copyToClipboard.ts
│   ├── externalUrls.ts # config file for all the external URLs accessible from the app
│   ├── generated # files generated by the codegen
│   │   └── graphql.tsx
│   ├── globalTypes.ts
│   ├── hooks
│   │   ├── auth
│   │   │   └── useIsAuthenticated.ts # To check if user is authenticated
│   │   ├── core
│   │   │   ├── useInternationalization.ts # Allow to use translations from internationalizationVar
│   │   │   └── useLocationHistory.ts # Allow to use the history from locationHistoryVar
│   │   ├── ui
│   │   │   ├── useListKeyNavigation.tsx # Allow to navigate with keyboard in a list of elements
│   │   │   └── useShortcuts.tsx # Allow to use a shortcut to do an action on a page
│   │   ├── useCurrentUser.ts # Allow current connected user informations
│   │   ├── useDebouncedSearch.ts # Allow to use the Search Input
│   │   └── useOrganizationInfos.ts # Allow to access selected organization informations
│   ├── index.html
│   ├── index.js
│   ├── layouts
│   ├── pages
│   ├── public
│   │   ├── countryCode.json # All the available country code for the app
│   │   ├── icons
│   │   └── images
│   ├── stories # All stoybook stories
│   └── styles
│       ├── colorsPalette.ts
│       ├── designSystem # design system related styles (not needing a full component)
│       │   └── index.ts
│       ├── globalStyle.tsx # global style definitions
│       ├── index.ts
│       └── muiTheme.ts # main material UI config
├── start.dev.sh # dev env conf to work with the global lago app
├── tsconfig.json
├── webpack.common.js
├── webpack.dev.js
├── webpack.prod.js
└── yarn.lock

/components

Components should be sorted by the main object it relates to. Ex: /components/customer/CustomerVatRate.tsx Always make sure to give an explicit name to your component and make sure to not use default export (to avoid mispelling).

/form

Form folders always have the same following structure :

├── form
│   └── ComponentName
│   │   ├── index.ts
│   │   └── ComponentName.ts # Usable without formik
│   │   └── ComponentNameField.ts # Usable with formik
│   └────── index.ts # Export all the form components

You can then access any form component from ~/components/form

/styles

Add a folder/file to this folder for any reusable style that don't need to be in a full component.