komga/next-ui
2025-11-28 16:05:22 +08:00
..
.storybook set msw to quiet in storybook 2025-11-28 16:05:22 +08:00
i18n i18n extract 2025-11-28 16:05:21 +08:00
public next-ui wip 2025-11-28 16:05:17 +08:00
public-msw bump deps 2025-11-28 16:05:22 +08:00
src import books add region 2025-11-28 16:05:22 +08:00
.browserslistrc next-ui wip 2025-11-28 16:05:17 +08:00
.editorconfig next-ui wip 2025-11-28 16:05:17 +08:00
.env.development move API url to config 2025-11-28 16:05:19 +08:00
.env.test add some pinia colada tests 2025-11-28 16:05:19 +08:00
.eslintrc-auto-import.json bump deps 2025-11-28 16:05:21 +08:00
.gitignore vitest coverage 2025-11-28 16:05:20 +08:00
.prettierignore prettier ignore 2025-11-28 16:05:19 +08:00
.prettierrc.json vuetify stuff 2025-11-28 16:05:18 +08:00
CHANGELOG.md add wip changelog 2025-11-28 16:05:18 +08:00
chromatic.config.json ci: chromatic 2025-11-28 16:05:20 +08:00
dir2json.d.ts wrap settings in a card 2025-11-28 16:05:21 +08:00
env.d.ts tree shake icons 2025-11-28 16:05:18 +08:00
eslint.config.ts eslint component casing 2025-11-28 16:05:22 +08:00
index.html handle dynamic base url 2025-11-28 16:05:22 +08:00
openapi-generator.mts handle File in openapi generator 2025-11-28 16:05:22 +08:00
package-lock.json bump deps 2025-11-28 16:05:22 +08:00
package.json bump deps 2025-11-28 16:05:22 +08:00
README.md handle dynamic base url 2025-11-28 16:05:22 +08:00
tsconfig.app.json migrate from unplugin-icons to unocss icons preset 2025-11-28 16:05:19 +08:00
tsconfig.json next-ui wip 2025-11-28 16:05:17 +08:00
tsconfig.node.json load vuetify locale 2025-11-28 16:05:18 +08:00
uno.config.ts fix type check 2025-11-28 16:05:19 +08:00
vite.config.mts handle dynamic base url 2025-11-28 16:05:22 +08:00
vitest.shims.d.ts add storybook 2025-11-28 16:05:19 +08:00

OpenAPI

OpenAPI-fetch is used to generate a fully typed client from the Komga OpenAPI documentation.

The openapi-generate tasks will generate bindings, and should be run when the OpenAPI definition has changed.

Pinia Colada

Pinia Colada is used for all the API queries and mutations.

Tests

Vitest projects are used to specify different kind of tests:

  • unit: unit tests
  • storybook: component tests, defined in Storybook stories. Those can be run from Storybook directly or through Vitest.

Mock Service Worker is used to mock the Komga API.

Code formatting

Both ESLint and Prettier are used in combination.

Tasks:

  • ESLint: lint and lint:fix
  • Prettier: prettier and prettier:fix

Type checking

Vite does not perform type-checking and leaves the job to the IDE. The type-check task can be used to perform type checking.

Storybook

Storybook is used for component development and testing. Run storybook:dev to start the Storybook server.

i18n

FormatJS is used for i18n.

Message IDs are generated automatically using the ESLint plugin, and hard-coded message IDs should be avoided.

Tasks:

  • i18n:extract: extracts the messages from the source into the i18n folder. This folder is what Weblate uses.
  • i18n:compile: compiles the translated files in i18n into ./src/i18n. This folder is what the application uses at runtime.

The Vite plugin dir2json is used to load the available translation files, see ./src/utils/locale-helper.ts for more details.

Components

Vue template files are segregated in different categories depending on usage:

  • ./src/components: UI components.
  • ./src/pages: Pages make use of components as well as API / Pinia stores. Each Component in that folder is converted to a navigable route using unplugin-vue-router. Pages contain a special <route> to define the layout to use as well as other router meta attributes.
  • ./src/layouts: Wrapper component around Pages.

Components are automatically imported using unplugin-vue-components.

Icons

UnoCSS Icons preset is used for icons, with the MDI set from Iconify.

Base URL

The generated bundle is server by Apache Tomcat when running Spring. By default the site is hosted at /, but if server.servlet-context-path is set, the base URL can be dynamic.

The base URL needs to be set correctly so the web app works:

  • in the API client
  • in the Vue Router, to properly handle the web history
  • in the generated bundle, to load other files (js/css/images)
  1. Vite is configured with the experimental renderBuiltUrl, which will use a dynamic function (window.buildUrl) defined in index.html to generate the asset path at runtime. This is only supported withing JS files though.

  2. To handle the dynamic path in index.html, a Gradle task prepareThymeLeafNext modifies index.html to duplicate href, src and content attributes as Thymeleaf variants.

    For example the following:

    <script
        type="module"
        crossorigin
        src="/assets/index-xEUJQodq.js"
    ></script>
    <link
        rel="stylesheet"
        crossorigin
        href="/assets/index-CQqFNa2f.css"
    />
    

    will be transformed to:

    <script
        type="module"
        crossorigin
        src="/assets/index-xEUJQodq.js"
        th:src="@{/assets/index-xEUJQodq.js}"
    ></script>
    <link
        rel="stylesheet"
        crossorigin
        href="/assets/index-CQqFNa2f.css"
        th:href="@{/assets/index-CQqFNa2f.css}"
    />
    

    In Thymeleaf, @{} will prepend the path with the context path dynamically when serving index.html.

  3. when the index.html is served by the IndexController, a baseUrl attribute is injected, which contains the servlet context path (by default /, but could be /komga for example)

  4. the index.html contains a Thymeleaf script block that will be processed when serving the page, effectively injecting the baseUrl value into window.ressourceBaseUrl.

  5. window.ressourceBaseUrl is subsequently used in Typescript code to set the base URL for: