mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-02-08 17:10:07 +00:00
fix: resolve i18n no-restricted-imports lint warnings (#8704)
## Summary
Fix all i18n `no-restricted-imports` lint warnings and upgrade rules
from `warn` to `error`.
## Changes
- **What**: Migrate Vue components from `import { t/d } from '@/i18n'`
to `const { t } = useI18n()`. Migrate non-component `.ts` files from
`useI18n()` to `import { t/d } from '@/i18n'`. Allow `st` import from
`@/i18n` in Vue components (it wraps `te`/`t` for safe fallback
translation). Remove `@deprecated` tag from `i18n.ts` global exports
(still used by `st` and non-component code). Upgrade both lint rules
from `warn` to `error`.
## Review Focus
- The `st` helper is intentionally excluded from the Vue component
restriction since it provides safe fallback translation needed for
custom node definitions.
Fixes #8701
┆Issue is synchronized with this [Notion
page](https://www.notion.so/PR-8704-fix-resolve-i18n-no-restricted-imports-lint-warnings-2ff6d73d365081ae84d8eb0dfef24323)
by [Unito](https://www.unito.io)
---------
Co-authored-by: Amp <amp@ampcode.com>
This commit is contained in:
@@ -287,12 +287,12 @@ export default defineConfig([
|
||||
files: ['**/*.vue'],
|
||||
rules: {
|
||||
'no-restricted-imports': [
|
||||
'warn',
|
||||
'error',
|
||||
{
|
||||
paths: [
|
||||
{
|
||||
name: '@/i18n',
|
||||
importNames: ['t', 'd', 'st', 'te'],
|
||||
importNames: ['t', 'd', 'te'],
|
||||
message:
|
||||
"In Vue components, use `const { t } = useI18n()` instead of importing from '@/i18n'."
|
||||
}
|
||||
@@ -301,13 +301,13 @@ export default defineConfig([
|
||||
]
|
||||
}
|
||||
},
|
||||
// Non-composable .ts files must use the global t/d/st/te, not useI18n()
|
||||
// Non-composable .ts files must use the global t/d/te, not useI18n()
|
||||
{
|
||||
files: ['**/*.ts'],
|
||||
ignores: ['**/use[A-Z]*.ts', '**/*.test.ts', 'src/i18n.ts'],
|
||||
rules: {
|
||||
'no-restricted-imports': [
|
||||
'warn',
|
||||
'error',
|
||||
{
|
||||
paths: [
|
||||
{
|
||||
|
||||
@@ -111,6 +111,7 @@ import {
|
||||
watch,
|
||||
watchEffect
|
||||
} from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
import LiteGraphCanvasSplitterOverlay from '@/components/LiteGraphCanvasSplitterOverlay.vue'
|
||||
import TopMenuSection from '@/components/TopMenuSection.vue'
|
||||
@@ -137,7 +138,6 @@ import { useCopy } from '@/composables/useCopy'
|
||||
import { useGlobalLitegraph } from '@/composables/useGlobalLitegraph'
|
||||
import { usePaste } from '@/composables/usePaste'
|
||||
import { useVueFeatureFlags } from '@/composables/useVueFeatureFlags'
|
||||
import { t } from '@/i18n'
|
||||
import { LiteGraph } from '@/lib/litegraph/src/litegraph'
|
||||
import { useLitegraphSettings } from '@/platform/settings/composables/useLitegraphSettings'
|
||||
import { CORE_SETTINGS } from '@/platform/settings/constants/coreSettings'
|
||||
@@ -175,6 +175,7 @@ import { isCloud } from '@/platform/distribution/types'
|
||||
import { useFeatureFlags } from '@/composables/useFeatureFlags'
|
||||
import { useInviteUrlLoader } from '@/platform/workspace/composables/useInviteUrlLoader'
|
||||
|
||||
const { t } = useI18n()
|
||||
const emit = defineEmits<{
|
||||
ready: []
|
||||
}>()
|
||||
|
||||
@@ -94,6 +94,7 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onBeforeUnmount, onMounted, ref, toRaw } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
import AnimationControls from '@/components/load3d/controls/AnimationControls.vue'
|
||||
import CameraControls from '@/components/load3d/controls/viewer/ViewerCameraControls.vue'
|
||||
@@ -104,11 +105,11 @@ import SceneControls from '@/components/load3d/controls/viewer/ViewerSceneContro
|
||||
import Button from '@/components/ui/button/Button.vue'
|
||||
import { useLoad3dDrag } from '@/composables/useLoad3dDrag'
|
||||
import { useLoad3dViewer } from '@/composables/useLoad3dViewer'
|
||||
import { t } from '@/i18n'
|
||||
import type { LGraphNode } from '@/lib/litegraph/src/LGraphNode'
|
||||
import { useLoad3dService } from '@/services/load3dService'
|
||||
import { useDialogStore } from '@/stores/dialogStore'
|
||||
|
||||
const { t } = useI18n()
|
||||
const props = defineProps<{
|
||||
node?: LGraphNode
|
||||
modelUrl?: string
|
||||
|
||||
@@ -94,15 +94,16 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, onMounted, onUnmounted, ref } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
import Button from '@/components/ui/button/Button.vue'
|
||||
import type {
|
||||
MaterialMode,
|
||||
UpDirection
|
||||
} from '@/extensions/core/load3d/interfaces'
|
||||
import { t } from '@/i18n'
|
||||
import { cn } from '@/utils/tailwindUtil'
|
||||
|
||||
const { t } = useI18n()
|
||||
const {
|
||||
hideMaterialMode = false,
|
||||
isPlyModel = false,
|
||||
|
||||
@@ -19,13 +19,15 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
import Load3DViewerContent from '@/components/load3d/Load3dViewerContent.vue'
|
||||
import Button from '@/components/ui/button/Button.vue'
|
||||
import { t } from '@/i18n'
|
||||
import type { LGraphNode } from '@/lib/litegraph/src/LGraphNode'
|
||||
import { useLoad3dService } from '@/services/load3dService'
|
||||
import { useDialogStore } from '@/stores/dialogStore'
|
||||
|
||||
const { t } = useI18n()
|
||||
const { node } = defineProps<{
|
||||
node: LGraphNode
|
||||
}>()
|
||||
|
||||
@@ -30,10 +30,11 @@
|
||||
import Select from 'primevue/select'
|
||||
import Slider from 'primevue/slider'
|
||||
import { computed } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
import type { CameraType } from '@/extensions/core/load3d/interfaces'
|
||||
import { t } from '@/i18n'
|
||||
|
||||
const { t } = useI18n()
|
||||
const cameras = [
|
||||
{ title: t('load3d.cameraType.perspective'), value: 'perspective' },
|
||||
{ title: t('load3d.cameraType.orthographic'), value: 'orthographic' }
|
||||
|
||||
@@ -25,13 +25,14 @@
|
||||
<script setup lang="ts">
|
||||
import Select from 'primevue/select'
|
||||
import { computed } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
import type {
|
||||
MaterialMode,
|
||||
UpDirection
|
||||
} from '@/extensions/core/load3d/interfaces'
|
||||
import { t } from '@/i18n'
|
||||
|
||||
const { t } = useI18n()
|
||||
const { hideMaterialMode = false, isPlyModel = false } = defineProps<{
|
||||
hideMaterialMode?: boolean
|
||||
isPlyModel?: boolean
|
||||
|
||||
@@ -160,14 +160,15 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, onBeforeUnmount, onMounted, ref } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
import { BrushShape } from '@/extensions/core/maskeditor/types'
|
||||
import { t } from '@/i18n'
|
||||
import { useMaskEditorStore } from '@/stores/maskEditorStore'
|
||||
import { cn } from '@/utils/tailwindUtil'
|
||||
|
||||
import SliderControl from './controls/SliderControl.vue'
|
||||
|
||||
const { t } = useI18n()
|
||||
const store = useMaskEditorStore()
|
||||
|
||||
const colorInputRef = ref<HTMLInputElement>()
|
||||
|
||||
@@ -61,14 +61,16 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
import { ColorComparisonMethod } from '@/extensions/core/maskeditor/types'
|
||||
import { t } from '@/i18n'
|
||||
import { useMaskEditorStore } from '@/stores/maskEditorStore'
|
||||
|
||||
import DropdownControl from './controls/DropdownControl.vue'
|
||||
import SliderControl from './controls/SliderControl.vue'
|
||||
import ToggleControl from './controls/ToggleControl.vue'
|
||||
|
||||
const { t } = useI18n()
|
||||
const store = useMaskEditorStore()
|
||||
|
||||
const methodOptions = Object.values(ColorComparisonMethod)
|
||||
|
||||
@@ -131,12 +131,12 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed, ref } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
import { useCanvasManager } from '@/composables/maskeditor/useCanvasManager'
|
||||
import type { useToolManager } from '@/composables/maskeditor/useToolManager'
|
||||
import type { ImageLayer } from '@/extensions/core/maskeditor/types'
|
||||
import { MaskBlendMode, Tools } from '@/extensions/core/maskeditor/types'
|
||||
import { t } from '@/i18n'
|
||||
import { useMaskEditorStore } from '@/stores/maskEditorStore'
|
||||
|
||||
import SliderControl from './controls/SliderControl.vue'
|
||||
@@ -145,6 +145,7 @@ const { toolManager } = defineProps<{
|
||||
toolManager?: ReturnType<typeof useToolManager>
|
||||
}>()
|
||||
|
||||
const { t } = useI18n()
|
||||
const store = useMaskEditorStore()
|
||||
const canvasManager = useCanvasManager()
|
||||
|
||||
|
||||
@@ -27,11 +27,13 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { t } from '@/i18n'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
import { useMaskEditorStore } from '@/stores/maskEditorStore'
|
||||
|
||||
import SliderControl from './controls/SliderControl.vue'
|
||||
|
||||
const { t } = useI18n()
|
||||
const store = useMaskEditorStore()
|
||||
|
||||
const onToleranceChange = (value: number) => {
|
||||
|
||||
@@ -31,18 +31,19 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
import type { useToolManager } from '@/composables/maskeditor/useToolManager'
|
||||
import { iconsHtml } from '@/extensions/core/maskeditor/constants'
|
||||
import type { Tools } from '@/extensions/core/maskeditor/types'
|
||||
import { allTools } from '@/extensions/core/maskeditor/types'
|
||||
import { t } from '@/i18n'
|
||||
import { useMaskEditorStore } from '@/stores/maskEditorStore'
|
||||
|
||||
const { toolManager } = defineProps<{
|
||||
toolManager: ReturnType<typeof useToolManager>
|
||||
}>()
|
||||
|
||||
const { t } = useI18n()
|
||||
const store = useMaskEditorStore()
|
||||
|
||||
const onToolSelect = (tool: Tools) => {
|
||||
|
||||
@@ -128,15 +128,16 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
import Button from '@/components/ui/button/Button.vue'
|
||||
import { useCanvasTools } from '@/composables/maskeditor/useCanvasTools'
|
||||
import { useCanvasTransform } from '@/composables/maskeditor/useCanvasTransform'
|
||||
import { useMaskEditorSaver } from '@/composables/maskeditor/useMaskEditorSaver'
|
||||
import { t } from '@/i18n'
|
||||
import { useDialogStore } from '@/stores/dialogStore'
|
||||
import { useMaskEditorStore } from '@/stores/maskEditorStore'
|
||||
|
||||
const { t } = useI18n()
|
||||
const store = useMaskEditorStore()
|
||||
const dialogStore = useDialogStore()
|
||||
const canvasTools = useCanvasTools()
|
||||
|
||||
@@ -44,6 +44,7 @@ const props = defineProps<{
|
||||
}>()
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
const executionStore = useExecutionStore()
|
||||
const {
|
||||
totalPercent,
|
||||
|
||||
@@ -36,6 +36,7 @@ const canvasStore = useCanvasStore()
|
||||
const rightSidePanelStore = useRightSidePanelStore()
|
||||
const settingStore = useSettingStore()
|
||||
const { t } = useI18n()
|
||||
|
||||
const { findParentGroup } = useGraphHierarchy()
|
||||
|
||||
const { selectedItems: directlySelectedItems } = storeToRefs(canvasStore)
|
||||
|
||||
@@ -46,6 +46,7 @@ const emit = defineEmits<{
|
||||
}>()
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
const canvasStore = useCanvasStore()
|
||||
const favoritedWidgetsStore = useFavoritedWidgetsStore()
|
||||
const isEditing = ref(false)
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
import Button from '@/components/ui/button/Button.vue'
|
||||
import { t } from '@/i18n'
|
||||
import { useKeybindingStore } from '@/platform/keybindings/keybindingStore'
|
||||
import { useCanvasStore } from '@/renderer/core/canvas/canvasStore'
|
||||
import { useCommandStore } from '@/stores/commandStore'
|
||||
|
||||
const { t } = useI18n()
|
||||
const canvasStore = useCanvasStore()
|
||||
const keybindingStore = useKeybindingStore()
|
||||
|
||||
|
||||
@@ -58,6 +58,7 @@
|
||||
import { useResizeObserver } from '@vueuse/core'
|
||||
import { debounce } from 'es-toolkit/compat'
|
||||
import { computed, nextTick, onBeforeUnmount, onMounted, ref, watch } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
import HelpCenterPopups from '@/components/helpcenter/HelpCenterPopups.vue'
|
||||
import ComfyMenuButton from '@/components/sidebar/ComfyMenuButton.vue'
|
||||
@@ -66,7 +67,6 @@ import SidebarBottomPanelToggleButton from '@/components/sidebar/SidebarBottomPa
|
||||
import SidebarSettingsButton from '@/components/sidebar/SidebarSettingsButton.vue'
|
||||
import SidebarShortcutsToggleButton from '@/components/sidebar/SidebarShortcutsToggleButton.vue'
|
||||
import { useFeatureFlags } from '@/composables/useFeatureFlags'
|
||||
import { t } from '@/i18n'
|
||||
import { isCloud } from '@/platform/distribution/types'
|
||||
import { useSettingStore } from '@/platform/settings/settingStore'
|
||||
import { useTelemetry } from '@/platform/telemetry'
|
||||
@@ -84,6 +84,7 @@ import SidebarIcon from './SidebarIcon.vue'
|
||||
import SidebarLogoutIcon from './SidebarLogoutIcon.vue'
|
||||
import SidebarTemplatesButton from './SidebarTemplatesButton.vue'
|
||||
|
||||
const { t } = useI18n()
|
||||
const workspaceStore = useWorkspaceStore()
|
||||
const settingStore = useSettingStore()
|
||||
const userStore = useUserStore()
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
import { t } from '@/i18n'
|
||||
import type { TopbarBadge as TopbarBadgeType } from '@/types/comfy'
|
||||
|
||||
import TopbarBadge from './TopbarBadge.vue'
|
||||
@@ -31,6 +31,8 @@ withDefaults(
|
||||
}
|
||||
)
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
const cloudBadge = computed<TopbarBadgeType>(() => ({
|
||||
label: t('g.beta'),
|
||||
text: 'Comfy Cloud'
|
||||
|
||||
@@ -37,17 +37,18 @@
|
||||
import Popover from 'primevue/popover'
|
||||
import type { HTMLAttributes } from 'vue'
|
||||
import { ref } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
import Button from '@/components/ui/button/Button.vue'
|
||||
import { useCurrentUser } from '@/composables/auth/useCurrentUser'
|
||||
import { useExternalLink } from '@/composables/useExternalLink'
|
||||
import { t } from '@/i18n'
|
||||
import { cn } from '@/utils/tailwindUtil'
|
||||
|
||||
const { class: className } = defineProps<{
|
||||
class?: HTMLAttributes['class']
|
||||
}>()
|
||||
|
||||
const { t } = useI18n()
|
||||
const { isLoggedIn, handleSignIn } = useCurrentUser()
|
||||
const { buildDocsUrl } = useExternalLink()
|
||||
const apiNodesOverviewUrl = buildDocsUrl(
|
||||
|
||||
@@ -201,7 +201,6 @@ export const i18n = createI18n({
|
||||
})
|
||||
|
||||
/** Convenience shorthand: i18n.global */
|
||||
/** @deprecated use useI18n */
|
||||
export const { t, te, d } = i18n.global
|
||||
|
||||
/**
|
||||
|
||||
@@ -62,14 +62,17 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
import Button from '@/components/ui/button/Button.vue'
|
||||
import { t } from '@/i18n'
|
||||
import videoPoster from '@/platform/cloud/onboarding/assets/videos/thumbnail.png'
|
||||
import videoSrc from '@/platform/cloud/onboarding/assets/videos/video.mp4'
|
||||
import CloudLogo from '@/platform/cloud/onboarding/components/CloudLogo.vue'
|
||||
import CloudTemplateFooter from '@/platform/cloud/onboarding/components/CloudTemplateFooter.vue'
|
||||
import BaseViewTemplate from '@/views/templates/BaseViewTemplate.vue'
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
const handleDownloadClick = () => {
|
||||
window.open('https://www.comfy.org/download', '_blank')
|
||||
}
|
||||
|
||||
@@ -79,6 +79,17 @@ const i18n = createI18n({
|
||||
currentPlan: 'Current Plan',
|
||||
subscribeTo: 'Subscribe to {plan}',
|
||||
changeTo: 'Change to {plan}',
|
||||
tierNameYearly: '{name} Yearly',
|
||||
yearlyCreditsLabel: 'Yearly credits',
|
||||
monthlyCreditsLabel: 'Monthly credits',
|
||||
maxDurationLabel: 'Max duration',
|
||||
gpuLabel: 'GPU',
|
||||
addCreditsLabel: 'Add more credits',
|
||||
customLoRAsLabel: 'Custom LoRAs',
|
||||
videoEstimateLabel: 'Video estimate',
|
||||
videoEstimateHelp: 'How is this calculated?',
|
||||
videoEstimateExplanation: 'Based on average usage.',
|
||||
videoEstimateTryTemplate: 'Try template',
|
||||
maxDuration: {
|
||||
standard: '30 min',
|
||||
creator: '30 min',
|
||||
|
||||
@@ -252,7 +252,6 @@ import { useI18n } from 'vue-i18n'
|
||||
import Button from '@/components/ui/button/Button.vue'
|
||||
import { useFirebaseAuthActions } from '@/composables/auth/useFirebaseAuthActions'
|
||||
import { useErrorHandling } from '@/composables/useErrorHandling'
|
||||
import { t } from '@/i18n'
|
||||
import { useSubscription } from '@/platform/cloud/subscription/composables/useSubscription'
|
||||
import {
|
||||
TIER_PRICING,
|
||||
@@ -292,6 +291,8 @@ interface PricingTierConfig {
|
||||
isPopular?: boolean
|
||||
}
|
||||
|
||||
const { t, n } = useI18n()
|
||||
|
||||
const billingCycleOptions: BillingCycleOption[] = [
|
||||
{ label: t('subscription.yearly'), value: 'yearly' },
|
||||
{ label: t('subscription.monthly'), value: 'monthly' }
|
||||
@@ -326,8 +327,6 @@ const tiers: PricingTierConfig[] = [
|
||||
isPopular: false
|
||||
}
|
||||
]
|
||||
|
||||
const { n } = useI18n()
|
||||
const { isActiveSubscription, subscriptionTier, isYearlySubscription } =
|
||||
useSubscription()
|
||||
const { accessBillingPortal, reportError } = useFirebaseAuthActions()
|
||||
|
||||
@@ -40,6 +40,7 @@ const props = defineProps<{
|
||||
}>()
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
function translateOptions(options: (SettingOption | string)[]) {
|
||||
if (typeof options === 'function') {
|
||||
// @ts-expect-error: Audit and deprecate usage of legacy options type:
|
||||
|
||||
@@ -3,11 +3,11 @@ import { useEventListener, useTimeout } from '@vueuse/core'
|
||||
import { partition } from 'es-toolkit'
|
||||
import { storeToRefs } from 'pinia'
|
||||
import { computed, ref, shallowRef } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
import Popover from '@/components/ui/Popover.vue'
|
||||
import Button from '@/components/ui/button/Button.vue'
|
||||
import { extractVueNodeData } from '@/composables/graph/useGraphNodeManager'
|
||||
import { t } from '@/i18n'
|
||||
import type { LGraphNode } from '@/lib/litegraph/src/LGraphNode'
|
||||
import { useBillingContext } from '@/composables/billing/useBillingContext'
|
||||
import SubscribeToRunButton from '@/platform/cloud/subscription/components/SubscribeToRun.vue'
|
||||
@@ -26,6 +26,7 @@ import { useQueueSettingsStore } from '@/stores/queueStore'
|
||||
import type { SimplifiedWidget } from '@/types/simplifiedWidget'
|
||||
import { cn } from '@/utils/tailwindUtil'
|
||||
|
||||
const { t } = useI18n()
|
||||
const commandStore = useCommandStore()
|
||||
const executionStore = useExecutionStore()
|
||||
const { batchCount } = storeToRefs(useQueueSettingsStore())
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
import { downloadFile } from '@/base/common/downloadUtil'
|
||||
import Popover from '@/components/ui/Popover.vue'
|
||||
import Button from '@/components/ui/button/Button.vue'
|
||||
import { d, t } from '@/i18n'
|
||||
import { useMediaAssetActions } from '@/platform/assets/composables/useMediaAssetActions'
|
||||
import { getOutputAssetMetadata } from '@/platform/assets/schemas/assetMetadataSchema'
|
||||
import type { AssetItem } from '@/platform/assets/schemas/assetSchema'
|
||||
@@ -26,6 +26,7 @@ import { formatDuration } from '@/utils/dateTimeUtil'
|
||||
import { collectAllNodes } from '@/utils/graphTraversalUtil'
|
||||
import { executeWidgetsCallback } from '@/utils/litegraphUtil'
|
||||
|
||||
const { t, d } = useI18n()
|
||||
const mediaActions = useMediaAssetActions()
|
||||
|
||||
const { runButtonClick, selectedItem, selectedOutput } = defineProps<{
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import { t } from '@/i18n'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
const { t } = useI18n()
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
||||
@@ -4,13 +4,15 @@ import {
|
||||
CollapsibleTrigger,
|
||||
CollapsibleContent
|
||||
} from 'reka-ui'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
import WorkflowsSidebarTab from '@/components/sidebar/tabs/WorkflowsSidebarTab.vue'
|
||||
import Button from '@/components/ui/button/Button.vue'
|
||||
import Popover from '@/components/ui/Popover.vue'
|
||||
import { useWorkflowTemplateSelectorDialog } from '@/composables/useWorkflowTemplateSelectorDialog'
|
||||
import { t } from '@/i18n'
|
||||
import { useCommandStore } from '@/stores/commandStore'
|
||||
|
||||
const { t } = useI18n()
|
||||
</script>
|
||||
<template>
|
||||
<CollapsibleRoot class="flex flex-col">
|
||||
|
||||
@@ -85,8 +85,8 @@
|
||||
import { useIntervalFn } from '@vueuse/core'
|
||||
import { Button } from 'primevue'
|
||||
import { computed, onMounted, onUnmounted, ref } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
import { t } from '@/i18n'
|
||||
import type { LGraphNode } from '@/lib/litegraph/src/LGraphNode'
|
||||
import type { IBaseWidget } from '@/lib/litegraph/src/types/widgets'
|
||||
import { useToastStore } from '@/platform/updates/common/toastStore'
|
||||
@@ -98,6 +98,8 @@ import { useAudioRecorder } from '../composables/audio/useAudioRecorder'
|
||||
import { useAudioWaveform } from '../composables/audio/useAudioWaveform'
|
||||
import { formatTime } from '../utils/audioUtils'
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
const props = defineProps<{
|
||||
readonly?: boolean
|
||||
nodeId: string
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<script setup lang="ts">
|
||||
import Popover from 'primevue/popover'
|
||||
import { computed, ref, useTemplateRef } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
import { t } from '@/i18n'
|
||||
import { useToastStore } from '@/platform/updates/common/toastStore'
|
||||
|
||||
import type {
|
||||
@@ -46,16 +46,28 @@ interface Props {
|
||||
) => Promise<FormDropdownItem[]>
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
placeholder: t('widgets.uploadSelect.placeholder'),
|
||||
multiple: false,
|
||||
uploadable: false,
|
||||
disabled: false,
|
||||
filterOptions: () => [],
|
||||
sortOptions: () => getDefaultSortOptions(),
|
||||
isSelected: (selected, item, _index) => selected.has(item.id),
|
||||
searcher: defaultSearcher
|
||||
})
|
||||
const { t } = useI18n()
|
||||
|
||||
const {
|
||||
placeholder,
|
||||
multiple = false,
|
||||
uploadable = false,
|
||||
disabled = false,
|
||||
accept,
|
||||
filterOptions = [],
|
||||
sortOptions = getDefaultSortOptions(),
|
||||
showOwnershipFilter,
|
||||
ownershipOptions,
|
||||
showBaseModelFilter,
|
||||
baseModelOptions,
|
||||
isSelected = (selected, item, _index) => selected.has(item.id),
|
||||
searcher = defaultSearcher,
|
||||
items
|
||||
} = defineProps<Props>()
|
||||
|
||||
const placeholderText = computed(
|
||||
() => placeholder ?? t('widgets.uploadSelect.placeholder')
|
||||
)
|
||||
|
||||
const selected = defineModel<Set<string>>('selected', {
|
||||
default: () => new Set()
|
||||
@@ -82,24 +94,22 @@ const triggerRef = useTemplateRef('triggerRef')
|
||||
const isOpen = ref(false)
|
||||
|
||||
const maxSelectable = computed(() => {
|
||||
if (props.multiple === true) return Infinity
|
||||
if (typeof props.multiple === 'number') return props.multiple
|
||||
if (multiple === true) return Infinity
|
||||
if (typeof multiple === 'number') return multiple
|
||||
return 1
|
||||
})
|
||||
|
||||
const itemsKey = computed(() => props.items.map((item) => item.id).join('|'))
|
||||
const itemsKey = computed(() => items.map((item) => item.id).join('|'))
|
||||
|
||||
const filteredItems = ref<FormDropdownItem[]>([])
|
||||
|
||||
const defaultSorter = computed<SortOption['sorter']>(() => {
|
||||
const sorter = props.sortOptions.find(
|
||||
(option) => option.id === 'default'
|
||||
)?.sorter
|
||||
return sorter || (({ items }) => items.slice())
|
||||
const sorter = sortOptions.find((option) => option.id === 'default')?.sorter
|
||||
return sorter || (({ items: i }) => i.slice())
|
||||
})
|
||||
const selectedSorter = computed<SortOption['sorter']>(() => {
|
||||
if (sortSelected.value === 'default') return defaultSorter.value
|
||||
const sorter = props.sortOptions.find(
|
||||
const sorter = sortOptions.find(
|
||||
(option) => option.id === sortSelected.value
|
||||
)?.sorter
|
||||
return sorter || defaultSorter.value
|
||||
@@ -109,11 +119,11 @@ const sortedItems = computed(() => {
|
||||
})
|
||||
|
||||
function internalIsSelected(item: FormDropdownItem, index: number): boolean {
|
||||
return props.isSelected?.(selected.value, item, index) ?? false
|
||||
return isSelected(selected.value, item, index)
|
||||
}
|
||||
|
||||
const toggleDropdown = (event: Event) => {
|
||||
if (props.disabled) return
|
||||
if (disabled) return
|
||||
if (popoverRef.value && triggerRef.value) {
|
||||
popoverRef.value.toggle(event, triggerRef.value)
|
||||
isOpen.value = !isOpen.value
|
||||
@@ -128,7 +138,7 @@ const closeDropdown = () => {
|
||||
}
|
||||
|
||||
function handleFileChange(event: Event) {
|
||||
if (props.disabled) return
|
||||
if (disabled) return
|
||||
const target = event.target
|
||||
if (!(target instanceof HTMLInputElement)) return
|
||||
if (target.files) {
|
||||
@@ -138,7 +148,7 @@ function handleFileChange(event: Event) {
|
||||
}
|
||||
|
||||
function handleSelection(item: FormDropdownItem, index: number) {
|
||||
if (props.disabled) return
|
||||
if (disabled) return
|
||||
const sel = selected.value
|
||||
if (internalIsSelected(item, index)) {
|
||||
sel.delete(item.id)
|
||||
@@ -170,11 +180,9 @@ async function customSearcher(
|
||||
isCleanup = true
|
||||
cleanupFn?.()
|
||||
})
|
||||
await props
|
||||
.searcher(query, props.items, (cb) => (cleanupFn = cb))
|
||||
.then((results) => {
|
||||
if (!isCleanup) filteredItems.value = results
|
||||
})
|
||||
await searcher(query, items, (cb) => (cleanupFn = cb)).then((results) => {
|
||||
if (!isCleanup) filteredItems.value = results
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -183,7 +191,7 @@ async function customSearcher(
|
||||
<FormDropdownInput
|
||||
:files
|
||||
:is-open
|
||||
:placeholder
|
||||
:placeholder="placeholderText"
|
||||
:items
|
||||
:max-selectable
|
||||
:selected
|
||||
|
||||
@@ -31,8 +31,8 @@ vi.mock('@/stores/firebaseAuthStore', () => ({
|
||||
useFirebaseAuthStore: vi.fn(() => mockFirebaseAuthStore)
|
||||
}))
|
||||
|
||||
vi.mock('vue-i18n', () => ({
|
||||
useI18n: vi.fn(() => mockI18n)
|
||||
vi.mock('@/i18n', () => ({
|
||||
d: mockI18n.d
|
||||
}))
|
||||
|
||||
vi.mock('@/utils/typeGuardUtil', () => ({
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import type { AxiosError, AxiosResponse } from 'axios'
|
||||
import axios from 'axios'
|
||||
import { ref, watch } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
import { getComfyApiBaseUrl } from '@/config/comfyApi'
|
||||
import { d } from '@/i18n'
|
||||
import { useFirebaseAuthStore } from '@/stores/firebaseAuthStore'
|
||||
import type { components, operations } from '@/types/comfyRegistryTypes'
|
||||
import { isAbortError } from '@/utils/typeGuardUtil'
|
||||
@@ -33,7 +33,6 @@ const customerApiClient = axios.create({
|
||||
export const useCustomerEventsService = () => {
|
||||
const isLoading = ref(false)
|
||||
const error = ref<string | null>(null)
|
||||
const { d } = useI18n()
|
||||
|
||||
watch(
|
||||
() => getComfyApiBaseUrl(),
|
||||
|
||||
@@ -8,12 +8,12 @@ import {
|
||||
import Splitter from 'primevue/splitter'
|
||||
import SplitterPanel from 'primevue/splitterpanel'
|
||||
import { ref, useTemplateRef } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
import ModeToggle from '@/components/sidebar/ModeToggle.vue'
|
||||
import TopbarBadges from '@/components/topbar/TopbarBadges.vue'
|
||||
import WorkflowTabs from '@/components/topbar/WorkflowTabs.vue'
|
||||
import TypeformPopoverButton from '@/components/ui/TypeformPopoverButton.vue'
|
||||
import { t } from '@/i18n'
|
||||
import type { AssetItem } from '@/platform/assets/schemas/assetSchema'
|
||||
import { useSettingStore } from '@/platform/settings/settingStore'
|
||||
import LinearControls from '@/renderer/extensions/linearMode/LinearControls.vue'
|
||||
@@ -23,6 +23,7 @@ import OutputHistory from '@/renderer/extensions/linearMode/OutputHistory.vue'
|
||||
import { useNodeOutputStore } from '@/stores/imagePreviewStore'
|
||||
import type { ResultItemImpl } from '@/stores/queueStore'
|
||||
|
||||
const { t } = useI18n()
|
||||
const nodeOutputStore = useNodeOutputStore()
|
||||
const settingStore = useSettingStore()
|
||||
|
||||
|
||||
@@ -2,8 +2,8 @@ import { useEventListener, whenever } from '@vueuse/core'
|
||||
import { defineStore } from 'pinia'
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
import { ref, watch } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
import { t } from '@/i18n'
|
||||
import { useCachedRequest } from '@/composables/useCachedRequest'
|
||||
import { useServerLogs } from '@/composables/useServerLogs'
|
||||
import { api } from '@/scripts/api'
|
||||
@@ -30,7 +30,6 @@ type UpdateAllPacksParams = components['schemas']['UpdateAllPacksParams']
|
||||
* Store for state of installed node packs
|
||||
*/
|
||||
export const useComfyManagerStore = defineStore('comfyManager', () => {
|
||||
const { t } = useI18n()
|
||||
const managerService = useComfyManagerService()
|
||||
|
||||
const installedPacks = ref<InstalledPacksResponse>({})
|
||||
|
||||
Reference in New Issue
Block a user