Conversation
Replace legacy I18nT usage with vue-i18n composition API (useI18n and t()) across numerous Vue components (App, Conf drawer, Deno, Erlang, MySQL modules, Podman, etc.). Add 'projectErlang' translation key to many locale host.json files and minor Vietnamese i18n additions. Remove legacy: true from createI18n call. Also add helper-go/go.sum and Windows resource binaries (rsrc_windows_386/amd64.syso).
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
| export const AppI18n = (l?: string): I18n => { | ||
| if (!i18n) { | ||
| i18n = createI18n({ | ||
| legacy: true, | ||
| locale: l || 'en', | ||
| fallbackLocale: 'en', | ||
| messages: lang as any |
There was a problem hiding this comment.
Bug: The removal of legacy: true from createI18n makes i18n.global.locale a Ref. The direct assignment i18n.global.locale = l will fail, breaking language switching.
Severity: CRITICAL
Suggested Fix
When legacy: false (the new default), the locale must be updated by assigning to the .value property of the Ref. Change i18n.global.locale = l to i18n.global.locale.value = l to correctly update the language.
Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent.
Verify if this is a real issue. If it is, propose a fix; if not, explain why it's not
valid.
Location: src/lang/index.ts#L169-L174
Potential issue: By removing `legacy: true` from the `createI18n` call, the
`i18n.global.locale` property is changed from a plain string to a reactive `Ref` object.
The code subsequently attempts to assign a new language code directly via
`i18n.global.locale = l`. This assignment will fail because a `Ref`'s value must be
updated through its `.value` property. This will prevent the application's language from
being updated when a user tries to change it in the settings, breaking the language
switching functionality.
Did we get this right? 👍 / 👎 to inform future reviews.
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request significantly refactors the application's internationalization system by adopting the Highlights
Changelog
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request successfully refactors most of the codebase to use the vue-i18n composition API, replacing the legacy I18nT helper. It also adds new translations for Erlang projects. The changes are mostly correct and improve consistency. However, I found a few issues: a typo in a translation key, one component that was missed in the refactoring, and a critical bug in a function call that would lead to a runtime error.
| <template v-if="PodmanManager.installEnd"> | ||
| <el-button type="primary" @click.stop="taskConfirm">{{ | ||
| I18nT('base.confirm') | ||
| taskConfirm('base.confirm') |
There was a problem hiding this comment.
| "dbclickRowToEdit": "Nhấp đúp vào dòng này để chỉnh sửa", | ||
|
|
||
| "OnlineDomain": "Tên miền trực tuyến", | ||
| "LocalDoman": "Tên miền Local" |
| <ProjectIndex | ||
| v-else-if="tab === 2" | ||
| :title="`Erlang ${I18nT('base.projects')}`" | ||
| :title="I18nT('host.projectErlang')" |
There was a problem hiding this comment.
This component still uses the legacy I18nT helper. To be consistent with the rest of the changes in this pull request, it should be updated to use the useI18n composition API. You'll need to import useI18n and initialize t in the <script setup> block, then use t() here and for defining tabs.
:title="t('host.projectErlang')"
There was a problem hiding this comment.
Actionable comments posted: 10
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (4)
src/render/components/Podman/compose-build/Meilisearch.vue (1)
5-11:⚠️ Potential issue | 🟡 MinorInconsistent i18n: hardcoded "Password" label.
Line 5 correctly uses
t('podman.Persistence'), but line 9 has a hardcodedlabel="Password". For consistency and proper localization, this should also use the translation function.Suggested fix
- <el-form-item label="Password"> + <el-form-item :label="t('base.password')">Note: Verify that the appropriate translation key exists in your locale files, or add one if needed.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/render/components/Podman/compose-build/Meilisearch.vue` around lines 5 - 11, The "Password" label in Meilisearch.vue is hardcoded; update the <el-form-item> that wraps the <el-input v-model="form.environment.MEILI_MASTER_KEY"> to use the i18n function (e.g. label="t('podman.Password')" or an appropriate key like t('meilisearch.Password')), ensure the chosen translation key exists in your locale files (or add it), and keep the v-model binding to form.environment.MEILI_MASTER_KEY unchanged.src/render/components/Podman/compose-build/RabbitMQ.vue (1)
5-21:⚠️ Potential issue | 🟡 MinorInconsistent i18n: hardcoded labels.
Line 5 correctly uses
t('podman.Persistence'), but lines 9 and 16 have hardcoded labels"Default User"and"Default Password". For consistent localization, these should also use the translation function.Suggested fix
- <el-form-item label="Default User"> + <el-form-item :label="t('rabbitmq.defaultUser')"> <el-input v-model="form.environment.RABBITMQ_DEFAULT_USER" placeholder="RABBITMQ_DEFAULT_USER" ></el-input> </el-form-item> - <el-form-item label="Default Password"> + <el-form-item :label="t('rabbitmq.defaultPassword')">Note: Ensure corresponding translation keys exist in your locale files.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/render/components/Podman/compose-build/RabbitMQ.vue` around lines 5 - 21, The two el-form-item labels in RabbitMQ.vue are hardcoded ("Default User"/"Default Password"); update those labels to use the i18n function (e.g. t('podman.DefaultUser') and t('podman.DefaultPassword')) so they match the existing i18n style used for persistence, keeping the bindings to form.environment.RABBITMQ_DEFAULT_USER and form.environment.RABBITMQ_DEFAULT_PASS unchanged, and add the corresponding keys to the locale files.src/render/App.vue (1)
183-189:⚠️ Potential issue | 🟡 MinorVariable
tshadows the i18n translation function.The variable
tdeclared on line 184 shadows thetfunction fromuseI18n()(line 25). While this works within the computed scope, it creates confusion and could lead to bugs if the computed body is modified to use translations.Rename the local variable to avoid shadowing.
🐛 Proposed fix
const theme = computed(() => { - const t = appStore?.config?.setup?.theme - if (!t) { + const configTheme = appStore?.config?.setup?.theme + if (!configTheme) { return isDark.value ? 'dark' : 'light' } - return t + return configTheme })🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/render/App.vue` around lines 183 - 189, The computed property theme uses a local variable named t which shadows the i18n translation function returned by useI18n(); rename that local variable (e.g., to themeSetting or cfgTheme) inside the theme computed (the block referencing appStore?.config?.setup?.theme) and update its uses so the i18n t() function remains unshadowed and available for translations elsewhere.src/render/components/Nodejs/projects/dependencies/index.vue (1)
192-194:⚠️ Potential issue | 🟡 MinorMissing parentheses on
toStringmethod call.
e.toStringreferences the function itself rather than calling it. This will display something like[Function: toString]instead of the actual error message.🐛 Proposed fix
} catch (e: any) { - ElMessage.error(e.toString) + ElMessage.error(e.toString()) }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/render/components/Nodejs/projects/dependencies/index.vue` around lines 192 - 194, The catch block is passing the toString function reference instead of invoking it; update the error handling in the catch for the ElMessage.error call (the block containing "catch (e: any)" and the ElMessage.error invocation) to call the function and surface a real message — e.g. invoke e.toString() or use e.message || String(e) so ElMessage.error receives an actual string.
🧹 Nitpick comments (37)
src/render/components/Mysql/Manage/setBackupDir.vue (1)
24-30: MoveuseI18n()call after all imports.The executable statement
const { t } = useI18n()is placed between import declarations. For better readability and consistency, group all imports together at the top, then place executable code afterward.♻️ Suggested reordering
import { computed } from 'vue' import { AsyncComponentSetup } from '@/util/AsyncComponent' import { useI18n } from 'vue-i18n' - -const { t } = useI18n() import type { ModuleInstalledItem } from '@/core/Module/ModuleInstalledItem' import { MySQLManage } from './manage' import { FolderOpened } from '@element-plus/icons-vue' import { dialog } from '@/util/NodeFn' + +const { t } = useI18n()🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/render/components/Mysql/Manage/setBackupDir.vue` around lines 24 - 30, Move the executable call const { t } = useI18n() so that it appears after all import statements; specifically, keep all imports (useI18n, ModuleInstalledItem, MySQLManage, FolderOpened, dialog) grouped at the top of setBackupDir.vue and then place the const { t } = useI18n() initialization immediately after the imports (before any other executable logic) to avoid having an executable statement between import declarations.src/render/components/Podman/compose-build/components/wwwRoot.vue (1)
15-17: MoveuseI18n()call after all imports.The
const { t } = useI18n()statement is placed between import statements. While this works (imports are hoisted), it breaks conventional code organization where all imports should be grouped at the top before any executable statements.♻️ Proposed fix
import { computed } from 'vue' import { ComposeBuildForm } from '@/components/Podman/compose-build/Form' import { Folder } from '@element-plus/icons-vue' import { useI18n } from 'vue-i18n' - const { t } = useI18n() import { ComposeBuildSetup } from '@/components/Podman/compose-build/setup' + + const { t } = useI18n()🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/render/components/Podman/compose-build/components/wwwRoot.vue` around lines 15 - 17, Move the call to useI18n so all import statements are grouped together: remove the top-level const { t } = useI18n() that currently sits between imports and place it immediately after the last import (e.g., after the ComposeBuildSetup import) or inside the component's setup() block; ensure the symbol t is still exported/available where used in this file (wwwRoot.vue) and that useI18n() is called once in the appropriate scope.src/render/components/Podman/machine/machineAdd.vue (2)
4-4: Avoid concatenating translated fragments in dialog title.Line 4 builds the title with
t(...) + t(...), which can break grammar/word order in several locales. Prefer a single translation key (with interpolation if needed) so each locale controls full phrasing.Proposed refactor
-:title="isEdit ? t('base.edit') + t('podman.Machine') : t('podman.Machine') + t('base.add')" +:title="isEdit ? t('podman.machineDialogTitle.edit') : t('podman.machineDialogTitle.add')"🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/render/components/Podman/machine/machineAdd.vue` at line 4, The title concatenates two translations which breaks localization; replace the inline concatenation in machineAdd.vue's :title binding by using a single translation key that accepts an action interpolation (e.g. t('podman.machineTitle', { action: isEdit ? t('base.edit') : t('base.add') })), and add corresponding i18n entries (e.g. "podman.machineTitle": "{{action}} {{Machine}}" or per-locale phrasing) so each locale controls full word order; update any uses of isEdit and t(...) in that :title binding to use the new single-key interpolation.
89-89: Use one localized key for the required-name error message.Line 89 concatenates
t('base.name') + t('podman.require'); this is brittle across locales. Use one message key (optionally interpolated) for a natural localized sentence.Proposed refactor
-ElMessage.error(t('base.name') + t('podman.require')) +ElMessage.error(t('podman.nameRequired'))🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/render/components/Podman/machine/machineAdd.vue` at line 89, Replace the concatenated localized strings with a single localization key that produces a natural sentence; update the ElMessage.error call in the machineAdd component to use one translation key (for example t('podman.requireName', { name: t('base.name') })) instead of t('base.name') + t('podman.require'), and add/update the corresponding entries in all locale files (podman.requireName) to accept the interpolated name so translations remain natural.src/render/components/Podman/compose/composeBuild.vue (1)
4-4: Localize the full dialog title key instead of concatenating an English suffix.On Line 4,
t('podman.Build') + ' Compose'hardcodes English and can produce awkward ordering in some locales. Prefer a single translation key (or interpolation) for the full title.♻️ Proposed refactor
- :title="t('podman.Build') + ' Compose'" + :title="t('podman.buildComposeTitle')"🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/render/components/Podman/compose/composeBuild.vue` at line 4, The template currently builds the dialog title by concatenating t('podman.Build') + ' Compose' which hardcodes English; change the :title binding in composeBuild.vue to use a single i18n key or interpolation instead (e.g. add a new translation key like "podman.BuildCompose" or a generic "podman.BuildWithTool" that accepts a tool interpolation) and update the template to call t(...) with that key and any interpolation variables; also add the corresponding entries to your locale files so all languages get a properly ordered, localized full title.src/render/components/Podman/compose-build/components/base.vue (1)
40-42: MoveuseI18n()call after all imports.The
const { t } = useI18n()statement is placed between import statements. Imports should be grouped together at the top, followed by other declarations.♻️ Suggested fix
import { computed, onMounted, onUnmounted } from 'vue' import { ComposeBuildForm } from '@/components/Podman/compose-build/Form' import { useI18n } from 'vue-i18n' -const { t } = useI18n() import { PodmanManager } from '../../class/Podman' + +const { t } = useI18n()🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/render/components/Podman/compose-build/components/base.vue` around lines 40 - 42, Move the useI18n() call so all imports are grouped at the top: remove "const { t } = useI18n()" from between the import statements and place it immediately after the import block (e.g. after the import of PodmanManager). Ensure the symbol useI18n and the destructured t remain unchanged and are initialized once at the top of the module scope, keeping import lines contiguous.src/render/components/Podman/image/image.vue (1)
87-90: Moveconst { t } = useI18n()after all imports.The
constdeclaration is placed between import statements, which is non-idiomatic. While JavaScript hoists imports so this works at runtime, it reduces readability and violates conventional code organization.♻️ Suggested fix
import { computed } from 'vue' import { PodmanManager } from '@/components/Podman/class/Podman' import { useI18n } from 'vue-i18n' - -const { t } = useI18n() import type { Image } from '@/components/Podman/class/Image' import { AsyncComponentShow } from '@/util/AsyncComponent' import { clipboard } from '@/util/NodeFn' import { MessageSuccess } from '@/util/Element' import { formatBytes } from '@/util/Index' import { XTermExecCache } from '@/util/XTermExec' + +const { t } = useI18n()🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/render/components/Podman/image/image.vue` around lines 87 - 90, Move the const { t } = useI18n() declaration so it appears after all import statements (e.g., after import type { Image } from '@/components/Podman/class/Image') — keep all import lines together at the top of src/render/components/Podman/image/image.vue and then call useI18n()/const { t } = useI18n() before any component code that uses t.src/render/components/Podman/image/imageAdd.vue (2)
37-39: Consider moving theuseI18n()call after all imports.Placing the
const { t } = useI18n()statement between import declarations is unconventional, even though<script setup>allows it. Grouping all imports at the top improves readability.🔧 Suggested reorganization
import { computed, ref, watch } from 'vue' import { useI18n } from 'vue-i18n' -const { t } = useI18n() import { ElMessage } from 'element-plus' import { PodmanManager } from '@/components/Podman/class/Podman' import { OfficialImages } from '@/components/Podman/officialImages' import { AllAppModule } from '@/core/type' import Base from '../compose-build/Form/Base' import { XTermExec, XTermExecCache } from '@/util/XTermExec' import { reactiveBind, uuid } from '@/util/Index' import { AsyncComponentSetup, AsyncComponentShow } from '@/util/AsyncComponent' import { Image } from '@/components/Podman/class/Image' +const { t } = useI18n() + const { show, onClosed, onSubmit, closedFn } = AsyncComponentSetup()🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/render/components/Podman/image/imageAdd.vue` around lines 37 - 39, Move the call to useI18n() so all import statements are grouped at the top: keep the import lines (including "import { useI18n } from 'vue-i18n'" and "import { ElMessage } from 'element-plus'") together, then invoke const { t } = useI18n() immediately after the imports (not between import lines). Update the file so useI18n() is called once after imports to improve readability and maintain conventional import grouping while leaving the rest of the component (references to t and ElMessage) unchanged.
4-4: String concatenation may produce awkward translations in some languages.Concatenating
t('podman.Image') + t('base.add')doesn't account for languages with different word orders or grammatical rules. Consider using a dedicated key liket('podman.addImageTitle')with the full phrase in each locale file.Same applies to line 165:
t('podman.Image') + t('podman.require').🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/render/components/Podman/image/imageAdd.vue` at line 4, Replace the string concatenations used for translated strings with single dedicated i18n keys: instead of t('podman.Image') + t('base.add') update the template binding (the :title expression) to use a new key like t('podman.addImageTitle'), and instead of t('podman.Image') + t('podman.require') replace that usage with a new key like t('podman.imageRequired'); add these full-phrase entries to the locale files for each language and remove the concatenations in the component so translations can handle word order and grammar correctly.src/render/components/Nodejs/nvm/index.vue (3)
46-49: Organize imports: placeuseI18nimport with other imports.The
useI18nimport and its destructuring are placed before other imports, creating an unconventional import organization. Consider grouping all imports together at the top.♻️ Suggested organization
<script lang="tsx" setup> - import { useI18n } from 'vue-i18n' - - const { t } = useI18n() import { NVMSetup, Setup } from './setup' import { type Column, ElButton, ElInput, ElTooltip } from 'element-plus' import { MessageSuccess } from '@/util/Element' import { clipboard } from '@/util/NodeFn' + import { useI18n } from 'vue-i18n' + + const { t } = useI18n()🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/render/components/Nodejs/nvm/index.vue` around lines 46 - 49, Move the import statement "import { useI18n } from 'vue-i18n'" to be grouped with the other imports at the top of the file and ensure the call "const { t } = useI18n()" occurs after imports (or inside the component/setup block) rather than before other imports; this keeps import ordering consistent with "import { NVMSetup, Setup } from './setup'" and avoids using useI18n() before module imports are declared.
13-15: Fix formatting per Prettier rules.The static analysis tool flagged a formatting issue. The radio button content should be on a single line.
♻️ Suggested fix
- <el-radio-button key="shell" label="shell" - >{{ t('base.Official') }} - </el-radio-button> + <el-radio-button key="shell" label="shell">{{ t('base.Official') }}</el-radio-button>🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/render/components/Nodejs/nvm/index.vue` around lines 13 - 15, The el-radio-button element rendering the official label in the Nodejs nvm component is split across multiple lines and violates Prettier; locate the <el-radio-button key="shell" label="shell"> element in src/render/components/Nodejs/nvm/index.vue and collapse its inner content so the entire tag and its interpolation {{ t('base.Official') }} are on a single line (e.g., <el-radio-button key="shell" label="shell">{{ t('base.Official') }}</el-radio-button>) to satisfy formatting rules.
21-23: Consider consistent formatting with other radio buttons.For consistency with line 16-17 (Homebrew and Macports buttons), consider keeping the install button content inline as well.
♻️ Suggested fix
- <el-button class="mt-3" type="primary" `@click.stop`="installNVM" - >{{ t('base.install') }} - </el-button> + <el-button class="mt-3" type="primary" `@click.stop`="installNVM">{{ + t('base.install') + }}</el-button>🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/render/components/Nodejs/nvm/index.vue` around lines 21 - 23, The install button's template is broken across multiple lines unlike the other radio buttons; update the <el-button> for installNVM so its content is inline like the Homebrew/Macports buttons (keep the same attributes including `@click.stop` and type="primary" and the installNVM handler, but place {{ t('base.install') }} on the same line inside the <el-button> tag).src/render/components/Nodejs/Index.vue (1)
24-28: Consider grouping all imports together at the top of the script.The
importstatements on lines 27-28 are placed after theconst { t } = useI18n()declaration. While JavaScript hoists imports, placing them after runtime code is unconventional and reduces readability.♻️ Suggested reordering
import { AppModuleSetup } from '@/core/Module' import { useI18n } from 'vue-i18n' - - const { t } = useI18n() import Create from './CreateProject.vue' import ProjectIndex from './projects/index.vue' + + const { t } = useI18n()🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/render/components/Nodejs/Index.vue` around lines 24 - 28, The import statements for Create and ProjectIndex are placed after the runtime call to useI18n (the line with const { t } = useI18n()), which is unconventional; move the imports for Create and ProjectIndex so that all import declarations (including useI18n) appear at the top of the module before any runtime code, e.g., import useI18n first then invoke const { t } = useI18n() afterward, ensuring symbols Create and ProjectIndex are imported before use.src/render/components/Podman/compose-build/Base.vue (1)
26-28: Minor style: import ordering.Same pattern as other files - import appears after the
const { t }declaration. Consider grouping all imports at the top for consistency across the codebase.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/render/components/Podman/compose-build/Base.vue` around lines 26 - 28, Move the import for ComposeBuildForm above any runtime statements so all imports are grouped at the top: place "import { ComposeBuildForm } from '@/components/Podman/compose-build/Form'" before the "const { t } = useI18n()" line (and ensure the call to useI18n() remains after the imports), keeping the useI18n import and the destructuring of t unchanged.src/render/components/Mysql/Config.vue (1)
22-25: Minor style: import statement after variable declaration.The import on line 25 appears after
const { t } = useI18n(). While ES module imports are hoisted and this works, it's unconventional and can reduce readability. Consider grouping all imports together at the top.Suggested reordering
- import { useI18n } from 'vue-i18n' - - const { t } = useI18n() import { debounce } from 'lodash-es' + import { useI18n } from 'vue-i18n' import { AppStore } from '@/store/app' import { uuid } from '@/util/Index' import { join } from '@/util/path-browserify' import { IniParse } from '@/util/IniParse' + + const { t } = useI18n()🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/render/components/Mysql/Config.vue` around lines 22 - 25, Move the import for debounce so all imports are grouped at the top of the module: place "import { debounce } from 'lodash-es'" above the call to useI18n(), then keep the existing "const { t } = useI18n()" afterwards; this preserves behavior (imports are hoisted) but improves readability and follows conventional module structure—locate the symbols useI18n, const { t } = useI18n(), and debounce when making the change.src/render/components/Podman/compose-build/Perl.vue (1)
18-20: Minor style: import ordering.Same pattern as other files. Consider grouping all imports at the top.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/render/components/Podman/compose-build/Perl.vue` around lines 18 - 20, Reorder the imports in Perl.vue so all import statements (e.g., import { useI18n } from 'vue-i18n' and import { OfficialImages } from '@/components/Podman/officialImages') appear at the top of the module, and move the destructuring const { t } = useI18n() immediately after the useI18n import (not between imports); this matches the project style of grouping imports first and then running module initialization like useI18n()/const { t } = useI18n().src/render/components/Podman/compose-build/RabbitMQ.vue (1)
30-32: Minor style: import ordering.Same pattern - import after
const { t }declaration. Consider grouping imports for consistency.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/render/components/Podman/compose-build/RabbitMQ.vue` around lines 30 - 32, Move all import statements before any top-level code: place "import { OfficialImages } from '@/components/Podman/officialImages'" above the call to useI18n and the "const { t } = useI18n()" line so imports are grouped together; ensure no other imports remain after the "const { t }" declaration and keep the "useI18n" call immediately after the imports.src/render/components/Podman/compose-build/Meilisearch.vue (1)
20-22: Minor style: import ordering.Same pattern - import after
const { t }declaration. Consider grouping imports for consistency.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/render/components/Podman/compose-build/Meilisearch.vue` around lines 20 - 22, Move the import of OfficialImages to be grouped with other imports before any runtime code; specifically, ensure the import statement for '@/components/Podman/officialImages' appears above the useI18n call so that useI18n() and the const { t } = useI18n() remain after all imports. Update the file to import OfficialImages alongside useI18n (and any other imports) to keep consistent import ordering and avoid declaring const { t } before module imports.src/render/components/Podman/compose-build/Bun.vue (1)
18-19: Minor style: import after variable declaration.Same as other files in this PR - the import on line 20 comes after
const { t } = useI18n(). Consider grouping imports together for consistency.Suggested reordering
import { computed } from 'vue' import { ComposeBuildForm } from '@/components/Podman/compose-build/Form' import { useI18n } from 'vue-i18n' - const { t } = useI18n() import { OfficialImages } from '@/components/Podman/officialImages' import BaseVM from '@/components/Podman/compose-build/components/base.vue' import PreviewVM from './components/preview.vue' import WwwRoot from './components/wwwRoot.vue' + + const { t } = useI18n()🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/render/components/Podman/compose-build/Bun.vue` around lines 18 - 19, Move the import so all imports are grouped at the top: place the "import { useI18n } from 'vue-i18n'" statement before the "const { t } = useI18n()" declaration in Bun.vue so the useI18n symbol is imported prior to being used and matches the import ordering used across the PR.src/render/components/Podman/compose-build/Python.vue (1)
18-20: Minor style: import ordering.Same pattern as other files. Consider grouping all imports at the top for consistency.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/render/components/Podman/compose-build/Python.vue` around lines 18 - 20, The import ordering is inconsistent: group all imports at the top of the module and move the useI18n call after imports—specifically ensure the import of OfficialImages and any other modules appear before calling const { t } = useI18n(), keeping the useI18n() invocation (const { t } = useI18n()) below the import block for consistent style with other files.src/render/components/Podman/compose-build/NodeJS.vue (1)
16-23: Consider grouping imports before executable statements.The
const { t } = useI18n()call on line 19 is interleaved between import statements. While this works, it's cleaner to place all imports together at the top, followed by theuseI18n()call.♻️ Suggested reordering
import { computed } from 'vue' import { ComposeBuildForm } from '@/components/Podman/compose-build/Form' import { useI18n } from 'vue-i18n' -const { t } = useI18n() import { OfficialImages } from '@/components/Podman/officialImages' import BaseVM from '@/components/Podman/compose-build/components/base.vue' import PreviewVM from '@/components/Podman/compose-build/components/preview.vue' import WwwRoot from '@/components/Podman/compose-build/components/wwwRoot.vue' + +const { t } = useI18n()🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/render/components/Podman/compose-build/NodeJS.vue` around lines 16 - 23, Move the executable call const { t } = useI18n() so all import statements are grouped together at the top of the module; specifically, keep the import lines for computed, ComposeBuildForm, useI18n, OfficialImages, BaseVM, PreviewVM, and WwwRoot together, then place the const { t } = useI18n() statement immediately after the imports (e.g., before any component logic or setup) to avoid interleaving imports with executable code.src/render/components/Ollama/models/index.vue (1)
53-61: Import after executable statement.Line 57 (
import { OllamaModelsSetup, SetupAll }...) comes after theuseI18n()call on line 56. Group all imports together.♻️ Suggested reordering
import { useI18n } from 'vue-i18n' - -const { t } = useI18n() import { OllamaModelsSetup, SetupAll } from './setup' import LocalVM from './local/index.vue' import AllVM from './all/index.vue' + +const { t } = useI18n()🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/render/components/Ollama/models/index.vue` around lines 53 - 61, The import of OllamaModelsSetup and SetupAll occurs after an executable call to useI18n(), which violates module import ordering; move the import statements (import { OllamaModelsSetup, SetupAll } from './setup' and imports for LocalVM and AllVM) above the call to useI18n() so all imports are grouped at the top, then call const { t } = useI18n() and finally invoke SetupAll() to destructure showFooter, taskEnd, taskConfirm, taskCancel, loading, reFetch, openURL.src/render/components/Deno/Index.vue (1)
41-41: Non-reactive translation intabsarray.The
tabsarray is initialized once at component setup. If your app supports runtime locale switching, these translations won't update when the locale changes. Consider using acomputedproperty instead.♻️ Reactive alternative (if needed)
-const tabs = [t('base.service'), t('base.versionManager'), t('host.projectDeno')] +const tabs = computed(() => [t('base.service'), t('base.versionManager'), t('host.projectDeno')])🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/render/components/Deno/Index.vue` at line 41, The tabs array is created once with const tabs = [t('base.service'), t('base.versionManager'), t('host.projectDeno')] so translations won't update when the locale changes; replace it with a reactive computed that returns [t('base.service'), t('base.versionManager'), t('host.projectDeno')] (i.e. use computed(() => [...]) inside the component setup and import computed from 'vue') so t() is re-evaluated on locale changes; ensure any usage in the template or script reads the computed directly (template auto-unwraps, script may need .value).src/render/components/Podman/compose-build/MySQL.vue (1)
35-37: Consider grouping imports before variable declarations.Same pattern as other files: move
const { t } = useI18n()after all import statements.♻️ Suggested reordering
import { useI18n } from 'vue-i18n' - const { t } = useI18n() import { OfficialImages } from '@/components/Podman/officialImages' import BaseVM from '@/components/Podman/compose-build/components/base.vue' import PreviewVM from '@/components/Podman/compose-build/components/preview.vue' + + const { t } = useI18n()🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/render/components/Podman/compose-build/MySQL.vue` around lines 35 - 37, The file declares const { t } = useI18n() before completing imports; move the const { t } = useI18n() line to after all import statements (i.e., after import { OfficialImages } from '@/components/Podman/officialImages') so useI18n() is invoked only after imports are grouped, keeping the import block together and consistent with other files.src/render/components/Podman/compose-build/components/preview.vue (1)
27-29: Consider grouping imports before variable declarations.The
const { t } = useI18n()is placed between import statements. For consistency across the codebase, group all imports before variable declarations.♻️ Suggested reordering
import { useI18n } from 'vue-i18n' - const { t } = useI18n() import { ComposeBuildSetup } from '@/components/Podman/compose-build/setup' + + const { t } = useI18n()🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/render/components/Podman/compose-build/components/preview.vue` around lines 27 - 29, Move the variable declaration const { t } = useI18n() so that all import statements are grouped above it; specifically, place the useI18n() call after the import of ComposeBuildSetup and any other imports in preview.vue, keeping the import block contiguous and then declare const { t } = useI18n() (referencing useI18n and t) below the imports to conform with project import ordering.src/render/components/Podman/compose-build/Redis.vue (1)
20-22: Consider grouping imports before variable declarations.The
const { t } = useI18n()declaration (line 21) is placed between import statements. For better readability and consistency, group all imports together before any variable declarations.♻️ Suggested reordering
import { ComposeBuildForm } from '@/components/Podman/compose-build/Form' import { useI18n } from 'vue-i18n' - const { t } = useI18n() import { OfficialImages } from '@/components/Podman/officialImages' import BaseVM from '@/components/Podman/compose-build/components/base.vue' import PreviewVM from '@/components/Podman/compose-build/components/preview.vue' + + const { t } = useI18n()🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/render/components/Podman/compose-build/Redis.vue` around lines 20 - 22, In Redis.vue the variable destructuring const { t } = useI18n() is placed between import statements (useI18n and OfficialImages); move that declaration so all imports (including useI18n and OfficialImages) are grouped at the top of the file, then immediately after the import block add const { t } = useI18n() to keep imports and variable declarations separated for readability.src/render/components/Nodejs/projects/dependencies/index.vue (1)
82-84: Consider grouping imports before variable declarations.The
const { t } = useI18n()is placed between import statements.♻️ Suggested reordering
import { useI18n } from 'vue-i18n' - const { t } = useI18n() import { join } from '@/util/path-browserify' import { shell, fs } from '@/util/NodeFn' import { asyncComputed } from '@vueuse/core' + + const { t } = useI18n()🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/render/components/Nodejs/projects/dependencies/index.vue` around lines 82 - 84, Move the variable declaration splitting imports so all imports are grouped at the top: relocate the const { t } = useI18n() line below the import statements (after import { useI18n } from 'vue-i18n' and import { join } from '@/util/path-browserify') so imports (useI18n, join) are contiguous and then initialize t from useI18n() to keep module imports before runtime variable declarations.src/render/components/Ollama/models/local/index.vue (1)
25-28: Consider grouping imports before variable declarations.Same pattern as other files in this PR: the
const { t } = useI18n()declaration is placed between import statements. Group all imports together before variable declarations for consistency.♻️ Suggested reordering
import { useI18n } from 'vue-i18n' - - const { t } = useI18n() import { Setup } from './setup' + + const { t } = useI18n() const { fetching, tableData } = Setup()🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/render/components/Ollama/models/local/index.vue` around lines 25 - 28, The file places the call to useI18n (const { t } = useI18n()) between import statements; move all imports (including "import { useI18n } from 'vue-i18n'" and "import { Setup } from './setup'") together at the top, then declare const { t } = useI18n() afterwards so imports are grouped consistently (look for useI18n and the const { t } = useI18n() occurrence to relocate).src/render/components/Podman/compose/composeAdd.vue (1)
129-130: Keep validation messages reactive to language changes.Line 130 initializes translated text once inside
rules. After a locale switch, form validation may keep the old language until component reload.♻️ Proposed fix
- import { ref } from 'vue' + import { computed, ref } from 'vue' @@ - const rules = ref<FormRules>({ + const rules = computed<FormRules>(() => ({ name: [{ required: true, message: t('base.name') + t('podman.require'), trigger: 'blur' }], @@ - }) + }))Also applies to: 144-150
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/render/components/Podman/compose/composeAdd.vue` around lines 129 - 130, The rules object initializes translated messages once, so locale changes don't update validation text; change rules from a static ref to a reactive/computed structure that calls the i18n translator (t) on access or use function-based validators that call t at runtime (e.g., convert const rules = ref<FormRules>({...}) into a computed/ref that recomputes messages using t('...') or replace message strings with validator callbacks that create Error(t('...'))), and update the same pattern where rules are defined (the rules symbol in this file and the similar definitions around lines 144-150) so validation messages are evaluated after locale switches.src/render/components/Nodejs/fnm/index.vue (1)
69-70: Make table column titles reactive to locale switching.Lines 118, 159, and 183 call
t(...)while creating a static array; those header labels stay fixed if language changes at runtime.♻️ Proposed fix
+import { computed } from 'vue' import { useI18n } from 'vue-i18n' @@ -const columns: Column<any>[] = [ +const columns = computed<Column<any>[]>(() => [ // ...same column definitions... -] +])Also applies to: 118-118, 159-159, 183-183
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/render/components/Nodejs/fnm/index.vue` around lines 69 - 70, The table column titles are being set once using t(...) when the static const columns: Column<any>[] is created, so they won't update on locale changes; change the static columns into a reactive/computed value or factory function that calls the i18n t() at runtime (e.g. replace the const columns with a computed(() => [ ... ]) or a getColumns() function) and use that reactive/computed reference wherever columns is used so the header titles (the places where t(...) is currently called inside the columns array) re-evaluate on locale switch.src/render/components/Perl/Index.vue (1)
37-38: Make tab labels reactive to locale changes.Line 42 currently evaluates translations once during setup. If the user switches language at runtime, these tab labels will not update.
♻️ Proposed fix
+import { computed } from 'vue' import { AppModuleSetup } from '@/core/Module' import { useI18n } from 'vue-i18n' const { t } = useI18n() @@ const { tab } = AppModuleSetup('perl') -const tabs = [t('base.service'), t('base.versionManager'), t('host.projectPerl')] +const tabs = computed(() => [t('base.service'), t('base.versionManager'), t('host.projectPerl')])Also applies to: 42-42
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/render/components/Perl/Index.vue` around lines 37 - 38, The tab labels are currently created once using useI18n's t() during setup and so won't update on locale change; make the labels reactive by wrapping each t(...) call in a computed (or build the entire tabs array inside a computed) so that components like t and the tabs array recompute when the locale changes—update the code that defines the tabs (the variable/const where tab labels are created) to use computed(() => t('...')) or computed(() => [{ label: t('...'), ... }, ...]) so label text updates automatically when useI18n's locale changes.src/render/components/Mysql/Group/Add.vue (1)
68-71: Moveconstdeclaration after all imports.The
const { t } = useI18n()is placed between import statements with an extra blank line. Group all imports together first for consistency.🔧 Suggested fix
import { computed, ref, watch } from 'vue' import { AsyncComponentSetup } from '@/util/AsyncComponent' import { useI18n } from 'vue-i18n' - -const { t } = useI18n() import { uuid } from '@/util/Index' import { BrewStore } from '@/store/brew' import { MessageSuccess } from '@/util/Element' import type { MysqlGroupItem } from '@shared/app' import { MysqlStore } from '../mysql' import { join } from '@/util/path-browserify' import { dialog } from '@/util/NodeFn' + +const { t } = useI18n()🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/render/components/Mysql/Group/Add.vue` around lines 68 - 71, Move the runtime destructuring const { t } = useI18n() so that all import statements are grouped together first; specifically, place the const { t } = useI18n() after the import lines (including import { useI18n } from 'vue-i18n' and import { uuid } from '@/util/Index') and remove the extra blank line so imports remain contiguous and the useI18n call occurs after imports.src/render/components/Podman/compose-build/Ruby.vue (1)
18-20: Moveconstdeclaration after all imports.The
const { t } = useI18n()statement is placed between import statements, breaking the conventional separation between imports and code. Consider grouping all imports together first.🔧 Suggested fix
import { computed } from 'vue' import { ComposeBuildForm } from '@/components/Podman/compose-build/Form' import { useI18n } from 'vue-i18n' -const { t } = useI18n() import { OfficialImages } from '@/components/Podman/officialImages' import BaseVM from '@/components/Podman/compose-build/components/base.vue' import PreviewVM from '@/components/Podman/compose-build/components/preview.vue' import WwwRoot from '@/components/Podman/compose-build/components/wwwRoot.vue' + +const { t } = useI18n()🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/render/components/Podman/compose-build/Ruby.vue` around lines 18 - 20, Move the const declaration out of the import block: keep all import statements together (including import { useI18n } from 'vue-i18n' and import { OfficialImages } from '@/components/Podman/officialImages') and then place const { t } = useI18n() immediately after the imports; update the Ruby.vue file so useI18n is imported first and the const { t } = useI18n() call occurs below the import list.src/render/components/Podman/compose-build/Elasticsearch.vue (1)
16-17: Moveconstdeclaration after all imports.Same as other components in this PR – the
const { t } = useI18n()statement is placed between import statements. Group all imports together, then add declarations.🔧 Suggested fix
import { computed } from 'vue' import { ComposeBuildForm } from '@/components/Podman/compose-build/Form' import { useI18n } from 'vue-i18n' -const { t } = useI18n() import { OfficialImages } from '@/components/Podman/officialImages' import BaseVM from '@/components/Podman/compose-build/components/base.vue' import PreviewVM from '@/components/Podman/compose-build/components/preview.vue' + +const { t } = useI18n()🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/render/components/Podman/compose-build/Elasticsearch.vue` around lines 16 - 17, Move the const declaration out of the import block: keep all import statements (including import { useI18n } from 'vue-i18n') grouped at the top, then add the declaration const { t } = useI18n() below the imports (e.g., after the last import or at the start of the script setup). Update the Elasticsearch.vue file so useI18n is only imported in the import section and const { t } = useI18n() appears afterward to match the other components' ordering.src/render/components/Podman/compose-build/PostgreSQL.vue (1)
31-32: Moveconstdeclaration after all imports.Same pattern as other components – group all imports together first.
🔧 Suggested fix
import { computed } from 'vue' import { ComposeBuildForm } from '@/components/Podman/compose-build/Form' import { useI18n } from 'vue-i18n' -const { t } = useI18n() import { OfficialImages } from '@/components/Podman/officialImages' import BaseVM from '@/components/Podman/compose-build/components/base.vue' import PreviewVM from '@/components/Podman/compose-build/components/preview.vue' + +const { t } = useI18n()🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/render/components/Podman/compose-build/PostgreSQL.vue` around lines 31 - 32, The const declaration for t is placed immediately after a single import; move "const { t } = useI18n()" so that all import statements remain grouped at the top and then add the const declaration below the import block (e.g., keep the import { useI18n } from 'vue-i18n' with other imports, then place const { t } = useI18n() after the imports), ensuring useI18n and t usage in the component remains unchanged.src/render/components/PHP/Extension/Macports/index.vue (1)
94-96: Moveconstdeclaration after all imports.Consistent with the pattern across this PR, move
const { t } = useI18n()after all import statements.🔧 Suggested fix
import { type SoftInstalled } from '@/store/brew' import { MacPortsSetup, Setup } from './setup' import { useI18n } from 'vue-i18n' -const { t } = useI18n() import { Link, Document, Download, Delete } from '@element-plus/icons-vue' + +const { t } = useI18n()🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/render/components/PHP/Extension/Macports/index.vue` around lines 94 - 96, The const declaration const { t } = useI18n() is placed before other imports; move the call to useI18n so that const { t } = useI18n() appears after all import statements (e.g., after import { Link, Document, Download, Delete } from '@element-plus/icons-vue') to follow the project's import-first ordering and keep the useI18n invocation below all imports.src/render/components/Mysql/Manage/setPassword.vue (1)
49-52: Moveconstdeclaration after all imports.The
const { t } = useI18n()is placed between import statements with an extra blank line. Group all imports together for consistency.🔧 Suggested fix
import { computed, reactive, ref } from 'vue' import { AsyncComponentSetup } from '@/util/AsyncComponent' import { useI18n } from 'vue-i18n' - -const { t } = useI18n() import type { ModuleInstalledItem } from '@/core/Module/ModuleInstalledItem' import { MySQLManage } from './manage' import { uuid } from '@/util/Index' import { Refresh } from '@element-plus/icons-vue' import { ElMessageBox } from 'element-plus' import { BrewStore } from '@/store/brew' import { MessageSuccess } from '@/util/Element' + +const { t } = useI18n()🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/render/components/Mysql/Manage/setPassword.vue` around lines 49 - 52, Move the top-level const extraction "const { t } = useI18n()" so it appears after all import statements (keep all imports grouped together), e.g., place it after the last import that references ModuleInstalledItem; ensure useI18n is still imported and the symbol t is declared only once and not interleaving import lines.
ℹ️ Review info
Configuration used: defaults
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (104)
src/lang/en/host.jsonsrc/lang/es/host.jsonsrc/lang/fi/host.jsonsrc/lang/fr/host.jsonsrc/lang/id/host.jsonsrc/lang/index.tssrc/lang/it/host.jsonsrc/lang/ja/host.jsonsrc/lang/nl/host.jsonsrc/lang/no/host.jsonsrc/lang/pl/host.jsonsrc/lang/pt-br/host.jsonsrc/lang/pt/host.jsonsrc/lang/ro/host.jsonsrc/lang/ru/host.jsonsrc/lang/sv/host.jsonsrc/lang/tr/host.jsonsrc/lang/uk/host.jsonsrc/lang/vi/host.jsonsrc/lang/zh/host.jsonsrc/render/App.vuesrc/render/components/Conf/drawer.vuesrc/render/components/Deno/Index.vuesrc/render/components/Erlang/Index.vuesrc/render/components/Mysql/Config.vuesrc/render/components/Mysql/Group/Add.vuesrc/render/components/Mysql/Group/Config.vuesrc/render/components/Mysql/Group/Index.vuesrc/render/components/Mysql/Group/Logs.vuesrc/render/components/Mysql/Group/SetupPopper.vuesrc/render/components/Mysql/Index.vuesrc/render/components/Mysql/Manage/addDatabase.vuesrc/render/components/Mysql/Manage/database.vuesrc/render/components/Mysql/Manage/index.vuesrc/render/components/Mysql/Manage/setBackupDir.vuesrc/render/components/Mysql/Manage/setPassword.vuesrc/render/components/Nginx/Config.vuesrc/render/components/Nginx/Index.vuesrc/render/components/Nodejs/Config.vuesrc/render/components/Nodejs/Index.vuesrc/render/components/Nodejs/List.vuesrc/render/components/Nodejs/default/index.vuesrc/render/components/Nodejs/fnm/index.vuesrc/render/components/Nodejs/nvm/index.vuesrc/render/components/Nodejs/projects/dependencies/index.vuesrc/render/components/Ollama/Index.vuesrc/render/components/Ollama/models/all/index.vuesrc/render/components/Ollama/models/index.vuesrc/render/components/Ollama/models/local/index.vuesrc/render/components/PHP/Config.vuesrc/render/components/PHP/DisableFunction.vuesrc/render/components/PHP/ErrorLog.vuesrc/render/components/PHP/Extends.vuesrc/render/components/PHP/Extension/Homebrew/index.vuesrc/render/components/PHP/Extension/Lib/index.vuesrc/render/components/PHP/Extension/Loaded/index.vuesrc/render/components/PHP/Extension/Local/index.vuesrc/render/components/PHP/Extension/Macports/index.vuesrc/render/components/PHP/List.vuesrc/render/components/PHP/Logs.vuesrc/render/components/PHP/aside.vuesrc/render/components/Perl/Index.vuesrc/render/components/Podman/Index.vuesrc/render/components/Podman/compose-build/Base.vuesrc/render/components/Podman/compose-build/Bun.vuesrc/render/components/Podman/compose-build/Consul.vuesrc/render/components/Podman/compose-build/Deno.vuesrc/render/components/Podman/compose-build/Elasticsearch.vuesrc/render/components/Podman/compose-build/Erlang.vuesrc/render/components/Podman/compose-build/Etcd.vuesrc/render/components/Podman/compose-build/Go.vuesrc/render/components/Podman/compose-build/Java.vuesrc/render/components/Podman/compose-build/MariaDB.vuesrc/render/components/Podman/compose-build/Meilisearch.vuesrc/render/components/Podman/compose-build/MinIO.vuesrc/render/components/Podman/compose-build/MongoDB.vuesrc/render/components/Podman/compose-build/MySQL.vuesrc/render/components/Podman/compose-build/NodeJS.vuesrc/render/components/Podman/compose-build/Perl.vuesrc/render/components/Podman/compose-build/PostgreSQL.vuesrc/render/components/Podman/compose-build/Python.vuesrc/render/components/Podman/compose-build/RabbitMQ.vuesrc/render/components/Podman/compose-build/Redis.vuesrc/render/components/Podman/compose-build/Ruby.vuesrc/render/components/Podman/compose-build/Rust.vuesrc/render/components/Podman/compose-build/components/base.vuesrc/render/components/Podman/compose-build/components/docRoot.vuesrc/render/components/Podman/compose-build/components/preview.vuesrc/render/components/Podman/compose-build/components/wwwRoot.vuesrc/render/components/Podman/compose/compose.vuesrc/render/components/Podman/compose/composeAdd.vuesrc/render/components/Podman/compose/composeBuild.vuesrc/render/components/Podman/container/container.vuesrc/render/components/Podman/container/containerCreate.vuesrc/render/components/Podman/container/info.vuesrc/render/components/Podman/container/preview.vuesrc/render/components/Podman/dashboard.vuesrc/render/components/Podman/image/image.vuesrc/render/components/Podman/image/imageAdd.vuesrc/render/components/Podman/left.vuesrc/render/components/Podman/machine/machineAdd.vuesrc/render/components/Podman/right.vuesrc/render/components/PostgreSql/Index.vuesrc/render/tray/App.vue
💤 Files with no reviewable changes (1)
- src/lang/index.ts
| import { useI18n } from 'vue-i18n' | ||
|
|
||
| const { t } = useI18n() | ||
| import type { MysqlGroupItem } from '@shared/app' |
There was a problem hiding this comment.
Incomplete migration: t is declared but never used.
The t function from useI18n() is imported but not utilized. Meanwhile, I18nT(...) is still called throughout the file (lines 80, 117, 128, 140, 156, 209). Complete the migration by replacing all I18nT(...) calls with t(...).
Additionally, the import on line 45 should be moved above the const { t } = useI18n() statement to keep all imports grouped at the top.
🔧 Proposed fix
import { computed } from 'vue'
import { MysqlStore } from '../mysql'
import type { Column } from 'element-plus'
import { useI18n } from 'vue-i18n'
-
-const { t } = useI18n()
import type { MysqlGroupItem } from '@shared/app'
import { AsyncComponentShow } from '@/util/AsyncComponent'
import { MessageError, MessageSuccess } from '@/util/Element'
import Popper from './SetupPopper.vue'
import { shell } from '@/util/NodeFn'
+const { t } = useI18n()
+
const mysqlStore = MysqlStore()Then replace I18nT(...) calls with t(...):
const handleRes = (res: true | string) => {
if (res === true) {
- MessageSuccess(I18nT('base.success'))
+ MessageSuccess(t('base.success'))
} else {Apply similar changes to lines 117, 128, 140, 156, and 209.
🧰 Tools
🪛 ESLint
[error] 44-44: 't' is assigned a value but never used. Allowed unused vars must match /^[hH]$/u.
(@typescript-eslint/no-unused-vars)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/render/components/Mysql/Group/Index.vue` around lines 42 - 45, Move the
import "import type { MysqlGroupItem } from '@shared/app'" above the const { t }
= useI18n() so all imports are grouped, then remove all uses of the legacy
I18nT(...) and replace them with t(...) calls (search for I18nT at places around
the current I18nT usages near lines where messages are built). Ensure you keep
the existing argument(s) passed to I18nT and pass them unchanged to t, and keep
useI18n() as the source of t; verify no unused t warnings remain.
| const tabs = [ | ||
| I18nT('base.service'), | ||
| I18nT('base.versionManager'), | ||
| I18nT('base.configFile'), | ||
| I18nT('base.log'), | ||
| I18nT('base.slowLog'), | ||
| I18nT('base.group') | ||
| t('base.service'), | ||
| t('base.versionManager'), | ||
| t('base.configFile'), | ||
| t('base.log'), | ||
| t('base.slowLog'), | ||
| t('base.group') | ||
| ] |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
find . -name "package.json" -type f | head -5Repository: TanNhatCMS/FlyEnv
Length of output: 380
🏁 Script executed:
git ls-files | grep -E "(i18n|vuerc|tsconfig)" | head -20Repository: TanNhatCMS/FlyEnv
Length of output: 74
🌐 Web query:
vue-i18n v9 composition api locale change reactivity computed
💡 Result:
In vue-i18n v9 (Composition API mode) the locale is a Vue ref, so locale switching (and anything computed that depends on translations) is only reactive if you update/read it as a ref.
Correct reactive pattern (Composition API)
import { useI18n } from 'vue-i18n'
import { computed } from 'vue'
const { t, locale } = useI18n({ useScope: 'global' })
function setLocale(l: string) {
locale.value = l
}
const title = computed(() => t('page.title')) // re-computes when locale changesChanging locale.value will update all t() usages reactively. [1]
Common mistakes
- Using
$t.locale:$tis the translate function, not the i18n/composer instance, so changing$t.localewon’t work. Use$i18n.locale(template) oruseI18n()(script). [3] - Forgetting
.valuewhen changing locale via the global composer:noti18n.global.locale.value = 'en'
i18n.global.locale = 'en'. [4]
Template-side locale switching
<select v-model="$i18n.locale">
<option value="en">en</option>
<option value="ja">ja</option>
</select>This is the documented reactive way (global scope). [1]
Sources: [1] Vue I18n docs (Composition API / Locale Changing), [3] Vue subreddit discussion, [4] Stack Overflow (locale is a ref)
🏁 Script executed:
cat package.json | grep -A 5 -B 5 "vue-i18n"Repository: TanNhatCMS/FlyEnv
Length of output: 324
🏁 Script executed:
find . -name "*.ts" -o -name "*.js" | xargs grep -l "createI18n\|useI18n" | head -5Repository: TanNhatCMS/FlyEnv
Length of output: 5515
🏁 Script executed:
cat src/render/components/Mysql/Index.vue | head -150Repository: TanNhatCMS/FlyEnv
Length of output: 13065
🏁 Script executed:
rg -i "locale.*=|setLocale|i18n.global.locale" --type vue --type ts --type js -A 3 -B 1 | head -100Repository: TanNhatCMS/FlyEnv
Length of output: 88
🏁 Script executed:
rg "computed\s*\(\s*\(\)\s*=>" src/render/components/ --type vue -A 2 | grep -E "(tabs|label|title)" | head -20Repository: TanNhatCMS/FlyEnv
Length of output: 88
🏁 Script executed:
rg "locale\s*=|setLocale" --type-add 'vue:*.vue' -t vue -t ts -t js -A 2 -B 1 | head -80Repository: TanNhatCMS/FlyEnv
Length of output: 2263
🏁 Script executed:
rg "computed\s*\(\s*\(\)\s*=>\s*\[" -A 3 | head -50Repository: TanNhatCMS/FlyEnv
Length of output: 43
Wrap tabs array in computed() for locale-reactive labels.
The tabs array snapshots translated strings at initialization. Since locale switching is implemented elsewhere in the app (src/lang/index.ts), runtime locale changes won't update these labels until the component remounts. Wrap the array in computed() so the translations re-evaluate reactively when locale changes.
Proposed fix
- const tabs = [
- t('base.service'),
- t('base.versionManager'),
- t('base.configFile'),
- t('base.log'),
- t('base.slowLog'),
- t('base.group')
- ]
+ const tabs = computed(() => [
+ t('base.service'),
+ t('base.versionManager'),
+ t('base.configFile'),
+ t('base.log'),
+ t('base.slowLog'),
+ t('base.group')
+ ])📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const tabs = [ | |
| I18nT('base.service'), | |
| I18nT('base.versionManager'), | |
| I18nT('base.configFile'), | |
| I18nT('base.log'), | |
| I18nT('base.slowLog'), | |
| I18nT('base.group') | |
| t('base.service'), | |
| t('base.versionManager'), | |
| t('base.configFile'), | |
| t('base.log'), | |
| t('base.slowLog'), | |
| t('base.group') | |
| ] | |
| const tabs = computed(() => [ | |
| t('base.service'), | |
| t('base.versionManager'), | |
| t('base.configFile'), | |
| t('base.log'), | |
| t('base.slowLog'), | |
| t('base.group') | |
| ]) |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/render/components/Mysql/Index.vue` around lines 88 - 95, The tabs array
currently captures translated strings once; make it reactive by replacing the
plain tabs array with a computed property: wrap the array in computed(() =>
[t('base.service'), t('base.versionManager'), ...]) so translations re-evaluate
on locale change, and ensure computed is imported from 'vue'; keep using the ref
in templates (auto-unwrapped) but if referenced in script logic use tabs.value.
| const tabs = [ | ||
| I18nT('base.service'), | ||
| I18nT('base.versionManager'), | ||
| I18nT('base.configFile'), | ||
| I18nT('base.errorLog'), | ||
| I18nT('base.log') | ||
| t('base.service'), | ||
| t('base.versionManager'), | ||
| t('base.configFile'), | ||
| t('base.errorLog'), | ||
| t('base.log') | ||
| ] |
There was a problem hiding this comment.
🧩 Analysis chain
🌐 Web query:
vue-i18n v9 Composition API t() function automatic locale change reactivity computed
💡 Result:
In vue-i18n v9 (Composition API), the translation result updates automatically on locale change only if t() is executed inside a reactive context (template render, computed, watchEffect, etc.). If you call t() once and store the returned string (e.g., in a plain variable/ref initialized once), it won’t update when locale changes—because the string has no reactive dependency tracking. Vue I18n explicitly notes that changing the global locale makes dependent translations work reactively (when used in reactive contexts). [1]
Correct pattern (reactive)
<script setup lang="ts">
import { computed } from 'vue'
import { useI18n } from 'vue-i18n'
const { t, locale } = useI18n({ useScope: 'global' })
const title = computed(() => t('page.title')) // updates when locale.value changes
function setLang(lang: string) {
locale.value = lang
}
</script>What won’t be reactive
const title = t('page.title') // evaluated once; won't change with localeIf you’re generating lists/objects of labels
Make the whole structure computed:
const columns = computed(() => ([
{ key: 'name', label: t('table.name') },
{ key: 'email', label: t('table.email') },
]))Related API note
Vue I18n’s Composition API also documents that translations (e.g., via resolver-style translation helpers) re-evaluate when locale changes if used in a reactive context—same principle as using t() inside computed/render. [2]
Sources: Vue I18n Composition API guide on reactive locale switching [1], Vue I18n Composition API reference note about re-evaluation on locale change in reactive contexts [2], common Vue-i18n advice to use computed rather than data for reactive translations [3].
References
[1] Vue I18n docs – Composition API / Locale Changing (reactivity on locale change): turn0search0
[2] Vue I18n docs – Composition API reference (reactive context re-evaluates on locale change): turn0search2
[3] Stack Overflow – translations in data not reactive; use computed: turn0search1
🏁 Script executed:
find . -name "Index.vue" -path "*/Nginx/*" | head -5Repository: TanNhatCMS/FlyEnv
Length of output: 100
🏁 Script executed:
cat -n ./src/render/components/Nginx/Index.vue | head -80Repository: TanNhatCMS/FlyEnv
Length of output: 1640
Make tab labels reactive to locale changes.
The tabs array is created once with t() calls at initialization. When users switch language at runtime, the tab labels won't update because the array is not in a reactive context. The template at line 4 iterates over tabs in a v-for, so stale translations will persist even after locale changes.
Wrap tabs in computed() to ensure translation calls re-evaluate when the locale changes:
Suggested fix
+ import { computed } from 'vue'
import { useI18n } from 'vue-i18n'
const { t } = useI18n()
const { tab, checkVersion } = AppModuleSetup('nginx')
- const tabs = [
- t('base.service'),
- t('base.versionManager'),
- t('base.configFile'),
- t('base.errorLog'),
- t('base.log')
- ]
+ const tabs = computed(() => [
+ t('base.service'),
+ t('base.versionManager'),
+ t('base.configFile'),
+ t('base.errorLog'),
+ t('base.log')
+ ])🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/render/components/Nginx/Index.vue` around lines 34 - 40, The tab labels
are created once with t() and stale after locale changes; replace the top-level
const tabs = [...] with a reactive computed wrapper: const tabs = computed(() =>
[t('base.service'), t('base.versionManager'), t('base.configFile'),
t('base.errorLog'), t('base.log')]) and import computed from 'vue' if missing;
the template v-for can continue using tabs (templates auto-unwrap refs) so
translations re-evaluate when the locale changes.
| const tabs = [ | ||
| I18nT('base.service'), | ||
| I18nT('base.versionManager'), | ||
| I18nT('ollama.model'), | ||
| I18nT('base.configFile'), | ||
| I18nT('base.log') | ||
| t('base.service'), | ||
| t('base.versionManager'), | ||
| t('ollama.model'), | ||
| t('base.configFile'), | ||
| t('base.log') | ||
| ] |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
fd "Index.vue" | grep -i ollamaRepository: TanNhatCMS/FlyEnv
Length of output: 99
🏁 Script executed:
cat -n src/render/components/Ollama/Index.vue | head -60Repository: TanNhatCMS/FlyEnv
Length of output: 1699
🌐 Web query:
vue-i18n composition api t() function reactive locale change setup
💡 Result:
In Vue I18n (v9+) Composition API, t is reactive only when it’s evaluated in a reactive context (template, computed, etc.). If you do const label = t('key') in setup(), that string won’t update when the locale changes—wrap it instead. (vue-i18n.intlify.dev)
<script setup>
import { computed } from 'vue'
import { useI18n } from 'vue-i18n'
const { t, locale } = useI18n({ useScope: 'global' }) // or omit options for global by default
const label = computed(() => t('message.hello')) // reactive on locale changes
function setEn() {
locale.value = 'en' // locale is a ref in composition mode
}
</script>
<template>
<p>{{ label }}</p>
<button `@click`="setEn">EN</button>
</template>Notes:
- To switch the whole app, change the global composer locale:
const { locale } = useI18n({ useScope: 'global' }); locale.value = 'en'. (vue-i18n.intlify.dev) - Call
useI18n()once per component and destructure everything from that single call (multiple local-scope calls can break reactivity). (vue-i18n.intlify.dev)
Citations:
- 1: https://vue-i18n.intlify.dev/api/composition?utm_source=openai
- 2: https://vue-i18n.intlify.dev/guide/advanced/composition?utm_source=openai
- 3: https://vue-i18n.intlify.dev/guide/advanced/composition?utm_source=openai
Wrap translated tab labels in computed for locale-switch updates.
Current tabs values are captured once during setup and won't react to language changes at runtime. Per vue-i18n's Composition API, t() is reactive only when evaluated in a reactive context like computed. Direct calls in setup-scope arrays are evaluated once and cached.
♻️ Proposed fix
- const tabs = [
- t('base.service'),
- t('base.versionManager'),
- t('ollama.model'),
- t('base.configFile'),
- t('base.log')
- ]
+ const tabs = computed(() => [
+ t('base.service'),
+ t('base.versionManager'),
+ t('ollama.model'),
+ t('base.configFile'),
+ t('base.log')
+ ])📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const tabs = [ | |
| I18nT('base.service'), | |
| I18nT('base.versionManager'), | |
| I18nT('ollama.model'), | |
| I18nT('base.configFile'), | |
| I18nT('base.log') | |
| t('base.service'), | |
| t('base.versionManager'), | |
| t('ollama.model'), | |
| t('base.configFile'), | |
| t('base.log') | |
| ] | |
| const tabs = computed(() => [ | |
| t('base.service'), | |
| t('base.versionManager'), | |
| t('ollama.model'), | |
| t('base.configFile'), | |
| t('base.log') | |
| ]) |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/render/components/Ollama/Index.vue` around lines 36 - 42, The tab labels
are captured once because tabs is a plain array using t() in setup; change tabs
into a Vue computed so t() is evaluated reactively on locale change: replace the
const tabs = [...] assignment with a computed that returns the array of
t('base.service'), t('base.versionManager'), t('ollama.model'),
t('base.configFile'), t('base.log') and update any template/consumers to use the
computed (tabs.value or destructured) so the labels update when locale changes.
| import { useI18n } from 'vue-i18n' | ||
| const { t } = useI18n() |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Find i18n initialization files
echo "=== Looking for i18n initialization files ==="
fd -e ts -e js -e mjs | xargs rg -l 'createI18n' 2>/dev/null | head -20
echo -e "\n=== Checking src/lang/index.ts if it exists ==="
if [ -f src/lang/index.ts ]; then
echo "File found. Content:"
cat -n src/lang/index.ts
else
echo "File not found"
fi
echo -e "\n=== Searching for createI18n in entire repo ==="
rg -n 'createI18n\(' --type ts --type js -A 10 2>/dev/null | head -100Repository: TanNhatCMS/FlyEnv
Length of output: 7455
Composition API mode is not enabled in i18n configuration.
The component uses useI18n() (Composition API) on lines 120-121, but src/lang/index.ts initializes createI18n without legacy: false. This will cause a runtime error because useI18n() requires Composition API mode.
Fix required in src/lang/index.ts
i18n = createI18n({
+ legacy: false,
locale: l || 'en',
fallbackLocale: 'en',
messages: lang as any
})🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/render/components/PHP/Extends.vue` around lines 120 - 121, The component
uses useI18n() (Composition API) but createI18n was initialized in legacy mode;
update the i18n initialization in src/lang/index.ts by enabling Composition API
mode (pass legacy: false into createI18n configuration) so useI18n() works at
runtime; locate the createI18n(...) call (and any exported i18n instance) and
add legacy: false alongside the existing locale/messages/options.
| {{ | ||
| containerDetail.IsInfra ? I18nT('podman.common.yes') : I18nT('podman.common.no') | ||
| containerDetail.IsInfra ? t('podman.common.yes') : t('podman.common.no') | ||
| }} |
There was a problem hiding this comment.
Resolve Prettier violations in multiline ternaries.
Static analysis flags these ranges as formatting errors; this will likely fail lint gates. Please run formatter or inline the ternaries as suggested by the linter output.
Also applies to: 66-70, 75-79, 85-87, 94-96, 102-106
🧰 Tools
🪛 ESLint
[error] 50-52: Replace ⏎··················containerDetail.IsInfra·?·t('podman.common.yes')·:·t('podman.common.no')⏎··············· with ·containerDetail.IsInfra·?·t('podman.common.yes')·:·t('podman.common.no')
(prettier/prettier)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/render/components/Podman/container/info.vue` around lines 50 - 52, The
multiline ternary expressions in src/render/components/Podman/container/info.vue
(e.g., the expression using containerDetail.IsInfra) are causing Prettier lint
failures; change each multiline ternary to either a single-line ternary (e.g.,
containerDetail.IsInfra ? t('podman.common.yes') : t('podman.common.no')) or
refactor into a computed property or small helper method (e.g.,
computed/isInfraLabel) that returns t('podman.common.yes') or
t('podman.common.no'), and replace the multiline blocks at the indicated ranges
(50-52, 66-70, 75-79, 85-87, 94-96, 102-106) with the single-line expression or
the computed property to satisfy Prettier.
| <el-button type="primary" @click.stop="taskConfirm">{{ | ||
| I18nT('base.confirm') | ||
| taskConfirm('base.confirm') | ||
| }}</el-button> |
There was a problem hiding this comment.
Critical: render-time side effect on confirm button label.
Line 55 calls taskConfirm(...) while rendering, which triggers install/reset logic immediately and renders an empty/undefined label. This should be a translation lookup instead.
Suggested fix
<template v-if="PodmanManager.installEnd">
<el-button type="primary" `@click.stop`="taskConfirm">{{
- taskConfirm('base.confirm')
+ t('base.confirm')
}}</el-button>
</template>📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| <el-button type="primary" @click.stop="taskConfirm">{{ | |
| I18nT('base.confirm') | |
| taskConfirm('base.confirm') | |
| }}</el-button> | |
| <el-button type="primary" `@click.stop`="taskConfirm">{{ | |
| t('base.confirm') | |
| }}</el-button> |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/render/components/Podman/Index.vue` around lines 54 - 56, The template is
calling taskConfirm('base.confirm') during render which causes side effects and
an empty label; stop invoking the action in interpolation—use a pure label
lookup instead and keep taskConfirm as the click handler. Replace the
interpolation {{ taskConfirm('base.confirm') }} with a translation lookup (e.g.
$t('base.confirm')) or a pure computed/property like taskConfirmLabel, and
ensure the button remains <el-button `@click.stop`="taskConfirm"> so the
taskConfirm method (the action with install/reset logic) is only executed on
click.
| <el-form-item v-if="!isEdit" :label="t('podman.identityPath')" prop="identityPath"> | ||
| <el-input v-model="form.identityPath" placeholder="~/.ssh/id_rsa" /> | ||
| </el-form-item> | ||
| <el-form-item v-if="!isEdit" :label="I18nT('podman.remoteUsername')" prop="remoteUsername"> | ||
| <el-form-item v-if="!isEdit" :label="t('podman.remoteUsername')" prop="remoteUsername"> | ||
| <el-input v-model="form.remoteUsername" placeholder="user" /> |
There was a problem hiding this comment.
Localize field placeholders for consistency.
Lines 38 and 41 placeholders are still hardcoded English (~/.ssh/id_rsa, user) while labels are translated. Consider moving placeholders to i18n keys for consistent multilingual UX.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/render/components/Podman/machine/machineAdd.vue` around lines 37 - 41,
The input placeholders for the identity path and remote username are hardcoded;
replace the literal placeholders "~/.ssh/id_rsa" and "user" in the template (the
<el-input> bound to form.identityPath and the <el-input> bound to
form.remoteUsername in machineAdd.vue) with translated i18n keys (e.g.
t('podman.identityPlaceholder') and t('podman.remoteUsernamePlaceholder')), and
add the corresponding keys to the locale files so placeholders are localized
consistently with the labels.
| <template #tool-left> | ||
| <div class="flex items-center gap-1 pl-4 pr-2"> | ||
| <span class="flex-shrink-0">{{ I18nT('util.mysqlDataDir') }}: </span> | ||
| <span class="flex-shrink-0">{{ t('util.mysqlDataDir') }}: </span> |
There was a problem hiding this comment.
Translation key util.mysqlDataDir used in PostgreSQL component.
Using a MySQL-named translation key in a PostgreSQL component is confusing. Consider adding a generic or PostgreSQL-specific translation key (e.g., util.dataDir or util.postgresqlDataDir) for clarity and maintainability.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/render/components/PostgreSql/Index.vue` at line 12, The translation key
used in the PostgreSQL component is misnamed: replace the call to
t('util.mysqlDataDir') inside the Index.vue template with a clearer key such as
t('util.dataDir') or t('util.postgresqlDataDir'); then add the corresponding
entries to the i18n translation files (for all locales) so the new key is
defined. Update any references to the old 'util.mysqlDataDir' key (search for
t('util.mysqlDataDir') or similar) and remove it if no longer used to keep
translations consistent.
| import { shell } from '@/util/NodeFn' | ||
|
|
||
| const { t } = useI18n() | ||
| const { tab, checkVersion } = AppModuleSetup('nginx') |
There was a problem hiding this comment.
Wrong module type passed to AppModuleSetup.
This is a PostgreSQL component, but AppModuleSetup('nginx') passes 'nginx' as the type flag. The Service and Manager components correctly use type-flag="postgresql", so this should be consistent.
🐛 Proposed fix
- const { tab, checkVersion } = AppModuleSetup('nginx')
+ const { tab, checkVersion } = AppModuleSetup('postgresql')📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const { tab, checkVersion } = AppModuleSetup('nginx') | |
| const { tab, checkVersion } = AppModuleSetup('postgresql') |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/render/components/PostgreSql/Index.vue` at line 56, The component
incorrectly calls AppModuleSetup with the 'nginx' type flag; update the call
site where const { tab, checkVersion } = AppModuleSetup('nginx') to use the
'postgresql' type flag so it matches the Service/Manager type-flag="postgresql"
usage and ensures the correct module behavior for this PostgreSql component.
Bumps [fast-xml-parser](https://github.com/NaturalIntelligence/fast-xml-parser) from 5.3.6 to 5.3.8. - [Release notes](https://github.com/NaturalIntelligence/fast-xml-parser/releases) - [Changelog](https://github.com/NaturalIntelligence/fast-xml-parser/blob/master/CHANGELOG.md) - [Commits](NaturalIntelligence/fast-xml-parser@v5.3.6...v5.3.8) --- updated-dependencies: - dependency-name: fast-xml-parser dependency-version: 5.3.8 dependency-type: direct:production ... Signed-off-by: dependabot[bot] <support@github.com>
…d_yarn/fast-xml-parser-5.3.8' into update-lang
| const edit: any = props.item | ||
| for (const key in form.value) { | ||
| form.value[key] = edit?.[key] ?? '' | ||
| } |
There was a problem hiding this comment.
Bug: The Vue form passes flat properties to the CloudflareTunnel class, but the class expects them within a dns array, causing all save operations to fail validation.
Severity: CRITICAL
Suggested Fix
In the form submission logic of add.vue and edit.vue, transform the flat form data into the expected structure before creating the CloudflareTunnel instance. Specifically, create an object with the form values and place it inside the dns array, like new CloudflareTunnel({ dns: [{ subdomain: form.value.subdomain, ... }] }). This ensures the data structure aligns with the backend's requirements.
Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent.
Verify if this is a real issue. If it is, propose a fix; if not, explain why it's not
valid.
Location: src/render/components/CloudflareTunnel/edit.vue#L98-L101
Potential issue: A data structure mismatch exists between the Vue forms and the
`CloudflareTunnel` class. The forms in `add.vue` and `edit.vue` collect individual
properties like `subdomain` and `zoneName` and pass them directly to the
`CloudflareTunnel` constructor. The constructor assigns these as flat properties, but
the backend logic, specifically in `CloudflareTunnel.start()`, expects these properties
to be nested within a `dns` array. Because the `dns` array is never populated and
remains empty, a validation check `if (!this.dns || this.dns.length === 0)` will always
throw an error, preventing any new Cloudflare Tunnels from being created or existing
ones from being saved.
| let versions: SoftInstalled[] = [] | ||
| let all: Promise<SoftInstalled[]>[] = [] | ||
| if (isWindows()) { | ||
| all = [versionLocalFetch(setup?.caddy?.dirs ?? [], 'cloudflared.exe')] |
There was a problem hiding this comment.
Bug: The Cloudflared module incorrectly uses setup?.caddy?.dirs instead of setup?.cloudflared?.dirs to locate installed binaries, breaking custom path detection.
Severity: MEDIUM
Suggested Fix
In src/fork/module/Cloudflared/index.ts, replace the incorrect reference setup?.caddy?.dirs with the correct one, setup?.cloudflared?.dirs. This will ensure the module correctly reads its own configuration when scanning for binaries in custom installation directories.
Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent.
Verify if this is a real issue. If it is, propose a fix; if not, explain why it's not
valid.
Location: src/fork/module/Cloudflared/index.ts#L65
Potential issue: In the Cloudflared module, the logic for discovering installed versions
incorrectly references the configuration for the Caddy module. The code at
`src/fork/module/Cloudflared/index.ts` uses `setup?.caddy?.dirs` to find local binaries,
which is a copy-paste error. The correct path should be `setup?.cloudflared?.dirs` to
match the pattern used by all other modules. This bug prevents the application from
finding Cloudflared binaries installed in custom directories specified by the user in
their `cloudflared` configuration, as it will look in Caddy's custom directories
instead.
Replace legacy I18nT usage with vue-i18n composition API (useI18n and t()) across numerous Vue components (App, Conf drawer, Deno, Erlang, MySQL modules, Podman, etc.). Add 'projectErlang' translation key to many locale host.json files and minor Vietnamese i18n additions. Remove legacy: true from createI18n call. Also add helper-go/go.sum and Windows resource binaries (rsrc_windows_386/amd64.syso).
Summary by CodeRabbit
New Features
Refactor
Localization