mirror of
https://github.com/n8n-io/n8n.git
synced 2024-12-30 06:59:41 -08:00
refactor(editor): Stop using $locale
in favor of the i18n
composable (#11731)
Some checks failed
Test Master / install-and-build (push) Has been cancelled
Test Master / Unit tests (18.x) (push) Has been cancelled
Test Master / Unit tests (20.x) (push) Has been cancelled
Test Master / Unit tests (22.4) (push) Has been cancelled
Test Master / Lint (push) Has been cancelled
Test Master / Notify Slack on failure (push) Has been cancelled
Some checks failed
Test Master / install-and-build (push) Has been cancelled
Test Master / Unit tests (18.x) (push) Has been cancelled
Test Master / Unit tests (20.x) (push) Has been cancelled
Test Master / Unit tests (22.4) (push) Has been cancelled
Test Master / Lint (push) Has been cancelled
Test Master / Notify Slack on failure (push) Has been cancelled
Co-authored-by: कारतोफ्फेलस्क्रिप्ट™ <aditya@netroy.in>
This commit is contained in:
parent
54e1f62535
commit
3f9127955a
|
@ -1,6 +1,6 @@
|
|||
import type { Plugin } from 'vue';
|
||||
import { render } from '@testing-library/vue';
|
||||
import { i18nInstance, I18nPlugin } from '@/plugins/i18n';
|
||||
import { i18nInstance } from '@/plugins/i18n';
|
||||
import { GlobalComponentsPlugin } from '@/plugins/components';
|
||||
import { GlobalDirectivesPlugin } from '@/plugins/directives';
|
||||
import { FontAwesomePlugin } from '@/plugins/icons';
|
||||
|
@ -32,7 +32,6 @@ const defaultOptions = {
|
|||
'vue-json-pretty': vueJsonPretty,
|
||||
},
|
||||
plugins: [
|
||||
I18nPlugin,
|
||||
i18nInstance,
|
||||
PiniaVuePlugin,
|
||||
FontAwesomePlugin,
|
||||
|
|
|
@ -66,9 +66,9 @@ const startNewSession = async () => {
|
|||
</template>
|
||||
<template #footer>
|
||||
<div :class="$style.footer">
|
||||
<n8n-button :label="$locale.baseText('generic.cancel')" type="secondary" @click="close" />
|
||||
<n8n-button :label="i18n.baseText('generic.cancel')" type="secondary" @click="close" />
|
||||
<n8n-button
|
||||
:label="$locale.baseText('aiAssistant.newSessionModal.confirm')"
|
||||
:label="i18n.baseText('aiAssistant.newSessionModal.confirm')"
|
||||
@click="startNewSession"
|
||||
/>
|
||||
</div>
|
||||
|
|
|
@ -4,6 +4,7 @@ import type { IBinaryData, IRunData } from 'n8n-workflow';
|
|||
import BinaryDataDisplayEmbed from '@/components/BinaryDataDisplayEmbed.vue';
|
||||
import { useWorkflowsStore } from '@/stores/workflows.store';
|
||||
import { useNodeHelpers } from '@/composables/useNodeHelpers';
|
||||
import { useI18n } from '@/composables/useI18n';
|
||||
|
||||
const props = defineProps<{
|
||||
displayData: IBinaryData;
|
||||
|
@ -17,6 +18,8 @@ const emit = defineEmits<{
|
|||
const nodeHelpers = useNodeHelpers();
|
||||
const workflowsStore = useWorkflowsStore();
|
||||
|
||||
const i18n = useI18n();
|
||||
|
||||
const workflowRunData = computed<IRunData | null>(() => {
|
||||
const workflowExecution = workflowsStore.getWorkflowExecution;
|
||||
if (workflowExecution === null) {
|
||||
|
@ -74,15 +77,15 @@ function closeWindow() {
|
|||
<n8n-button
|
||||
size="small"
|
||||
class="binary-data-window-back"
|
||||
:title="$locale.baseText('binaryDataDisplay.backToOverviewPage')"
|
||||
:title="i18n.baseText('binaryDataDisplay.backToOverviewPage')"
|
||||
icon="arrow-left"
|
||||
:label="$locale.baseText('binaryDataDisplay.backToList')"
|
||||
:label="i18n.baseText('binaryDataDisplay.backToList')"
|
||||
@click.stop="closeWindow"
|
||||
/>
|
||||
|
||||
<div class="binary-data-window-wrapper">
|
||||
<div v-if="!binaryData">
|
||||
{{ $locale.baseText('binaryDataDisplay.noDataFoundToDisplay') }}
|
||||
{{ i18n.baseText('binaryDataDisplay.noDataFoundToDisplay') }}
|
||||
</div>
|
||||
<BinaryDataDisplayEmbed v-else :binary-data="binaryData" />
|
||||
</div>
|
||||
|
|
|
@ -5,6 +5,7 @@ import type { IBinaryData } from 'n8n-workflow';
|
|||
import { jsonParse } from 'n8n-workflow';
|
||||
import VueJsonPretty from 'vue-json-pretty';
|
||||
import RunDataHtml from '@/components/RunDataHtml.vue';
|
||||
import { useI18n } from '@/composables/useI18n';
|
||||
|
||||
const props = defineProps<{
|
||||
binaryData: IBinaryData;
|
||||
|
@ -17,6 +18,8 @@ const data = ref('');
|
|||
|
||||
const workflowsStore = useWorkflowsStore();
|
||||
|
||||
const i18n = useI18n();
|
||||
|
||||
const embedClass = computed(() => {
|
||||
return [props.binaryData.fileType ?? 'other'];
|
||||
});
|
||||
|
@ -57,11 +60,11 @@ onMounted(async () => {
|
|||
<span v-else>
|
||||
<video v-if="binaryData.fileType === 'video'" controls autoplay>
|
||||
<source :src="embedSource" :type="binaryData.mimeType" />
|
||||
{{ $locale.baseText('binaryDataDisplay.yourBrowserDoesNotSupport') }}
|
||||
{{ i18n.baseText('binaryDataDisplay.yourBrowserDoesNotSupport') }}
|
||||
</video>
|
||||
<audio v-else-if="binaryData.fileType === 'audio'" controls autoplay>
|
||||
<source :src="embedSource" :type="binaryData.mimeType" />
|
||||
{{ $locale.baseText('binaryDataDisplay.yourBrowserDoesNotSupport') }}
|
||||
{{ i18n.baseText('binaryDataDisplay.yourBrowserDoesNotSupport') }}
|
||||
</audio>
|
||||
<img v-else-if="binaryData.fileType === 'image'" :src="embedSource" />
|
||||
<VueJsonPretty
|
||||
|
|
|
@ -4,11 +4,13 @@ import { storeToRefs } from 'pinia';
|
|||
import { useCanvasStore } from '@/stores/canvas.store';
|
||||
import KeyboardShortcutTooltip from '@/components/KeyboardShortcutTooltip.vue';
|
||||
import { useDeviceSupport } from 'n8n-design-system';
|
||||
import { useI18n } from '@/composables/useI18n';
|
||||
|
||||
const canvasStore = useCanvasStore();
|
||||
const { zoomToFit, zoomIn, zoomOut, resetZoom } = canvasStore;
|
||||
const { nodeViewScale, isDemo } = storeToRefs(canvasStore);
|
||||
const deviceSupport = useDeviceSupport();
|
||||
const i18n = useI18n();
|
||||
|
||||
const keyDown = (e: KeyboardEvent) => {
|
||||
const isCtrlKeyPressed = deviceSupport.isCtrlKeyPressed(e);
|
||||
|
@ -41,7 +43,7 @@ onBeforeUnmount(() => {
|
|||
}"
|
||||
>
|
||||
<KeyboardShortcutTooltip
|
||||
:label="$locale.baseText('nodeView.zoomToFit')"
|
||||
:label="i18n.baseText('nodeView.zoomToFit')"
|
||||
:shortcut="{ keys: ['1'] }"
|
||||
>
|
||||
<n8n-icon-button
|
||||
|
@ -52,10 +54,7 @@ onBeforeUnmount(() => {
|
|||
@click="zoomToFit"
|
||||
/>
|
||||
</KeyboardShortcutTooltip>
|
||||
<KeyboardShortcutTooltip
|
||||
:label="$locale.baseText('nodeView.zoomIn')"
|
||||
:shortcut="{ keys: ['+'] }"
|
||||
>
|
||||
<KeyboardShortcutTooltip :label="i18n.baseText('nodeView.zoomIn')" :shortcut="{ keys: ['+'] }">
|
||||
<n8n-icon-button
|
||||
type="tertiary"
|
||||
size="large"
|
||||
|
@ -64,10 +63,7 @@ onBeforeUnmount(() => {
|
|||
@click="zoomIn"
|
||||
/>
|
||||
</KeyboardShortcutTooltip>
|
||||
<KeyboardShortcutTooltip
|
||||
:label="$locale.baseText('nodeView.zoomOut')"
|
||||
:shortcut="{ keys: ['-'] }"
|
||||
>
|
||||
<KeyboardShortcutTooltip :label="i18n.baseText('nodeView.zoomOut')" :shortcut="{ keys: ['-'] }">
|
||||
<n8n-icon-button
|
||||
type="tertiary"
|
||||
size="large"
|
||||
|
@ -77,7 +73,7 @@ onBeforeUnmount(() => {
|
|||
/>
|
||||
</KeyboardShortcutTooltip>
|
||||
<KeyboardShortcutTooltip
|
||||
:label="$locale.baseText('nodeView.resetZoom')"
|
||||
:label="i18n.baseText('nodeView.resetZoom')"
|
||||
:shortcut="{ keys: ['0'] }"
|
||||
>
|
||||
<n8n-icon-button
|
||||
|
|
|
@ -399,7 +399,7 @@ async function onDrop(value: string, event: MouseEvent) {
|
|||
:class="$style.tabs"
|
||||
>
|
||||
<el-tab-pane
|
||||
:label="$locale.baseText('codeNodeEditor.tabs.code')"
|
||||
:label="i18n.baseText('codeNodeEditor.tabs.code')"
|
||||
name="code"
|
||||
data-test-id="code-node-tab-code"
|
||||
:class="$style.fillHeight"
|
||||
|
@ -426,7 +426,7 @@ async function onDrop(value: string, event: MouseEvent) {
|
|||
<slot name="suffix" />
|
||||
</el-tab-pane>
|
||||
<el-tab-pane
|
||||
:label="$locale.baseText('codeNodeEditor.tabs.askAi')"
|
||||
:label="i18n.baseText('codeNodeEditor.tabs.askAi')"
|
||||
name="ask-ai"
|
||||
data-test-id="code-node-tab-ai"
|
||||
>
|
||||
|
|
|
@ -1,12 +1,10 @@
|
|||
import type { EditorView } from '@codemirror/view';
|
||||
import type { I18nClass } from '@/plugins/i18n';
|
||||
import type { Workflow, CodeExecutionMode, CodeNodeEditorLanguage } from 'n8n-workflow';
|
||||
import type { Node } from 'estree';
|
||||
import type { DefineComponent } from 'vue';
|
||||
|
||||
export type CodeNodeEditorMixin = InstanceType<
|
||||
DefineComponent & {
|
||||
$locale: I18nClass;
|
||||
editor: EditorView | null;
|
||||
mode: CodeExecutionMode;
|
||||
language: CodeNodeEditorLanguage;
|
||||
|
|
|
@ -164,7 +164,7 @@ function valueChanged(parameterData: IUpdateInformation) {
|
|||
<div class="collection-parameter" @keydown.stop>
|
||||
<div class="collection-parameter-wrapper">
|
||||
<div v-if="getProperties.length === 0" class="no-items-exist">
|
||||
<n8n-text size="small">{{ $locale.baseText('collectionParameter.noProperties') }}</n8n-text>
|
||||
<n8n-text size="small">{{ i18n.baseText('collectionParameter.noProperties') }}</n8n-text>
|
||||
</div>
|
||||
|
||||
<Suspense>
|
||||
|
|
|
@ -36,7 +36,7 @@ const validators = ref<{ [key: string]: IValidator }>({
|
|||
|
||||
if (!VALID_EMAIL_REGEX.test(value)) {
|
||||
return {
|
||||
messageKey: 'settings.users.invalidEmailError',
|
||||
message: 'settings.users.invalidEmailError',
|
||||
options: { interpolate: { email: value } },
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
<script setup lang="ts">
|
||||
import ParameterInputFull from '@/components/ParameterInputFull.vue';
|
||||
import { useI18n } from '@/composables/useI18n';
|
||||
import type { IUpdateInformation, NodeAuthenticationOption } from '@/Interface';
|
||||
import { useNDVStore } from '@/stores/ndv.store';
|
||||
import { useNodeTypesStore } from '@/stores/nodeTypes.store';
|
||||
|
@ -28,6 +29,8 @@ const emit = defineEmits<{
|
|||
const nodeTypesStore = useNodeTypesStore();
|
||||
const ndvStore = useNDVStore();
|
||||
|
||||
const i18n = useI18n();
|
||||
|
||||
const props = defineProps<Props>();
|
||||
|
||||
const selected = ref('');
|
||||
|
@ -133,8 +136,8 @@ defineExpose({
|
|||
</div>
|
||||
<div>
|
||||
<n8n-input-label
|
||||
:label="$locale.baseText('credentialEdit.credentialConfig.authTypeSelectorLabel')"
|
||||
:tooltip-text="$locale.baseText('credentialEdit.credentialConfig.authTypeSelectorTooltip')"
|
||||
:label="i18n.baseText('credentialEdit.credentialConfig.authTypeSelectorLabel')"
|
||||
:tooltip-text="i18n.baseText('credentialEdit.credentialConfig.authTypeSelectorTooltip')"
|
||||
:required="true"
|
||||
/>
|
||||
</div>
|
||||
|
|
|
@ -241,7 +241,7 @@ watch(showOAuthSuccessBanner, (newValue, oldValue) => {
|
|||
v-show="showValidationWarning"
|
||||
theme="danger"
|
||||
:message="
|
||||
$locale.baseText(
|
||||
i18n.baseText(
|
||||
`credentialEdit.credentialConfig.pleaseCheckTheErrorsBelow${
|
||||
credentialPermissions.update ? '' : '.sharee'
|
||||
}`,
|
||||
|
@ -254,7 +254,7 @@ watch(showOAuthSuccessBanner, (newValue, oldValue) => {
|
|||
v-if="authError && !showValidationWarning"
|
||||
theme="danger"
|
||||
:message="
|
||||
$locale.baseText(
|
||||
i18n.baseText(
|
||||
`credentialEdit.credentialConfig.couldntConnectWithTheseSettings${
|
||||
credentialPermissions.update ? '' : '.sharee'
|
||||
}`,
|
||||
|
@ -262,9 +262,9 @@ watch(showOAuthSuccessBanner, (newValue, oldValue) => {
|
|||
)
|
||||
"
|
||||
:details="authError"
|
||||
:button-label="$locale.baseText('credentialEdit.credentialConfig.retry')"
|
||||
:button-label="i18n.baseText('credentialEdit.credentialConfig.retry')"
|
||||
button-loading-label="Retrying"
|
||||
:button-title="$locale.baseText('credentialEdit.credentialConfig.retryCredentialTest')"
|
||||
:button-title="i18n.baseText('credentialEdit.credentialConfig.retryCredentialTest')"
|
||||
:button-loading="isRetesting"
|
||||
@click="$emit('retest')"
|
||||
/>
|
||||
|
@ -272,18 +272,16 @@ watch(showOAuthSuccessBanner, (newValue, oldValue) => {
|
|||
<Banner
|
||||
v-show="showOAuthSuccessBanner && !showValidationWarning"
|
||||
theme="success"
|
||||
:message="$locale.baseText('credentialEdit.credentialConfig.accountConnected')"
|
||||
:button-label="$locale.baseText('credentialEdit.credentialConfig.reconnect')"
|
||||
:button-title="
|
||||
$locale.baseText('credentialEdit.credentialConfig.reconnectOAuth2Credential')
|
||||
"
|
||||
:message="i18n.baseText('credentialEdit.credentialConfig.accountConnected')"
|
||||
:button-label="i18n.baseText('credentialEdit.credentialConfig.reconnect')"
|
||||
:button-title="i18n.baseText('credentialEdit.credentialConfig.reconnectOAuth2Credential')"
|
||||
data-test-id="oauth-connect-success-banner"
|
||||
@click="$emit('oauth')"
|
||||
>
|
||||
<template v-if="isGoogleOAuthType" #button>
|
||||
<p
|
||||
:class="$style.googleReconnectLabel"
|
||||
v-text="`${$locale.baseText('credentialEdit.credentialConfig.reconnect')}:`"
|
||||
v-text="`${i18n.baseText('credentialEdit.credentialConfig.reconnect')}:`"
|
||||
/>
|
||||
<GoogleAuthButton @click="$emit('oauth')" />
|
||||
</template>
|
||||
|
@ -292,10 +290,10 @@ watch(showOAuthSuccessBanner, (newValue, oldValue) => {
|
|||
<Banner
|
||||
v-show="testedSuccessfully && !showValidationWarning"
|
||||
theme="success"
|
||||
:message="$locale.baseText('credentialEdit.credentialConfig.connectionTestedSuccessfully')"
|
||||
:button-label="$locale.baseText('credentialEdit.credentialConfig.retry')"
|
||||
:button-loading-label="$locale.baseText('credentialEdit.credentialConfig.retrying')"
|
||||
:button-title="$locale.baseText('credentialEdit.credentialConfig.retryCredentialTest')"
|
||||
:message="i18n.baseText('credentialEdit.credentialConfig.connectionTestedSuccessfully')"
|
||||
:button-label="i18n.baseText('credentialEdit.credentialConfig.retry')"
|
||||
:button-loading-label="i18n.baseText('credentialEdit.credentialConfig.retrying')"
|
||||
:button-title="i18n.baseText('credentialEdit.credentialConfig.retryCredentialTest')"
|
||||
:button-loading="isRetesting"
|
||||
data-test-id="credentials-config-container-test-success"
|
||||
@click="$emit('retest')"
|
||||
|
@ -306,10 +304,10 @@ watch(showOAuthSuccessBanner, (newValue, oldValue) => {
|
|||
v-if="documentationUrl && credentialProperties.length && !showCredentialDocs"
|
||||
theme="warning"
|
||||
>
|
||||
{{ $locale.baseText('credentialEdit.credentialConfig.needHelpFillingOutTheseFields') }}
|
||||
{{ i18n.baseText('credentialEdit.credentialConfig.needHelpFillingOutTheseFields') }}
|
||||
<span class="ml-4xs">
|
||||
<n8n-link :to="documentationUrl" size="small" bold @click="onDocumentationUrlClick">
|
||||
{{ $locale.baseText('credentialEdit.credentialConfig.openDocs') }}
|
||||
{{ i18n.baseText('credentialEdit.credentialConfig.openDocs') }}
|
||||
</n8n-link>
|
||||
</span>
|
||||
</n8n-notice>
|
||||
|
@ -331,16 +329,16 @@ watch(showOAuthSuccessBanner, (newValue, oldValue) => {
|
|||
|
||||
<CopyInput
|
||||
v-if="isOAuthType && !allOAuth2BasePropertiesOverridden"
|
||||
:label="$locale.baseText('credentialEdit.credentialConfig.oAuthRedirectUrl')"
|
||||
:label="i18n.baseText('credentialEdit.credentialConfig.oAuthRedirectUrl')"
|
||||
:value="oAuthCallbackUrl"
|
||||
:copy-button-text="$locale.baseText('credentialEdit.credentialConfig.clickToCopy')"
|
||||
:copy-button-text="i18n.baseText('credentialEdit.credentialConfig.clickToCopy')"
|
||||
:hint="
|
||||
$locale.baseText('credentialEdit.credentialConfig.subtitle', {
|
||||
i18n.baseText('credentialEdit.credentialConfig.subtitle', {
|
||||
interpolate: { appName },
|
||||
})
|
||||
"
|
||||
:toast-title="
|
||||
$locale.baseText('credentialEdit.credentialConfig.redirectUrlCopiedToClipboard')
|
||||
i18n.baseText('credentialEdit.credentialConfig.redirectUrlCopiedToClipboard')
|
||||
"
|
||||
:redact-value="true"
|
||||
/>
|
||||
|
@ -349,7 +347,7 @@ watch(showOAuthSuccessBanner, (newValue, oldValue) => {
|
|||
<div>
|
||||
<n8n-info-tip :bold="false">
|
||||
{{
|
||||
$locale.baseText('credentialEdit.credentialEdit.info.sharee', {
|
||||
i18n.baseText('credentialEdit.credentialEdit.info.sharee', {
|
||||
interpolate: { credentialOwnerName },
|
||||
})
|
||||
}}
|
||||
|
@ -379,15 +377,15 @@ watch(showOAuthSuccessBanner, (newValue, oldValue) => {
|
|||
/>
|
||||
|
||||
<n8n-text v-if="isMissingCredentials" color="text-base" size="medium">
|
||||
{{ $locale.baseText('credentialEdit.credentialConfig.missingCredentialType') }}
|
||||
{{ i18n.baseText('credentialEdit.credentialConfig.missingCredentialType') }}
|
||||
</n8n-text>
|
||||
|
||||
<EnterpriseEdition :features="[EnterpriseEditionFeature.ExternalSecrets]">
|
||||
<template #fallback>
|
||||
<n8n-info-tip class="mt-s">
|
||||
{{ $locale.baseText('credentialEdit.credentialConfig.externalSecrets') }}
|
||||
<n8n-link bold :to="$locale.baseText('settings.externalSecrets.docs')" size="small">
|
||||
{{ $locale.baseText('credentialEdit.credentialConfig.externalSecrets.moreInfo') }}
|
||||
{{ i18n.baseText('credentialEdit.credentialConfig.externalSecrets') }}
|
||||
<n8n-link bold :to="i18n.baseText('settings.externalSecrets.docs')" size="small">
|
||||
{{ i18n.baseText('credentialEdit.credentialConfig.externalSecrets.moreInfo') }}
|
||||
</n8n-link>
|
||||
</n8n-info-tip>
|
||||
</template>
|
||||
|
|
|
@ -1067,7 +1067,7 @@ function resetCredentialData(): void {
|
|||
<div :class="$style.credActions">
|
||||
<n8n-icon-button
|
||||
v-if="currentCredential && credentialPermissions.delete"
|
||||
:title="$locale.baseText('credentialEdit.credentialEdit.delete')"
|
||||
:title="i18n.baseText('credentialEdit.credentialEdit.delete')"
|
||||
icon="trash"
|
||||
type="tertiary"
|
||||
:disabled="isSaving"
|
||||
|
@ -1081,8 +1081,8 @@ function resetCredentialData(): void {
|
|||
:is-saving="isSaving || isTesting"
|
||||
:saving-label="
|
||||
isTesting
|
||||
? $locale.baseText('credentialEdit.credentialEdit.testing')
|
||||
: $locale.baseText('credentialEdit.credentialEdit.saving')
|
||||
? i18n.baseText('credentialEdit.credentialEdit.testing')
|
||||
: i18n.baseText('credentialEdit.credentialEdit.saving')
|
||||
"
|
||||
data-test-id="credential-save-button"
|
||||
@click="saveCredential"
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
<script lang="ts" setup>
|
||||
import { useUIStore } from '@/stores/ui.store';
|
||||
import { useRootStore } from '@/stores/root.store';
|
||||
import { useI18n } from '@/composables/useI18n';
|
||||
|
||||
const { baseUrl } = useRootStore();
|
||||
const type = useUIStore().appliedTheme === 'dark' ? '.dark.png' : '.png';
|
||||
const i18n = useI18n();
|
||||
const googleAuthButtons = {
|
||||
'--google-auth-btn-normal': `url(${baseUrl}static/google-auth/normal${type}`,
|
||||
'--google-auth-btn-focus': `url(${baseUrl}static/google-auth/focus${type}`,
|
||||
|
@ -15,7 +17,7 @@ const googleAuthButtons = {
|
|||
<template>
|
||||
<button
|
||||
:class="$style.googleAuthBtn"
|
||||
:title="$locale.baseText('credentialEdit.oAuthButton.signInWithGoogle')"
|
||||
:title="i18n.baseText('credentialEdit.oAuthButton.signInWithGoogle')"
|
||||
:style="googleAuthButtons"
|
||||
/>
|
||||
</template>
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
<script lang="ts" setup>
|
||||
import { useI18n } from '@/composables/useI18n';
|
||||
import GoogleAuthButton from './GoogleAuthButton.vue';
|
||||
|
||||
defineProps<{
|
||||
isGoogleOAuthType: boolean;
|
||||
}>();
|
||||
const i18n = useI18n();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
@ -11,7 +13,7 @@ defineProps<{
|
|||
<GoogleAuthButton v-if="isGoogleOAuthType" />
|
||||
<n8n-button
|
||||
v-else
|
||||
:label="$locale.baseText('credentialEdit.oAuthButton.connectMyAccount')"
|
||||
:label="i18n.baseText('credentialEdit.oAuthButton.connectMyAccount')"
|
||||
size="large"
|
||||
/>
|
||||
</div>
|
||||
|
|
|
@ -6,6 +6,7 @@ import NodeCredentials from '@/components/NodeCredentials.vue';
|
|||
import { useCredentialsStore } from '@/stores/credentials.store';
|
||||
import { N8nOption, N8nSelect } from 'n8n-design-system';
|
||||
import type { INodeUi, INodeUpdatePropertiesInformation } from '@/Interface';
|
||||
import { useI18n } from '@/composables/useI18n';
|
||||
|
||||
type Props = {
|
||||
activeCredentialType: string;
|
||||
|
@ -28,6 +29,8 @@ const emit = defineEmits<{
|
|||
|
||||
const credentialsStore = useCredentialsStore();
|
||||
|
||||
const i18n = useI18n();
|
||||
|
||||
const innerSelectRef = ref<HTMLSelectElement>();
|
||||
|
||||
const allCredentialTypes = computed(() => credentialsStore.allCredentialTypes);
|
||||
|
@ -119,7 +122,7 @@ defineExpose({ focus });
|
|||
:size="inputSize"
|
||||
filterable
|
||||
:model-value="displayValue"
|
||||
:placeholder="$locale.baseText('parameterInput.select')"
|
||||
:placeholder="i18n.baseText('parameterInput.select')"
|
||||
:title="displayTitle"
|
||||
:disabled="isReadOnly"
|
||||
data-test-id="credential-select"
|
||||
|
|
|
@ -9,9 +9,11 @@ import { createEventBus } from 'n8n-design-system/utils';
|
|||
import { onMounted, ref } from 'vue';
|
||||
import { CREDENTIAL_SELECT_MODAL_KEY } from '../constants';
|
||||
import Modal from './Modal.vue';
|
||||
import { useI18n } from '@/composables/useI18n';
|
||||
|
||||
const externalHooks = useExternalHooks();
|
||||
const telemetry = useTelemetry();
|
||||
const i18n = useI18n();
|
||||
|
||||
const modalBus = ref(createEventBus());
|
||||
const selected = ref('');
|
||||
|
@ -68,19 +70,19 @@ function openCredentialType() {
|
|||
>
|
||||
<template #header>
|
||||
<h2 :class="$style.title">
|
||||
{{ $locale.baseText('credentialSelectModal.addNewCredential') }}
|
||||
{{ i18n.baseText('credentialSelectModal.addNewCredential') }}
|
||||
</h2>
|
||||
</template>
|
||||
<template #content>
|
||||
<div>
|
||||
<div :class="$style.subtitle">
|
||||
{{ $locale.baseText('credentialSelectModal.selectAnAppOrServiceToConnectTo') }}
|
||||
{{ i18n.baseText('credentialSelectModal.selectAnAppOrServiceToConnectTo') }}
|
||||
</div>
|
||||
<N8nSelect
|
||||
ref="selectRef"
|
||||
filterable
|
||||
default-first-option
|
||||
:placeholder="$locale.baseText('credentialSelectModal.searchForApp')"
|
||||
:placeholder="i18n.baseText('credentialSelectModal.searchForApp')"
|
||||
size="xlarge"
|
||||
:model-value="selected"
|
||||
data-test-id="new-credential-type-select"
|
||||
|
@ -103,7 +105,7 @@ function openCredentialType() {
|
|||
<template #footer>
|
||||
<div :class="$style.footer">
|
||||
<N8nButton
|
||||
:label="$locale.baseText('credentialSelectModal.continue')"
|
||||
:label="i18n.baseText('credentialSelectModal.continue')"
|
||||
float="right"
|
||||
size="large"
|
||||
:disabled="!selected"
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
<script setup lang="ts">
|
||||
import { useRouter } from 'vue-router';
|
||||
import { VIEWS } from '@/constants';
|
||||
import { useI18n } from '@/composables/useI18n';
|
||||
|
||||
const router = useRouter();
|
||||
const i18n = useI18n();
|
||||
|
||||
const navigateTo = () => {
|
||||
void router.push({ name: VIEWS.TEMPLATES });
|
||||
|
@ -12,7 +14,7 @@ const navigateTo = () => {
|
|||
<template>
|
||||
<div :class="$style.wrapper" @click="navigateTo">
|
||||
<font-awesome-icon :class="$style.icon" icon="arrow-left" />
|
||||
<div :class="$style.text" v-text="$locale.baseText('template.buttons.goBackButton')" />
|
||||
<div :class="$style.text" v-text="i18n.baseText('template.buttons.goBackButton')" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<script lang="ts" setup>
|
||||
import { useI18n } from '@/composables/useI18n';
|
||||
import { IMPORT_CURL_MODAL_KEY } from '@/constants';
|
||||
import { useUIStore } from '@/stores/ui.store';
|
||||
|
||||
|
@ -7,6 +8,7 @@ defineProps<{
|
|||
}>();
|
||||
|
||||
const uiStore = useUIStore();
|
||||
const i18n = useI18n();
|
||||
|
||||
function onImportCurlClicked() {
|
||||
uiStore.openModal(IMPORT_CURL_MODAL_KEY);
|
||||
|
@ -17,7 +19,7 @@ function onImportCurlClicked() {
|
|||
<div :class="$style.importSection">
|
||||
<n8n-button
|
||||
type="secondary"
|
||||
:label="$locale.baseText('importCurlParameter.label')"
|
||||
:label="i18n.baseText('importCurlParameter.label')"
|
||||
:disabled="isReadOnly"
|
||||
size="mini"
|
||||
@click="onImportCurlClicked"
|
||||
|
|
|
@ -340,10 +340,10 @@ function activatePane() {
|
|||
:run-index="isMappingMode ? 0 : runIndex"
|
||||
:linked-runs="linkedRuns"
|
||||
:can-link-runs="!mappedNode && canLinkRuns"
|
||||
:too-much-data-title="$locale.baseText('ndv.input.tooMuchData.title')"
|
||||
:no-data-in-branch-message="$locale.baseText('ndv.input.noOutputDataInBranch')"
|
||||
:too-much-data-title="i18n.baseText('ndv.input.tooMuchData.title')"
|
||||
:no-data-in-branch-message="i18n.baseText('ndv.input.noOutputDataInBranch')"
|
||||
:is-executing="isExecutingPrevious"
|
||||
:executing-message="$locale.baseText('ndv.input.executingPrevious')"
|
||||
:executing-message="i18n.baseText('ndv.input.executingPrevious')"
|
||||
:push-ref="pushRef"
|
||||
:override-outputs="connectedCurrentNodeOutputs"
|
||||
:mapping-enabled="isMappingEnabled"
|
||||
|
@ -362,7 +362,7 @@ function activatePane() {
|
|||
>
|
||||
<template #header>
|
||||
<div :class="$style.titleSection">
|
||||
<span :class="$style.title">{{ $locale.baseText('ndv.input') }}</span>
|
||||
<span :class="$style.title">{{ i18n.baseText('ndv.input') }}</span>
|
||||
<N8nRadioButtons
|
||||
v-if="isActiveNodeConfig && !readOnly"
|
||||
data-test-id="input-panel-mode"
|
||||
|
@ -402,13 +402,13 @@ function activatePane() {
|
|||
:class="$style.noOutputData"
|
||||
>
|
||||
<N8nText tag="div" :bold="true" color="text-dark" size="large">{{
|
||||
$locale.baseText('ndv.input.noOutputData.title')
|
||||
i18n.baseText('ndv.input.noOutputData.title')
|
||||
}}</N8nText>
|
||||
<N8nTooltip v-if="!readOnly" :visible="showDraggableHint && showDraggableHintWithDelay">
|
||||
<template #content>
|
||||
<div
|
||||
v-n8n-html="
|
||||
$locale.baseText('dataMapping.dragFromPreviousHint', {
|
||||
i18n.baseText('dataMapping.dragFromPreviousHint', {
|
||||
interpolate: { name: focusedMappableInput },
|
||||
})
|
||||
"
|
||||
|
@ -419,14 +419,14 @@ function activatePane() {
|
|||
hide-icon
|
||||
:transparent="true"
|
||||
:node-name="(isActiveNodeConfig ? rootNode : currentNodeName) ?? ''"
|
||||
:label="$locale.baseText('ndv.input.noOutputData.executePrevious')"
|
||||
:label="i18n.baseText('ndv.input.noOutputData.executePrevious')"
|
||||
telemetry-source="inputs"
|
||||
data-test-id="execute-previous-node"
|
||||
@execute="onNodeExecute"
|
||||
/>
|
||||
</N8nTooltip>
|
||||
<N8nText v-if="!readOnly" tag="div" size="small">
|
||||
{{ $locale.baseText('ndv.input.noOutputData.hint') }}
|
||||
{{ i18n.baseText('ndv.input.noOutputData.hint') }}
|
||||
</N8nText>
|
||||
</div>
|
||||
<div v-else :class="$style.notConnected">
|
||||
|
@ -434,16 +434,16 @@ function activatePane() {
|
|||
<WireMeUp />
|
||||
</div>
|
||||
<N8nText tag="div" :bold="true" color="text-dark" size="large">{{
|
||||
$locale.baseText('ndv.input.notConnected.title')
|
||||
i18n.baseText('ndv.input.notConnected.title')
|
||||
}}</N8nText>
|
||||
<N8nText tag="div">
|
||||
{{ $locale.baseText('ndv.input.notConnected.message') }}
|
||||
{{ i18n.baseText('ndv.input.notConnected.message') }}
|
||||
<a
|
||||
href="https://docs.n8n.io/workflows/connections/"
|
||||
target="_blank"
|
||||
@click="onConnectionHelpClick"
|
||||
>
|
||||
{{ $locale.baseText('ndv.input.notConnected.learnMore') }}
|
||||
{{ i18n.baseText('ndv.input.notConnected.learnMore') }}
|
||||
</a>
|
||||
</N8nText>
|
||||
</div>
|
||||
|
@ -456,17 +456,17 @@ function activatePane() {
|
|||
|
||||
<template #no-output-data>
|
||||
<N8nText tag="div" :bold="true" color="text-dark" size="large">{{
|
||||
$locale.baseText('ndv.input.noOutputData')
|
||||
i18n.baseText('ndv.input.noOutputData')
|
||||
}}</N8nText>
|
||||
</template>
|
||||
|
||||
<template #recovered-artificial-output-data>
|
||||
<div :class="$style.recoveredOutputData">
|
||||
<N8nText tag="div" :bold="true" color="text-dark" size="large">{{
|
||||
$locale.baseText('executionDetails.executionFailed.recoveredNodeTitle')
|
||||
i18n.baseText('executionDetails.executionFailed.recoveredNodeTitle')
|
||||
}}</N8nText>
|
||||
<N8nText>
|
||||
{{ $locale.baseText('executionDetails.executionFailed.recoveredNodeMessage') }}
|
||||
{{ i18n.baseText('executionDetails.executionFailed.recoveredNodeMessage') }}
|
||||
</N8nText>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
@ -80,6 +80,7 @@ const usersStore = useUsersStore();
|
|||
const workflowsStore = useWorkflowsStore();
|
||||
const projectsStore = useProjectsStore();
|
||||
const npsSurveyStore = useNpsSurveyStore();
|
||||
const i18n = useI18n();
|
||||
|
||||
const router = useRouter();
|
||||
const route = useRoute();
|
||||
|
@ -644,7 +645,7 @@ function showCreateWorkflowSuccessToast(id?: string) {
|
|||
ref="dropdown"
|
||||
v-model="appliedTagIds"
|
||||
:event-bus="tagsEventBus"
|
||||
:placeholder="$locale.baseText('workflowDetails.chooseOrCreateATag')"
|
||||
:placeholder="i18n.baseText('workflowDetails.chooseOrCreateATag')"
|
||||
class="tags-edit"
|
||||
data-test-id="workflow-tags-dropdown"
|
||||
@blur="onTagsBlur"
|
||||
|
@ -656,7 +657,7 @@ function showCreateWorkflowSuccessToast(id?: string) {
|
|||
"
|
||||
>
|
||||
<span class="add-tag clickable" data-test-id="new-tag-link" @click="onTagsEditEnable">
|
||||
+ {{ $locale.baseText('workflowDetails.addTag') }}
|
||||
+ {{ i18n.baseText('workflowDetails.addTag') }}
|
||||
</span>
|
||||
</div>
|
||||
<WorkflowTagsContainer
|
||||
|
@ -687,13 +688,13 @@ function showCreateWorkflowSuccessToast(id?: string) {
|
|||
data-test-id="workflow-share-button"
|
||||
@click="onShareButtonClick"
|
||||
>
|
||||
{{ $locale.baseText('workflowDetails.share') }}
|
||||
{{ i18n.baseText('workflowDetails.share') }}
|
||||
</N8nButton>
|
||||
</div>
|
||||
<template #fallback>
|
||||
<N8nTooltip>
|
||||
<N8nButton type="secondary" :class="['mr-2xs', $style.disabledShareButton]">
|
||||
{{ $locale.baseText('workflowDetails.share') }}
|
||||
{{ i18n.baseText('workflowDetails.share') }}
|
||||
</N8nButton>
|
||||
<template #content>
|
||||
<i18n-t
|
||||
|
@ -706,7 +707,7 @@ function showCreateWorkflowSuccessToast(id?: string) {
|
|||
<template #action>
|
||||
<a @click="goToUpgrade">
|
||||
{{
|
||||
$locale.baseText(
|
||||
i18n.baseText(
|
||||
uiStore.contextBasedTranslationKeys.workflows.sharing.unavailable
|
||||
.button as BaseTextKey,
|
||||
)
|
||||
|
@ -727,7 +728,7 @@ function showCreateWorkflowSuccessToast(id?: string) {
|
|||
"
|
||||
:is-saving="isWorkflowSaving"
|
||||
:with-shortcut="!readOnly && workflowPermissions.update"
|
||||
:shortcut-tooltip="$locale.baseText('saveWorkflowButton.hint')"
|
||||
:shortcut-tooltip="i18n.baseText('saveWorkflowButton.hint')"
|
||||
data-test-id="workflow-save-button"
|
||||
@click="onSaveButtonClick"
|
||||
/>
|
||||
|
@ -755,9 +756,9 @@ function showCreateWorkflowSuccessToast(id?: string) {
|
|||
/>
|
||||
<template #content>
|
||||
<div class="mb-4xs">
|
||||
<N8nBadge>{{ $locale.baseText('menuActions.badge.alpha') }}</N8nBadge>
|
||||
<N8nBadge>{{ i18n.baseText('menuActions.badge.alpha') }}</N8nBadge>
|
||||
</div>
|
||||
{{ $locale.baseText('menuActions.nodeViewDiscovery.tooltip') }}
|
||||
{{ i18n.baseText('menuActions.nodeViewDiscovery.tooltip') }}
|
||||
<N8nIcon
|
||||
:class="$style.closeNodeViewDiscovery"
|
||||
icon="times-circle"
|
||||
|
|
|
@ -35,7 +35,7 @@ const workflowsStore = useWorkflowsStore();
|
|||
|
||||
const { callDebounced } = useDebounce();
|
||||
const externalHooks = useExternalHooks();
|
||||
const locale = useI18n();
|
||||
const i18n = useI18n();
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
const telemetry = useTelemetry();
|
||||
|
@ -53,11 +53,11 @@ const fullyExpanded = ref(false);
|
|||
const userMenuItems = ref([
|
||||
{
|
||||
id: 'settings',
|
||||
label: locale.baseText('settings'),
|
||||
label: i18n.baseText('settings'),
|
||||
},
|
||||
{
|
||||
id: 'logout',
|
||||
label: locale.baseText('auth.signout'),
|
||||
label: i18n.baseText('auth.signout'),
|
||||
},
|
||||
]);
|
||||
|
||||
|
@ -73,7 +73,7 @@ const mainMenuItems = computed(() => [
|
|||
// Link to in-app templates, available if custom templates are enabled
|
||||
id: 'templates',
|
||||
icon: 'box-open',
|
||||
label: locale.baseText('mainSidebar.templates'),
|
||||
label: i18n.baseText('mainSidebar.templates'),
|
||||
position: 'bottom',
|
||||
available: settingsStore.isTemplatesEnabled && templatesStore.hasCustomTemplatesHost,
|
||||
route: { to: { name: VIEWS.TEMPLATES } },
|
||||
|
@ -82,7 +82,7 @@ const mainMenuItems = computed(() => [
|
|||
// Link to website templates, available if custom templates are not enabled
|
||||
id: 'templates',
|
||||
icon: 'box-open',
|
||||
label: locale.baseText('mainSidebar.templates'),
|
||||
label: i18n.baseText('mainSidebar.templates'),
|
||||
position: 'bottom',
|
||||
available: settingsStore.isTemplatesEnabled && !templatesStore.hasCustomTemplatesHost,
|
||||
link: {
|
||||
|
@ -93,7 +93,7 @@ const mainMenuItems = computed(() => [
|
|||
{
|
||||
id: 'variables',
|
||||
icon: 'variable',
|
||||
label: locale.baseText('mainSidebar.variables'),
|
||||
label: i18n.baseText('mainSidebar.variables'),
|
||||
customIconSize: 'medium',
|
||||
position: 'bottom',
|
||||
route: { to: { name: VIEWS.VARIABLES } },
|
||||
|
@ -101,13 +101,13 @@ const mainMenuItems = computed(() => [
|
|||
{
|
||||
id: 'help',
|
||||
icon: 'question',
|
||||
label: locale.baseText('mainSidebar.help'),
|
||||
label: i18n.baseText('mainSidebar.help'),
|
||||
position: 'bottom',
|
||||
children: [
|
||||
{
|
||||
id: 'quickstart',
|
||||
icon: 'video',
|
||||
label: locale.baseText('mainSidebar.helpMenuItems.quickstart'),
|
||||
label: i18n.baseText('mainSidebar.helpMenuItems.quickstart'),
|
||||
link: {
|
||||
href: 'https://www.youtube.com/watch?v=1MwSoB0gnM4',
|
||||
target: '_blank',
|
||||
|
@ -116,7 +116,7 @@ const mainMenuItems = computed(() => [
|
|||
{
|
||||
id: 'docs',
|
||||
icon: 'book',
|
||||
label: locale.baseText('mainSidebar.helpMenuItems.documentation'),
|
||||
label: i18n.baseText('mainSidebar.helpMenuItems.documentation'),
|
||||
link: {
|
||||
href: 'https://docs.n8n.io?utm_source=n8n_app&utm_medium=app_sidebar',
|
||||
target: '_blank',
|
||||
|
@ -125,7 +125,7 @@ const mainMenuItems = computed(() => [
|
|||
{
|
||||
id: 'forum',
|
||||
icon: 'users',
|
||||
label: locale.baseText('mainSidebar.helpMenuItems.forum'),
|
||||
label: i18n.baseText('mainSidebar.helpMenuItems.forum'),
|
||||
link: {
|
||||
href: 'https://community.n8n.io?utm_source=n8n_app&utm_medium=app_sidebar',
|
||||
target: '_blank',
|
||||
|
@ -134,7 +134,7 @@ const mainMenuItems = computed(() => [
|
|||
{
|
||||
id: 'examples',
|
||||
icon: 'graduation-cap',
|
||||
label: locale.baseText('mainSidebar.helpMenuItems.course'),
|
||||
label: i18n.baseText('mainSidebar.helpMenuItems.course'),
|
||||
link: {
|
||||
href: 'https://docs.n8n.io/courses/',
|
||||
target: '_blank',
|
||||
|
@ -143,7 +143,7 @@ const mainMenuItems = computed(() => [
|
|||
{
|
||||
id: 'report-bug',
|
||||
icon: 'bug',
|
||||
label: locale.baseText('mainSidebar.helpMenuItems.reportBug'),
|
||||
label: i18n.baseText('mainSidebar.helpMenuItems.reportBug'),
|
||||
link: {
|
||||
href: getReportingURL(),
|
||||
target: '_blank',
|
||||
|
@ -152,7 +152,7 @@ const mainMenuItems = computed(() => [
|
|||
{
|
||||
id: 'about',
|
||||
icon: 'info',
|
||||
label: locale.baseText('mainSidebar.aboutN8n'),
|
||||
label: i18n.baseText('mainSidebar.aboutN8n'),
|
||||
position: 'bottom',
|
||||
},
|
||||
],
|
||||
|
@ -357,10 +357,10 @@ const checkWidthAndAdjustSidebar = async (width: number) => {
|
|||
<template v-if="isCollapsed" #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item command="settings">
|
||||
{{ $locale.baseText('settings') }}
|
||||
{{ i18n.baseText('settings') }}
|
||||
</el-dropdown-item>
|
||||
<el-dropdown-item command="logout">
|
||||
{{ $locale.baseText('auth.signout') }}
|
||||
{{ i18n.baseText('auth.signout') }}
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
|
|
|
@ -39,7 +39,7 @@ const loadingQrCode = ref(true);
|
|||
|
||||
const clipboard = useClipboard();
|
||||
const userStore = useUsersStore();
|
||||
const i18 = useI18n();
|
||||
const i18n = useI18n();
|
||||
const toast = useToast();
|
||||
|
||||
// #endregion
|
||||
|
@ -64,15 +64,15 @@ const onInput = (value: string) => {
|
|||
authenticatorCode.value = value;
|
||||
})
|
||||
.catch(() => {
|
||||
infoTextErrorMessage.value = i18.baseText('mfa.setup.invalidCode');
|
||||
infoTextErrorMessage.value = i18n.baseText('mfa.setup.invalidCode');
|
||||
});
|
||||
};
|
||||
|
||||
const onCopySecretToClipboard = () => {
|
||||
void clipboard.copy(secret.value);
|
||||
toast.showToast({
|
||||
title: i18.baseText('mfa.setup.step1.toast.copyToClipboard.title'),
|
||||
message: i18.baseText('mfa.setup.step1.toast.copyToClipboard.message'),
|
||||
title: i18n.baseText('mfa.setup.step1.toast.copyToClipboard.title'),
|
||||
message: i18n.baseText('mfa.setup.step1.toast.copyToClipboard.message'),
|
||||
type: 'success',
|
||||
});
|
||||
};
|
||||
|
@ -102,20 +102,20 @@ const onSetupClick = async () => {
|
|||
closeDialog();
|
||||
toast.showMessage({
|
||||
type: 'success',
|
||||
title: i18.baseText('mfa.setup.step2.toast.setupFinished.message'),
|
||||
title: i18n.baseText('mfa.setup.step2.toast.setupFinished.message'),
|
||||
});
|
||||
} catch (e) {
|
||||
if (e.errorCode === MFA_AUTHENTICATION_TOKEN_WINDOW_EXPIRED) {
|
||||
toast.showMessage({
|
||||
type: 'error',
|
||||
title: i18.baseText('mfa.setup.step2.toast.tokenExpired.error.message'),
|
||||
title: i18n.baseText('mfa.setup.step2.toast.tokenExpired.error.message'),
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
toast.showMessage({
|
||||
type: 'error',
|
||||
title: i18.baseText('mfa.setup.step2.toast.setupFinished.error.message'),
|
||||
title: i18n.baseText('mfa.setup.step2.toast.setupFinished.error.message'),
|
||||
});
|
||||
}
|
||||
};
|
||||
|
@ -127,7 +127,7 @@ const getMfaQR = async () => {
|
|||
secret.value = response.secret;
|
||||
recoveryCodes.value = response.recoveryCodes;
|
||||
} catch (error) {
|
||||
toast.showError(error, i18.baseText('settings.api.view.error'));
|
||||
toast.showError(error, i18n.baseText('settings.api.view.error'));
|
||||
} finally {
|
||||
loadingQrCode.value = false;
|
||||
}
|
||||
|
@ -153,8 +153,8 @@ onMounted(async () => {
|
|||
max-height="640px"
|
||||
:title="
|
||||
!showRecoveryCodes
|
||||
? i18.baseText('mfa.setup.step1.title')
|
||||
: i18.baseText('mfa.setup.step2.title')
|
||||
? i18n.baseText('mfa.setup.step1.title')
|
||||
: i18n.baseText('mfa.setup.step2.title')
|
||||
"
|
||||
:event-bus="modalBus"
|
||||
:name="MFA_SETUP_MODAL_KEY_NAME"
|
||||
|
@ -165,21 +165,21 @@ onMounted(async () => {
|
|||
<div v-if="!showRecoveryCodes" :class="[$style.container, $style.modalContent]">
|
||||
<div :class="$style.textContainer">
|
||||
<n8n-text size="large" color="text-dark" :bold="true">{{
|
||||
i18.baseText('mfa.setup.step1.instruction1.title')
|
||||
i18n.baseText('mfa.setup.step1.instruction1.title')
|
||||
}}</n8n-text>
|
||||
</div>
|
||||
<div>
|
||||
<n8n-text size="medium" :bold="false">
|
||||
<i18n-t keypath="mfa.setup.step1.instruction1.subtitle" tag="span">
|
||||
<template #part1>
|
||||
{{ i18.baseText('mfa.setup.step1.instruction1.subtitle.part1') }}
|
||||
{{ i18n.baseText('mfa.setup.step1.instruction1.subtitle.part1') }}
|
||||
</template>
|
||||
<template #part2>
|
||||
<a
|
||||
:class="$style.secret"
|
||||
data-test-id="mfa-secret-button"
|
||||
@click="onCopySecretToClipboard"
|
||||
>{{ i18.baseText('mfa.setup.step1.instruction1.subtitle.part2') }}</a
|
||||
>{{ i18n.baseText('mfa.setup.step1.instruction1.subtitle.part2') }}</a
|
||||
>
|
||||
</template>
|
||||
</i18n-t>
|
||||
|
@ -190,7 +190,7 @@ onMounted(async () => {
|
|||
</div>
|
||||
<div :class="$style.textContainer">
|
||||
<n8n-text size="large" color="text-dark" :bold="true">{{
|
||||
i18.baseText('mfa.setup.step1.instruction2.title')
|
||||
i18n.baseText('mfa.setup.step1.instruction2.title')
|
||||
}}</n8n-text>
|
||||
</div>
|
||||
<div :class="[$style.form, infoTextErrorMessage ? $style.error : '']">
|
||||
|
@ -198,13 +198,13 @@ onMounted(async () => {
|
|||
size="medium"
|
||||
:bold="false"
|
||||
:class="$style.labelTooltip"
|
||||
:label="i18.baseText('mfa.setup.step1.input.label')"
|
||||
:label="i18n.baseText('mfa.setup.step1.input.label')"
|
||||
>
|
||||
<n8n-input
|
||||
v-model="authenticatorCode"
|
||||
type="text"
|
||||
:maxlength="6"
|
||||
:placeholder="$locale.baseText('mfa.code.input.placeholder')"
|
||||
:placeholder="i18n.baseText('mfa.code.input.placeholder')"
|
||||
:required="true"
|
||||
data-test-id="mfa-token-input"
|
||||
@input="onInput"
|
||||
|
@ -218,7 +218,7 @@ onMounted(async () => {
|
|||
<div v-else :class="$style.container">
|
||||
<div>
|
||||
<n8n-text size="medium" :bold="false">{{
|
||||
i18.baseText('mfa.setup.step2.description')
|
||||
i18n.baseText('mfa.setup.step2.description')
|
||||
}}</n8n-text>
|
||||
</div>
|
||||
<div :class="$style.recoveryCodesContainer">
|
||||
|
@ -227,23 +227,23 @@ onMounted(async () => {
|
|||
</div>
|
||||
</div>
|
||||
<n8n-info-tip :bold="false" :class="$style['edit-mode-footer-infotip']">
|
||||
<i18n-t keypath="mfa.setup.step2.infobox.description" tag="span">
|
||||
<i18nn-t keypath="mfa.setup.step2.infobox.description" tag="span">
|
||||
<template #part1>
|
||||
{{ i18.baseText('mfa.setup.step2.infobox.description.part1') }}
|
||||
{{ i18n.baseText('mfa.setup.step2.infobox.description.part1') }}
|
||||
</template>
|
||||
<template #part2>
|
||||
<n8n-text size="small" :bold="true" :class="$style.loseAccessText">
|
||||
{{ i18.baseText('mfa.setup.step2.infobox.description.part2') }}
|
||||
{{ i18n.baseText('mfa.setup.step2.infobox.description.part2') }}
|
||||
</n8n-text>
|
||||
</template>
|
||||
</i18n-t>
|
||||
</i18nn-t>
|
||||
</n8n-info-tip>
|
||||
<div>
|
||||
<n8n-button
|
||||
type="primary"
|
||||
icon="download"
|
||||
float="right"
|
||||
:label="i18.baseText('mfa.setup.step2.button.download')"
|
||||
:label="i18n.baseText('mfa.setup.step2.button.download')"
|
||||
data-test-id="mfa-recovery-codes-button"
|
||||
@click="onDownloadClick"
|
||||
/>
|
||||
|
@ -256,7 +256,7 @@ onMounted(async () => {
|
|||
<n8n-button
|
||||
float="right"
|
||||
:disabled="!recoveryCodesDownloaded"
|
||||
:label="i18.baseText('mfa.setup.step2.button.save')"
|
||||
:label="i18n.baseText('mfa.setup.step2.button.save')"
|
||||
size="large"
|
||||
data-test-id="mfa-save-button"
|
||||
@click="onSetupClick"
|
||||
|
@ -267,7 +267,7 @@ onMounted(async () => {
|
|||
<div>
|
||||
<n8n-button
|
||||
float="right"
|
||||
:label="i18.baseText('mfa.setup.step1.button.continue')"
|
||||
:label="i18n.baseText('mfa.setup.step1.button.continue')"
|
||||
size="large"
|
||||
:disabled="!readyToSubmit"
|
||||
@click="onSaveClick"
|
||||
|
|
|
@ -14,6 +14,7 @@ import type {
|
|||
} from 'n8n-workflow';
|
||||
import { useDebounce } from '@/composables/useDebounce';
|
||||
import { OnClickOutside } from '@vueuse/components';
|
||||
import { useI18n } from '@/composables/useI18n';
|
||||
|
||||
interface Props {
|
||||
rootNode: INodeUi;
|
||||
|
@ -23,6 +24,7 @@ const props = defineProps<Props>();
|
|||
const workflowsStore = useWorkflowsStore();
|
||||
const nodeTypesStore = useNodeTypesStore();
|
||||
const nodeHelpers = useNodeHelpers();
|
||||
const i18n = useI18n();
|
||||
const { debounce } = useDebounce();
|
||||
const emit = defineEmits<{
|
||||
switchSelectedNode: [nodeName: string];
|
||||
|
@ -245,7 +247,7 @@ defineExpose({
|
|||
Add {{ connection.displayName }}
|
||||
<template v-if="hasInputIssues(connection.type)">
|
||||
<TitledList
|
||||
:title="`${$locale.baseText('node.issues')}:`"
|
||||
:title="`${i18n.baseText('node.issues')}:`"
|
||||
:items="nodeInputIssues[connection.type]"
|
||||
/>
|
||||
</template>
|
||||
|
@ -285,7 +287,7 @@ defineExpose({
|
|||
{{ node.node.name }}
|
||||
<template v-if="node.issues">
|
||||
<TitledList
|
||||
:title="`${$locale.baseText('node.issues')}:`"
|
||||
:title="`${i18n.baseText('node.issues')}:`"
|
||||
:items="node.issues"
|
||||
/>
|
||||
</template>
|
||||
|
|
|
@ -13,6 +13,7 @@ import type { AddedNodesAndConnections, ToggleNodeCreatorOptions } from '@/Inter
|
|||
import { useActions } from './NodeCreator/composables/useActions';
|
||||
import { useThrottleFn } from '@vueuse/core';
|
||||
import KeyboardShortcutTooltip from '@/components/KeyboardShortcutTooltip.vue';
|
||||
import { useI18n } from '@/composables/useI18n';
|
||||
|
||||
type Props = {
|
||||
nodeViewScale: number;
|
||||
|
@ -34,6 +35,7 @@ const emit = defineEmits<{
|
|||
}>();
|
||||
|
||||
const uiStore = useUIStore();
|
||||
const i18n = useI18n();
|
||||
|
||||
const { getAddedNodesAndConnections } = useActions();
|
||||
|
||||
|
@ -101,7 +103,7 @@ onBeforeUnmount(() => {
|
|||
<div v-if="!createNodeActive" :class="$style.nodeButtonsWrapper">
|
||||
<div :class="$style.nodeCreatorButton" ref="wrapperRef" data-test-id="node-creator-plus-button">
|
||||
<KeyboardShortcutTooltip
|
||||
:label="$locale.baseText('nodeView.openNodesPanel')"
|
||||
:label="i18n.baseText('nodeView.openNodesPanel')"
|
||||
:shortcut="{ keys: ['Tab'] }"
|
||||
placement="left"
|
||||
>
|
||||
|
@ -119,7 +121,7 @@ onBeforeUnmount(() => {
|
|||
@click="addStickyNote"
|
||||
>
|
||||
<KeyboardShortcutTooltip
|
||||
:label="$locale.baseText('nodeView.addStickyHint')"
|
||||
:label="i18n.baseText('nodeView.addStickyHint')"
|
||||
:shortcut="{ keys: ['s'], shiftKey: true }"
|
||||
placement="left"
|
||||
>
|
||||
|
|
|
@ -245,7 +245,7 @@ registerKeyHook('MainViewArrowLeft', {
|
|||
<CategorizedItemsRenderer
|
||||
v-if="globalSearchItemsDiff.length > 0"
|
||||
:elements="globalSearchItemsDiff"
|
||||
:category="$locale.baseText('nodeCreator.categoryNames.otherCategories')"
|
||||
:category="i18n.baseText('nodeCreator.categoryNames.otherCategories')"
|
||||
@selected="onSelected"
|
||||
>
|
||||
</CategorizedItemsRenderer>
|
||||
|
|
|
@ -7,6 +7,7 @@ import {
|
|||
import type { NodeFilterType } from '@/Interface';
|
||||
|
||||
import NoResultsIcon from './NoResultsIcon.vue';
|
||||
import { useI18n } from '@/composables/useI18n';
|
||||
|
||||
export interface Props {
|
||||
showIcon?: boolean;
|
||||
|
@ -15,6 +16,7 @@ export interface Props {
|
|||
}
|
||||
|
||||
defineProps<Props>();
|
||||
const i18n = useI18n();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
@ -27,34 +29,34 @@ defineProps<Props>();
|
|||
</div>
|
||||
<div :class="$style.title">
|
||||
<slot name="title" />
|
||||
<p v-text="$locale.baseText('nodeCreator.noResults.weDidntMakeThatYet')" />
|
||||
<p v-text="i18n.baseText('nodeCreator.noResults.weDidntMakeThatYet')" />
|
||||
<div
|
||||
v-if="rootView === REGULAR_NODE_CREATOR_VIEW || rootView === TRIGGER_NODE_CREATOR_VIEW"
|
||||
:class="$style.action"
|
||||
>
|
||||
{{ $locale.baseText('nodeCreator.noResults.dontWorryYouCanProbablyDoItWithThe') }}
|
||||
{{ i18n.baseText('nodeCreator.noResults.dontWorryYouCanProbablyDoItWithThe') }}
|
||||
<n8n-link v-if="rootView === REGULAR_NODE_CREATOR_VIEW" @click="$emit('addHttpNode')">
|
||||
{{ $locale.baseText('nodeCreator.noResults.httpRequest') }}
|
||||
{{ i18n.baseText('nodeCreator.noResults.httpRequest') }}
|
||||
</n8n-link>
|
||||
|
||||
<n8n-link v-if="rootView === TRIGGER_NODE_CREATOR_VIEW" @click="$emit('addWebhookNode')">
|
||||
{{ $locale.baseText('nodeCreator.noResults.webhook') }}
|
||||
{{ i18n.baseText('nodeCreator.noResults.webhook') }}
|
||||
</n8n-link>
|
||||
{{ $locale.baseText('nodeCreator.noResults.node') }}
|
||||
{{ i18n.baseText('nodeCreator.noResults.node') }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="showRequest" :class="$style.request">
|
||||
<p v-text="$locale.baseText('nodeCreator.noResults.wantUsToMakeItFaster')" />
|
||||
<p v-text="i18n.baseText('nodeCreator.noResults.wantUsToMakeItFaster')" />
|
||||
<div>
|
||||
<n8n-link :to="REQUEST_NODE_FORM_URL">
|
||||
<span>{{ $locale.baseText('nodeCreator.noResults.requestTheNode') }}</span
|
||||
<span>{{ i18n.baseText('nodeCreator.noResults.requestTheNode') }}</span
|
||||
>
|
||||
<span>
|
||||
<font-awesome-icon
|
||||
:class="$style.external"
|
||||
icon="external-link-alt"
|
||||
:title="$locale.baseText('nodeCreator.noResults.requestTheNode')"
|
||||
:title="i18n.baseText('nodeCreator.noResults.requestTheNode')"
|
||||
/>
|
||||
</span>
|
||||
</n8n-link>
|
||||
|
|
|
@ -176,9 +176,7 @@ function onBackButton() {
|
|||
v-if="activeViewStack.hasSearch"
|
||||
:class="$style.searchBar"
|
||||
:placeholder="
|
||||
searchPlaceholder
|
||||
? searchPlaceholder
|
||||
: $locale.baseText('nodeCreator.searchBar.searchNodes')
|
||||
searchPlaceholder ? searchPlaceholder : i18n.baseText('nodeCreator.searchBar.searchNodes')
|
||||
"
|
||||
:model-value="activeViewStack.search"
|
||||
@update:model-value="onSearch"
|
||||
|
|
|
@ -75,7 +75,6 @@ const uiStore = useUIStore();
|
|||
const workflowsStore = useWorkflowsStore();
|
||||
|
||||
const nodeHelpers = useNodeHelpers();
|
||||
|
||||
const toast = useToast();
|
||||
|
||||
const subscribedToCredentialType = ref('');
|
||||
|
@ -558,7 +557,7 @@ function getCredentialsFieldLabel(credentialType: INodeCredentialDescription): s
|
|||
<N8nTooltip placement="top">
|
||||
<template #content>
|
||||
<TitledList
|
||||
:title="`${$locale.baseText('nodeCredentials.issues')}:`"
|
||||
:title="`${i18n.baseText('nodeCredentials.issues')}:`"
|
||||
:items="getIssues(type.name)"
|
||||
/>
|
||||
</template>
|
||||
|
@ -574,7 +573,7 @@ function getCredentialsFieldLabel(credentialType: INodeCredentialDescription): s
|
|||
<font-awesome-icon
|
||||
icon="pen"
|
||||
class="clickable"
|
||||
:title="$locale.baseText('nodeCredentials.updateCredential')"
|
||||
:title="i18n.baseText('nodeCredentials.updateCredential')"
|
||||
@click="editCredential(type.name)"
|
||||
/>
|
||||
</div>
|
||||
|
|
|
@ -703,13 +703,13 @@ onBeforeUnmount(() => {
|
|||
>
|
||||
<template #content>
|
||||
<div :class="$style.triggerWarning">
|
||||
{{ $locale.baseText('ndv.backToCanvas.waitingForTriggerWarning') }}
|
||||
{{ i18n.baseText('ndv.backToCanvas.waitingForTriggerWarning') }}
|
||||
</div>
|
||||
</template>
|
||||
<div :class="$style.backToCanvas" data-test-id="back-to-canvas" @click="close">
|
||||
<n8n-icon icon="arrow-left" color="text-xlight" size="medium" />
|
||||
<n8n-text color="text-xlight" size="medium" :bold="true">
|
||||
{{ $locale.baseText('ndv.backToCanvas') }}
|
||||
{{ i18n.baseText('ndv.backToCanvas') }}
|
||||
</n8n-text>
|
||||
</div>
|
||||
</n8n-tooltip>
|
||||
|
@ -816,7 +816,7 @@ onBeforeUnmount(() => {
|
|||
@click="onFeatureRequestClick"
|
||||
>
|
||||
<font-awesome-icon icon="lightbulb" />
|
||||
{{ $locale.baseText('ndv.featureRequest') }}
|
||||
{{ i18n.baseText('ndv.featureRequest') }}
|
||||
</a>
|
||||
</template>
|
||||
</NDVDraggablePanels>
|
||||
|
|
|
@ -981,7 +981,7 @@ onBeforeUnmount(() => {
|
|||
</p>
|
||||
<div class="missingNodeTitleContainer mt-s mb-xs">
|
||||
<n8n-text size="large" color="text-dark" bold>
|
||||
{{ $locale.baseText('nodeSettings.communityNodeUnknown.title') }}
|
||||
{{ i18n.baseText('nodeSettings.communityNodeUnknown.title') }}
|
||||
</n8n-text>
|
||||
</div>
|
||||
<div v-if="isCommunityNode" :class="$style.descriptionContainer">
|
||||
|
@ -1004,7 +1004,7 @@ onBeforeUnmount(() => {
|
|||
:to="COMMUNITY_NODES_INSTALLATION_DOCS_URL"
|
||||
@click="onMissingNodeLearnMoreLinkClick"
|
||||
>
|
||||
{{ $locale.baseText('nodeSettings.communityNodeUnknown.installLink.text') }}
|
||||
{{ i18n.baseText('nodeSettings.communityNodeUnknown.installLink.text') }}
|
||||
</n8n-link>
|
||||
</div>
|
||||
<i18n-t v-else keypath="nodeSettings.nodeTypeUnknown.description" tag="span">
|
||||
|
@ -1012,7 +1012,7 @@ onBeforeUnmount(() => {
|
|||
<a
|
||||
:href="CUSTOM_NODES_DOCS_URL"
|
||||
target="_blank"
|
||||
v-text="$locale.baseText('nodeSettings.nodeTypeUnknown.description.customNode')"
|
||||
v-text="i18n.baseText('nodeSettings.nodeTypeUnknown.description.customNode')"
|
||||
/>
|
||||
</template>
|
||||
</i18n-t>
|
||||
|
@ -1021,7 +1021,7 @@ onBeforeUnmount(() => {
|
|||
<n8n-notice
|
||||
v-if="hasForeignCredential && !isHomeProjectTeam"
|
||||
:content="
|
||||
$locale.baseText('nodeSettings.hasForeignCredential', {
|
||||
i18n.baseText('nodeSettings.hasForeignCredential', {
|
||||
interpolate: { owner: credentialOwnerName },
|
||||
})
|
||||
"
|
||||
|
@ -1053,7 +1053,7 @@ onBeforeUnmount(() => {
|
|||
</ParameterInputList>
|
||||
<div v-if="parametersNoneSetting.length === 0" class="no-parameters">
|
||||
<n8n-text>
|
||||
{{ $locale.baseText('nodeSettings.thisNodeDoesNotHaveAnyParameters') }}
|
||||
{{ i18n.baseText('nodeSettings.thisNodeDoesNotHaveAnyParameters') }}
|
||||
</n8n-text>
|
||||
</div>
|
||||
|
||||
|
@ -1064,7 +1064,7 @@ onBeforeUnmount(() => {
|
|||
>
|
||||
<n8n-notice
|
||||
:content="
|
||||
$locale.baseText('nodeSettings.useTheHttpRequestNode', {
|
||||
i18n.baseText('nodeSettings.useTheHttpRequestNode', {
|
||||
interpolate: { nodeTypeDisplayName: nodeType?.displayName ?? '' },
|
||||
})
|
||||
"
|
||||
|
@ -1094,7 +1094,7 @@ onBeforeUnmount(() => {
|
|||
/>
|
||||
<div class="node-version" data-test-id="node-version">
|
||||
{{
|
||||
$locale.baseText('nodeSettings.nodeVersion', {
|
||||
i18n.baseText('nodeSettings.nodeVersion', {
|
||||
interpolate: {
|
||||
node: nodeType?.displayName as string,
|
||||
version: (node.typeVersion ?? latestVersion).toString(),
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
<script setup lang="ts">
|
||||
import NodeIcon from '@/components/NodeIcon.vue';
|
||||
import { useI18n } from '@/composables/useI18n';
|
||||
import type { INodeTypeDescription } from 'n8n-workflow';
|
||||
import { computed, nextTick, ref } from 'vue';
|
||||
|
||||
|
@ -21,6 +22,8 @@ const editName = ref(false);
|
|||
const newName = ref('');
|
||||
const input = ref<HTMLInputElement>();
|
||||
|
||||
const i18n = useI18n();
|
||||
|
||||
const editable = computed(() => !props.readOnly && window === window.parent);
|
||||
|
||||
async function onEdit() {
|
||||
|
@ -54,21 +57,21 @@ function onRename() {
|
|||
@keydown.esc="editName = false"
|
||||
>
|
||||
<n8n-text :bold="true" color="text-base" tag="div">{{
|
||||
$locale.baseText('ndv.title.renameNode')
|
||||
i18n.baseText('ndv.title.renameNode')
|
||||
}}</n8n-text>
|
||||
<n8n-input ref="input" v-model="newName" size="small" data-test-id="node-rename-input" />
|
||||
<div :class="$style.editButtons">
|
||||
<n8n-button
|
||||
type="secondary"
|
||||
size="small"
|
||||
:label="$locale.baseText('ndv.title.cancel')"
|
||||
:label="i18n.baseText('ndv.title.cancel')"
|
||||
@click="editName = false"
|
||||
@keydown.enter.stop
|
||||
/>
|
||||
<n8n-button
|
||||
type="primary"
|
||||
size="small"
|
||||
:label="$locale.baseText('ndv.title.rename')"
|
||||
:label="i18n.baseText('ndv.title.rename')"
|
||||
@click="onRename"
|
||||
/>
|
||||
</div>
|
||||
|
|
|
@ -1092,7 +1092,7 @@ onUpdated(async () => {
|
|||
:model-value="codeEditDialogVisible"
|
||||
:append-to="`#${APP_MODALS_ELEMENT_ID}`"
|
||||
width="80%"
|
||||
:title="`${i18n.baseText('codeEdit.edit')} ${$locale
|
||||
:title="`${i18n.baseText('codeEdit.edit')} ${i18n
|
||||
.nodeText()
|
||||
.inputLabelDisplayName(parameter, path)}`"
|
||||
:before-close="closeCodeEditDialog"
|
||||
|
@ -1181,7 +1181,7 @@ onUpdated(async () => {
|
|||
icon="external-link-alt"
|
||||
size="xsmall"
|
||||
class="textarea-modal-opener"
|
||||
:title="$locale.baseText('parameterInput.openEditWindow')"
|
||||
:title="i18n.baseText('parameterInput.openEditWindow')"
|
||||
@click="displayEditDialog()"
|
||||
/>
|
||||
</template>
|
||||
|
@ -1203,7 +1203,7 @@ onUpdated(async () => {
|
|||
icon="external-link-alt"
|
||||
size="xsmall"
|
||||
class="textarea-modal-opener"
|
||||
:title="$locale.baseText('parameterInput.openEditWindow')"
|
||||
:title="i18n.baseText('parameterInput.openEditWindow')"
|
||||
@click="displayEditDialog()"
|
||||
/>
|
||||
</template>
|
||||
|
@ -1224,7 +1224,7 @@ onUpdated(async () => {
|
|||
icon="external-link-alt"
|
||||
size="xsmall"
|
||||
class="textarea-modal-opener"
|
||||
:title="$locale.baseText('parameterInput.openEditWindow')"
|
||||
:title="i18n.baseText('parameterInput.openEditWindow')"
|
||||
@click="displayEditDialog()"
|
||||
/>
|
||||
</template>
|
||||
|
@ -1246,7 +1246,7 @@ onUpdated(async () => {
|
|||
icon="external-link-alt"
|
||||
size="xsmall"
|
||||
class="textarea-modal-opener"
|
||||
:title="$locale.baseText('parameterInput.openEditWindow')"
|
||||
:title="i18n.baseText('parameterInput.openEditWindow')"
|
||||
@click="displayEditDialog()"
|
||||
/>
|
||||
</template>
|
||||
|
@ -1266,7 +1266,7 @@ onUpdated(async () => {
|
|||
icon="external-link-alt"
|
||||
size="xsmall"
|
||||
class="textarea-modal-opener"
|
||||
:title="$locale.baseText('parameterInput.openEditWindow')"
|
||||
:title="i18n.baseText('parameterInput.openEditWindow')"
|
||||
@click="displayEditDialog()"
|
||||
/>
|
||||
</template>
|
||||
|
|
|
@ -110,8 +110,8 @@ function onDocumentationUrlClick(): void {
|
|||
|
||||
<template>
|
||||
<n8n-input-label
|
||||
:label="$locale.credText().inputLabelDisplayName(parameter)"
|
||||
:tooltip-text="$locale.credText().inputLabelDescription(parameter)"
|
||||
:label="i18n.credText().inputLabelDisplayName(parameter)"
|
||||
:tooltip-text="i18n.credText().inputLabelDescription(parameter)"
|
||||
:required="parameter.required"
|
||||
:show-tooltip="focused"
|
||||
:show-options="menuExpanded"
|
||||
|
@ -149,7 +149,7 @@ function onDocumentationUrlClick(): void {
|
|||
/>
|
||||
<div v-if="showRequiredErrors" :class="$style.errors">
|
||||
<n8n-text color="danger" size="small">
|
||||
{{ $locale.baseText('parameterInputExpanded.thisFieldIsRequired') }}
|
||||
{{ i18n.baseText('parameterInputExpanded.thisFieldIsRequired') }}
|
||||
<n8n-link
|
||||
v-if="documentationUrl"
|
||||
:to="documentationUrl"
|
||||
|
@ -157,7 +157,7 @@ function onDocumentationUrlClick(): void {
|
|||
:underline="true"
|
||||
@click="onDocumentationUrlClick"
|
||||
>
|
||||
{{ $locale.baseText('parameterInputExpanded.openDocs') }}
|
||||
{{ i18n.baseText('parameterInputExpanded.openDocs') }}
|
||||
</n8n-link>
|
||||
</n8n-text>
|
||||
</div>
|
||||
|
|
|
@ -36,6 +36,7 @@ import { get, set } from 'lodash-es';
|
|||
import { useRouter } from 'vue-router';
|
||||
import { captureException } from '@sentry/vue';
|
||||
import { N8nNotice, N8nIconButton, N8nInputLabel, N8nText, N8nIcon } from 'n8n-design-system';
|
||||
import { useI18n } from '@/composables/useI18n';
|
||||
|
||||
const LazyFixedCollectionParameter = defineAsyncComponent(
|
||||
async () => await import('./FixedCollectionParameter.vue'),
|
||||
|
@ -69,6 +70,7 @@ const nodeHelpers = useNodeHelpers();
|
|||
const asyncLoadingError = ref(false);
|
||||
const router = useRouter();
|
||||
const workflowHelpers = useWorkflowHelpers({ router });
|
||||
const i18n = useI18n();
|
||||
|
||||
onErrorCaptured((e, component) => {
|
||||
if (
|
||||
|
@ -511,7 +513,7 @@ function getParameterValue<T extends NodeParameterValueType = NodeParameterValue
|
|||
<N8nNotice
|
||||
v-else-if="parameter.type === 'notice'"
|
||||
:class="['parameter-item', parameter.typeOptions?.containerClass ?? '']"
|
||||
:content="$locale.nodeText().inputLabelDisplayName(parameter, path)"
|
||||
:content="i18n.nodeText().inputLabelDisplayName(parameter, path)"
|
||||
@action="onNoticeAction"
|
||||
/>
|
||||
|
||||
|
@ -536,12 +538,12 @@ function getParameterValue<T extends NodeParameterValueType = NodeParameterValue
|
|||
size="mini"
|
||||
icon="trash"
|
||||
class="delete-option"
|
||||
:title="$locale.baseText('parameterInputList.delete')"
|
||||
:title="i18n.baseText('parameterInputList.delete')"
|
||||
@click="deleteOption(parameter.name)"
|
||||
></N8nIconButton>
|
||||
<N8nInputLabel
|
||||
:label="$locale.nodeText().inputLabelDisplayName(parameter, path)"
|
||||
:tooltip-text="$locale.nodeText().inputLabelDescription(parameter, path)"
|
||||
:label="i18n.nodeText().inputLabelDisplayName(parameter, path)"
|
||||
:tooltip-text="i18n.nodeText().inputLabelDescription(parameter, path)"
|
||||
size="small"
|
||||
:underline="true"
|
||||
color="text-dark"
|
||||
|
@ -570,13 +572,13 @@ function getParameterValue<T extends NodeParameterValueType = NodeParameterValue
|
|||
<template #fallback>
|
||||
<N8nText size="small" class="async-notice">
|
||||
<N8nIcon icon="sync-alt" size="xsmall" :spin="true" />
|
||||
{{ $locale.baseText('parameterInputList.loadingFields') }}
|
||||
{{ i18n.baseText('parameterInputList.loadingFields') }}
|
||||
</N8nText>
|
||||
</template>
|
||||
</Suspense>
|
||||
<N8nText v-else size="small" color="danger" class="async-notice">
|
||||
<N8nIcon icon="exclamation-triangle" size="xsmall" />
|
||||
{{ $locale.baseText('parameterInputList.loadingError') }}
|
||||
{{ i18n.baseText('parameterInputList.loadingError') }}
|
||||
</N8nText>
|
||||
</div>
|
||||
<ResourceMapper
|
||||
|
@ -619,7 +621,7 @@ function getParameterValue<T extends NodeParameterValueType = NodeParameterValue
|
|||
size="mini"
|
||||
icon="trash"
|
||||
class="delete-option"
|
||||
:title="$locale.baseText('parameterInputList.delete')"
|
||||
:title="i18n.baseText('parameterInputList.delete')"
|
||||
@click="deleteOption(parameter.name)"
|
||||
></N8nIconButton>
|
||||
|
||||
|
|
|
@ -1,16 +1,19 @@
|
|||
<script setup lang="ts">
|
||||
import TitledList from '@/components/TitledList.vue';
|
||||
import { useI18n } from '@/composables/useI18n';
|
||||
|
||||
defineProps<{
|
||||
issues: string[];
|
||||
}>();
|
||||
|
||||
const i18n = useI18n();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div v-if="issues.length" :class="$style['parameter-issues']" data-test-id="parameter-issues">
|
||||
<n8n-tooltip placement="top">
|
||||
<template #content>
|
||||
<TitledList :title="`${$locale.baseText('parameterInput.issues')}:`" :items="issues" />
|
||||
<TitledList :title="`${i18n.baseText('parameterInput.issues')}:`" :items="issues" />
|
||||
</template>
|
||||
<font-awesome-icon icon="exclamation-triangle" />
|
||||
</n8n-tooltip>
|
||||
|
|
|
@ -605,8 +605,8 @@ const onSubmit = async (values: IPersonalizationLatestVersion) => {
|
|||
<template>
|
||||
<Modal
|
||||
:name="PERSONALIZATION_MODAL_KEY"
|
||||
:title="$locale.baseText('personalizationModal.customizeN8n')"
|
||||
:subtitle="$locale.baseText('personalizationModal.theseQuestionsHelpUs')"
|
||||
:title="i18n.baseText('personalizationModal.customizeN8n')"
|
||||
:subtitle="i18n.baseText('personalizationModal.theseQuestionsHelpUs')"
|
||||
:center-title="true"
|
||||
:show-close="false"
|
||||
:event-bus="modalBus"
|
||||
|
@ -633,7 +633,7 @@ const onSubmit = async (values: IPersonalizationLatestVersion) => {
|
|||
<div>
|
||||
<n8n-button
|
||||
:loading="isSaving"
|
||||
:label="$locale.baseText('personalizationModal.getStarted')"
|
||||
:label="i18n.baseText('personalizationModal.getStarted')"
|
||||
float="right"
|
||||
@click="onSave"
|
||||
/>
|
||||
|
|
|
@ -689,15 +689,15 @@ function onInputBlur() {
|
|||
<template #error>
|
||||
<div :class="$style.error" data-test-id="rlc-error-container">
|
||||
<n8n-text color="text-dark" align="center" tag="div">
|
||||
{{ $locale.baseText('resourceLocator.mode.list.error.title') }}
|
||||
{{ i18n.baseText('resourceLocator.mode.list.error.title') }}
|
||||
</n8n-text>
|
||||
<n8n-text v-if="hasCredential || credentialsNotSet" size="small" color="text-base">
|
||||
{{ $locale.baseText('resourceLocator.mode.list.error.description.part1') }}
|
||||
{{ i18n.baseText('resourceLocator.mode.list.error.description.part1') }}
|
||||
<a v-if="credentialsNotSet" @click="createNewCredential">{{
|
||||
$locale.baseText('resourceLocator.mode.list.error.description.part2.noCredentials')
|
||||
i18n.baseText('resourceLocator.mode.list.error.description.part2.noCredentials')
|
||||
}}</a>
|
||||
<a v-else-if="hasCredential" @click="openCredential">{{
|
||||
$locale.baseText('resourceLocator.mode.list.error.description.part2.hasCredentials')
|
||||
i18n.baseText('resourceLocator.mode.list.error.description.part2.hasCredentials')
|
||||
}}</a>
|
||||
</n8n-text>
|
||||
</div>
|
||||
|
@ -714,7 +714,7 @@ function onInputBlur() {
|
|||
:model-value="selectedMode"
|
||||
:size="inputSize"
|
||||
:disabled="isReadOnly"
|
||||
:placeholder="$locale.baseText('resourceLocator.modeSelector.placeholder')"
|
||||
:placeholder="i18n.baseText('resourceLocator.modeSelector.placeholder')"
|
||||
data-test-id="rlc-mode-selector"
|
||||
@update:model-value="onModeSelected"
|
||||
>
|
||||
|
@ -726,7 +726,7 @@ function onInputBlur() {
|
|||
:disabled="isValueExpression && mode.name === 'list'"
|
||||
:title="
|
||||
isValueExpression && mode.name === 'list'
|
||||
? $locale.baseText('resourceLocator.mode.list.disabled.title')
|
||||
? i18n.baseText('resourceLocator.mode.list.disabled.title')
|
||||
: ''
|
||||
"
|
||||
>
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<script setup lang="ts">
|
||||
import { useI18n } from '@/composables/useI18n';
|
||||
import type { IResourceLocatorResultExpanded } from '@/Interface';
|
||||
import { N8nLoading } from 'n8n-design-system';
|
||||
import type { EventBus } from 'n8n-design-system/utils';
|
||||
|
@ -43,6 +44,8 @@ const emit = defineEmits<{
|
|||
filter: [filter: string];
|
||||
}>();
|
||||
|
||||
const i18n = useI18n();
|
||||
|
||||
const hoverIndex = ref(0);
|
||||
const showHoverUrl = ref(false);
|
||||
const searchRef = ref<HTMLInputElement>();
|
||||
|
@ -209,7 +212,7 @@ function onResultsEnd() {
|
|||
ref="searchRef"
|
||||
:model-value="filter"
|
||||
:clearable="true"
|
||||
:placeholder="$locale.baseText('resourceLocator.search.placeholder')"
|
||||
:placeholder="i18n.baseText('resourceLocator.search.placeholder')"
|
||||
data-test-id="rlc-search"
|
||||
@update:model-value="onFilterInput"
|
||||
>
|
||||
|
@ -219,13 +222,13 @@ function onResultsEnd() {
|
|||
</N8nInput>
|
||||
</div>
|
||||
<div v-if="filterRequired && !filter && !errorView && !loading" :class="$style.searchRequired">
|
||||
{{ $locale.baseText('resourceLocator.mode.list.searchRequired') }}
|
||||
{{ i18n.baseText('resourceLocator.mode.list.searchRequired') }}
|
||||
</div>
|
||||
<div
|
||||
v-else-if="!errorView && sortedResources.length === 0 && !loading"
|
||||
:class="$style.messageContainer"
|
||||
>
|
||||
{{ $locale.baseText('resourceLocator.mode.list.noResults') }}
|
||||
{{ i18n.baseText('resourceLocator.mode.list.noResults') }}
|
||||
</div>
|
||||
<div
|
||||
v-else-if="!errorView"
|
||||
|
@ -254,7 +257,7 @@ function onResultsEnd() {
|
|||
<font-awesome-icon
|
||||
v-if="showHoverUrl && result.url && hoverIndex === i"
|
||||
icon="external-link-alt"
|
||||
:title="result.linkAlt || $locale.baseText('resourceLocator.mode.list.openUrl')"
|
||||
:title="result.linkAlt || i18n.baseText('resourceLocator.mode.list.openUrl')"
|
||||
@click="openUrl($event, result.url)"
|
||||
/>
|
||||
</div>
|
||||
|
|
|
@ -22,6 +22,7 @@ import {
|
|||
} from '@/utils/nodeTypesUtils';
|
||||
import { useNodeSpecificationValues } from '@/composables/useNodeSpecificationValues';
|
||||
import { N8nIconButton, N8nInputLabel, N8nOption, N8nSelect, N8nTooltip } from 'n8n-design-system';
|
||||
import { useI18n } from '@/composables/useI18n';
|
||||
|
||||
interface Props {
|
||||
parameter: INodeProperties;
|
||||
|
@ -52,6 +53,8 @@ const {
|
|||
pluralFieldWordCapitalized,
|
||||
} = useNodeSpecificationValues(props.parameter.typeOptions);
|
||||
|
||||
const i18n = useI18n();
|
||||
|
||||
const emit = defineEmits<{
|
||||
fieldValueChanged: [value: IUpdateInformation];
|
||||
removeField: [field: string];
|
||||
|
@ -311,7 +314,7 @@ defineExpose({
|
|||
</N8nInputLabel>
|
||||
<div v-if="orderedFields.length === 0" class="mt-3xs mb-xs">
|
||||
<N8nText size="small">{{
|
||||
$locale.baseText('fixedCollectionParameter.currentlyNoItemsExist')
|
||||
i18n.baseText('fixedCollectionParameter.currentlyNoItemsExist')
|
||||
}}</N8nText>
|
||||
</div>
|
||||
<div
|
||||
|
|
|
@ -1254,7 +1254,7 @@ defineExpose({ enterEditMode });
|
|||
icon="thumbtack"
|
||||
:class="$style.pinnedDataCallout"
|
||||
>
|
||||
{{ $locale.baseText('runData.pindata.thisDataIsPinned') }}
|
||||
{{ i18n.baseText('runData.pindata.thisDataIsPinned') }}
|
||||
<span v-if="!isReadOnlyRoute && !readOnlyEnv" class="ml-4xs">
|
||||
<N8nLink
|
||||
theme="secondary"
|
||||
|
@ -1264,7 +1264,7 @@ defineExpose({ enterEditMode });
|
|||
data-test-id="ndv-unpin-data"
|
||||
@click.stop="onTogglePinData({ source: 'banner-link' })"
|
||||
>
|
||||
{{ $locale.baseText('runData.pindata.unpin') }}
|
||||
{{ i18n.baseText('runData.pindata.unpin') }}
|
||||
</N8nLink>
|
||||
</span>
|
||||
<template #trailingContent>
|
||||
|
@ -1276,7 +1276,7 @@ defineExpose({ enterEditMode });
|
|||
underline
|
||||
@click="onClickDataPinningDocsLink"
|
||||
>
|
||||
{{ $locale.baseText('runData.pindata.learnMore') }}
|
||||
{{ i18n.baseText('runData.pindata.learnMore') }}
|
||||
</N8nLink>
|
||||
</template>
|
||||
</N8nCallout>
|
||||
|
@ -1322,7 +1322,7 @@ defineExpose({ enterEditMode });
|
|||
<N8nIconButton
|
||||
v-if="canPinData && !isReadOnlyRoute && !readOnlyEnv"
|
||||
v-show="!editMode.enabled"
|
||||
:title="$locale.baseText('runData.editOutput')"
|
||||
:title="i18n.baseText('runData.editOutput')"
|
||||
:circle="false"
|
||||
:disabled="node?.disabled"
|
||||
icon="pencil-alt"
|
||||
|
@ -1347,13 +1347,13 @@ defineExpose({ enterEditMode });
|
|||
<div v-show="editMode.enabled" :class="$style.editModeActions">
|
||||
<N8nButton
|
||||
type="tertiary"
|
||||
:label="$locale.baseText('runData.editor.cancel')"
|
||||
:label="i18n.baseText('runData.editor.cancel')"
|
||||
@click="onClickCancelEdit"
|
||||
/>
|
||||
<N8nButton
|
||||
class="ml-2xs"
|
||||
type="primary"
|
||||
:label="$locale.baseText('runData.editor.save')"
|
||||
:label="i18n.baseText('runData.editor.save')"
|
||||
@click="onClickSaveEdit"
|
||||
/>
|
||||
</div>
|
||||
|
@ -1381,7 +1381,7 @@ defineExpose({ enterEditMode });
|
|||
@update:model-value="onRunIndexChange"
|
||||
@click.stop
|
||||
>
|
||||
<template #prepend>{{ $locale.baseText('ndv.output.run') }}</template>
|
||||
<template #prepend>{{ i18n.baseText('ndv.output.run') }}</template>
|
||||
<N8nOption
|
||||
v-for="option in maxRunIndex + 1"
|
||||
:key="option"
|
||||
|
@ -1392,7 +1392,7 @@ defineExpose({ enterEditMode });
|
|||
|
||||
<N8nTooltip v-if="canLinkRuns" placement="right">
|
||||
<template #content>
|
||||
{{ $locale.baseText(linkedRuns ? 'runData.unlinking.hint' : 'runData.linking.hint') }}
|
||||
{{ i18n.baseText(linkedRuns ? 'runData.unlinking.hint' : 'runData.linking.hint') }}
|
||||
</template>
|
||||
<N8nIconButton
|
||||
:icon="linkedRuns ? 'unlink' : 'link'"
|
||||
|
@ -1467,7 +1467,7 @@ defineExpose({ enterEditMode });
|
|||
|
||||
<N8nText v-if="search" :class="$style.itemsText">
|
||||
{{
|
||||
$locale.baseText('ndv.search.items', {
|
||||
i18n.baseText('ndv.search.items', {
|
||||
adjustToNumber: unfilteredDataCount,
|
||||
interpolate: { matched: dataCount, total: unfilteredDataCount },
|
||||
})
|
||||
|
@ -1476,7 +1476,7 @@ defineExpose({ enterEditMode });
|
|||
<N8nText v-else :class="$style.itemsText">
|
||||
<span>
|
||||
{{
|
||||
$locale.baseText('ndv.output.items', {
|
||||
i18n.baseText('ndv.output.items', {
|
||||
adjustToNumber: dataCount,
|
||||
interpolate: { count: dataCount },
|
||||
})
|
||||
|
@ -1484,7 +1484,7 @@ defineExpose({ enterEditMode });
|
|||
</span>
|
||||
<span v-if="activeTaskMetadata?.subExecutionsCount">
|
||||
{{
|
||||
$locale.baseText('ndv.output.andSubExecutions', {
|
||||
i18n.baseText('ndv.output.andSubExecutions', {
|
||||
adjustToNumber: activeTaskMetadata.subExecutionsCount,
|
||||
interpolate: { count: activeTaskMetadata.subExecutionsCount },
|
||||
})
|
||||
|
@ -1523,9 +1523,9 @@ defineExpose({ enterEditMode });
|
|||
</div>
|
||||
<div :class="$style.editModeFooter">
|
||||
<N8nInfoTip :bold="false" :class="$style.editModeFooterInfotip">
|
||||
{{ $locale.baseText('runData.editor.copyDataInfo') }}
|
||||
{{ i18n.baseText('runData.editor.copyDataInfo') }}
|
||||
<N8nLink :to="DATA_EDITING_DOCS_URL" size="small">
|
||||
{{ $locale.baseText('generic.learnMore') }}
|
||||
{{ i18n.baseText('generic.learnMore') }}
|
||||
</N8nLink>
|
||||
</N8nInfoTip>
|
||||
</div>
|
||||
|
@ -1556,9 +1556,9 @@ defineExpose({ enterEditMode });
|
|||
:class="$style.center"
|
||||
>
|
||||
<N8nText>
|
||||
{{ $locale.baseText('ndv.input.disabled', { interpolate: { nodeName: node.name } }) }}
|
||||
{{ i18n.baseText('ndv.input.disabled', { interpolate: { nodeName: node.name } }) }}
|
||||
<N8nLink @click="enableNode">
|
||||
{{ $locale.baseText('ndv.input.disabled.cta') }}
|
||||
{{ i18n.baseText('ndv.input.disabled.cta') }}
|
||||
</N8nLink>
|
||||
</N8nText>
|
||||
</div>
|
||||
|
@ -1570,7 +1570,7 @@ defineExpose({ enterEditMode });
|
|||
<div v-else-if="hasNodeRun && hasRunError" :class="$style.stretchVertically">
|
||||
<N8nText v-if="isPaneTypeInput" :class="$style.center" size="large" tag="p" bold>
|
||||
{{
|
||||
$locale.baseText('nodeErrorView.inputPanel.previousNodeError.title', {
|
||||
i18n.baseText('nodeErrorView.inputPanel.previousNodeError.title', {
|
||||
interpolate: { nodeName: node?.name ?? '' },
|
||||
})
|
||||
}}
|
||||
|
@ -1598,14 +1598,12 @@ defineExpose({ enterEditMode });
|
|||
:class="$style.center"
|
||||
>
|
||||
<div v-if="search">
|
||||
<N8nText tag="h3" size="large">{{
|
||||
$locale.baseText('ndv.search.noMatch.title')
|
||||
}}</N8nText>
|
||||
<N8nText tag="h3" size="large">{{ i18n.baseText('ndv.search.noMatch.title') }}</N8nText>
|
||||
<N8nText>
|
||||
<i18n-t keypath="ndv.search.noMatch.description" tag="span">
|
||||
<template #link>
|
||||
<a href="#" @click="onSearchClear">
|
||||
{{ $locale.baseText('ndv.search.noMatch.description.link') }}
|
||||
{{ i18n.baseText('ndv.search.noMatch.description.link') }}
|
||||
</a>
|
||||
</template>
|
||||
</i18n-t>
|
||||
|
@ -1629,7 +1627,7 @@ defineExpose({ enterEditMode });
|
|||
<N8nText align="center" tag="div"
|
||||
><span
|
||||
v-n8n-html="
|
||||
$locale.baseText('ndv.output.tooMuchData.message', {
|
||||
i18n.baseText('ndv.output.tooMuchData.message', {
|
||||
interpolate: { size: dataSizeInMB },
|
||||
})
|
||||
"
|
||||
|
@ -1638,13 +1636,13 @@ defineExpose({ enterEditMode });
|
|||
|
||||
<N8nButton
|
||||
outline
|
||||
:label="$locale.baseText('ndv.output.tooMuchData.showDataAnyway')"
|
||||
:label="i18n.baseText('ndv.output.tooMuchData.showDataAnyway')"
|
||||
@click="showTooMuchData"
|
||||
/>
|
||||
|
||||
<N8nButton
|
||||
size="small"
|
||||
:label="$locale.baseText('runData.downloadBinaryData')"
|
||||
:label="i18n.baseText('runData.downloadBinaryData')"
|
||||
@click="downloadJsonData()"
|
||||
/>
|
||||
</div>
|
||||
|
@ -1663,20 +1661,20 @@ defineExpose({ enterEditMode });
|
|||
:class="$style.center"
|
||||
>
|
||||
<N8nText>
|
||||
{{ $locale.baseText('runData.switchToBinary.info') }}
|
||||
{{ i18n.baseText('runData.switchToBinary.info') }}
|
||||
<a @click="switchToBinary">
|
||||
{{ $locale.baseText('runData.switchToBinary.binary') }}
|
||||
{{ i18n.baseText('runData.switchToBinary.binary') }}
|
||||
</a>
|
||||
</N8nText>
|
||||
</div>
|
||||
|
||||
<div v-else-if="showIoSearchNoMatchContent" :class="$style.center">
|
||||
<N8nText tag="h3" size="large">{{ $locale.baseText('ndv.search.noMatch.title') }}</N8nText>
|
||||
<N8nText tag="h3" size="large">{{ i18n.baseText('ndv.search.noMatch.title') }}</N8nText>
|
||||
<N8nText>
|
||||
<i18n-t keypath="ndv.search.noMatch.description" tag="span">
|
||||
<template #link>
|
||||
<a href="#" @click="onSearchClear">
|
||||
{{ $locale.baseText('ndv.search.noMatch.description.link') }}
|
||||
{{ i18n.baseText('ndv.search.noMatch.description.link') }}
|
||||
</a>
|
||||
</template>
|
||||
</i18n-t>
|
||||
|
@ -1737,9 +1735,7 @@ defineExpose({ enterEditMode });
|
|||
</Suspense>
|
||||
|
||||
<div v-else-if="displayMode === 'binary' && binaryData.length === 0" :class="$style.center">
|
||||
<N8nText align="center" tag="div">{{
|
||||
$locale.baseText('runData.noBinaryDataFound')
|
||||
}}</N8nText>
|
||||
<N8nText align="center" tag="div">{{ i18n.baseText('runData.noBinaryDataFound') }}</N8nText>
|
||||
</div>
|
||||
|
||||
<div v-else-if="displayMode === 'binary'" :class="$style.dataDisplay">
|
||||
|
@ -1763,7 +1759,7 @@ defineExpose({ enterEditMode });
|
|||
<div v-if="binaryData.fileName">
|
||||
<div>
|
||||
<N8nText size="small" :bold="true"
|
||||
>{{ $locale.baseText('runData.fileName') }}:
|
||||
>{{ i18n.baseText('runData.fileName') }}:
|
||||
</N8nText>
|
||||
</div>
|
||||
<div :class="$style.binaryValue">{{ binaryData.fileName }}</div>
|
||||
|
@ -1771,7 +1767,7 @@ defineExpose({ enterEditMode });
|
|||
<div v-if="binaryData.directory">
|
||||
<div>
|
||||
<N8nText size="small" :bold="true"
|
||||
>{{ $locale.baseText('runData.directory') }}:
|
||||
>{{ i18n.baseText('runData.directory') }}:
|
||||
</N8nText>
|
||||
</div>
|
||||
<div :class="$style.binaryValue">{{ binaryData.directory }}</div>
|
||||
|
@ -1779,7 +1775,7 @@ defineExpose({ enterEditMode });
|
|||
<div v-if="binaryData.fileExtension">
|
||||
<div>
|
||||
<N8nText size="small" :bold="true"
|
||||
>{{ $locale.baseText('runData.fileExtension') }}:</N8nText
|
||||
>{{ i18n.baseText('runData.fileExtension') }}:</N8nText
|
||||
>
|
||||
</div>
|
||||
<div :class="$style.binaryValue">{{ binaryData.fileExtension }}</div>
|
||||
|
@ -1787,7 +1783,7 @@ defineExpose({ enterEditMode });
|
|||
<div v-if="binaryData.mimeType">
|
||||
<div>
|
||||
<N8nText size="small" :bold="true"
|
||||
>{{ $locale.baseText('runData.mimeType') }}:
|
||||
>{{ i18n.baseText('runData.mimeType') }}:
|
||||
</N8nText>
|
||||
</div>
|
||||
<div :class="$style.binaryValue">{{ binaryData.mimeType }}</div>
|
||||
|
@ -1795,7 +1791,7 @@ defineExpose({ enterEditMode });
|
|||
<div v-if="binaryData.fileSize">
|
||||
<div>
|
||||
<N8nText size="small" :bold="true"
|
||||
>{{ $locale.baseText('runData.fileSize') }}:
|
||||
>{{ i18n.baseText('runData.fileSize') }}:
|
||||
</N8nText>
|
||||
</div>
|
||||
<div :class="$style.binaryValue">{{ binaryData.fileSize }}</div>
|
||||
|
@ -1805,7 +1801,7 @@ defineExpose({ enterEditMode });
|
|||
<N8nButton
|
||||
v-if="isViewable(index, key)"
|
||||
size="small"
|
||||
:label="$locale.baseText('runData.showBinaryData')"
|
||||
:label="i18n.baseText('runData.showBinaryData')"
|
||||
data-test-id="ndv-view-binary-data"
|
||||
@click="displayBinaryData(index, key)"
|
||||
/>
|
||||
|
@ -1813,7 +1809,7 @@ defineExpose({ enterEditMode });
|
|||
v-if="isDownloadable(index, key)"
|
||||
size="small"
|
||||
type="secondary"
|
||||
:label="$locale.baseText('runData.downloadBinaryData')"
|
||||
:label="i18n.baseText('runData.downloadBinaryData')"
|
||||
data-test-id="ndv-download-binary-data"
|
||||
@click="downloadBinaryData(index, key)"
|
||||
/>
|
||||
|
@ -1857,9 +1853,9 @@ defineExpose({ enterEditMode });
|
|||
teleported
|
||||
@update:model-value="onPageSizeChange"
|
||||
>
|
||||
<template #prepend>{{ $locale.baseText('ndv.output.pageSize') }}</template>
|
||||
<template #prepend>{{ i18n.baseText('ndv.output.pageSize') }}</template>
|
||||
<N8nOption v-for="size in pageSizes" :key="size" :label="size" :value="size"> </N8nOption>
|
||||
<N8nOption :label="$locale.baseText('ndv.output.all')" :value="dataCount"> </N8nOption>
|
||||
<N8nOption :label="i18n.baseText('ndv.output.all')" :value="dataCount"> </N8nOption>
|
||||
</N8nSelect>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -207,7 +207,7 @@ onMounted(() => {
|
|||
size="small"
|
||||
:class="$style.copyToClipboard"
|
||||
type="secondary"
|
||||
:title="$locale.baseText('nodeErrorView.copyToClipboard')"
|
||||
:title="i18n.baseText('nodeErrorView.copyToClipboard')"
|
||||
icon="copy"
|
||||
@click="onCopyToClipboard(raw)"
|
||||
/>
|
||||
|
|
|
@ -8,6 +8,7 @@ import { useWorkflowsStore } from '@/stores/workflows.store';
|
|||
import NodeIcon from '@/components/NodeIcon.vue';
|
||||
import RunDataAiContent from './RunDataAiContent.vue';
|
||||
import { ElTree } from 'element-plus';
|
||||
import { useI18n } from '@/composables/useI18n';
|
||||
|
||||
interface AIResult {
|
||||
node: string;
|
||||
|
@ -32,6 +33,9 @@ const props = withDefaults(defineProps<Props>(), { runIndex: 0 });
|
|||
const workflowsStore = useWorkflowsStore();
|
||||
const nodeTypesStore = useNodeTypesStore();
|
||||
const selectedRun: Ref<IAiData[]> = ref([]);
|
||||
|
||||
const i18n = useI18n();
|
||||
|
||||
function isTreeNodeSelected(node: TreeNode) {
|
||||
return selectedRun.value.some((run) => run.node === node.node && run.runIndex === node.runIndex);
|
||||
}
|
||||
|
@ -260,7 +264,7 @@ watch(() => props.runIndex, selectFirst, { immediate: true });
|
|||
<div v-if="selectedRun.length === 0" :class="$style.empty">
|
||||
<n8n-text size="large">
|
||||
{{
|
||||
$locale.baseText('ndv.output.ai.empty', {
|
||||
i18n.baseText('ndv.output.ai.empty', {
|
||||
interpolate: {
|
||||
node: props.node.name,
|
||||
},
|
||||
|
@ -277,7 +281,7 @@ watch(() => props.runIndex, selectFirst, { immediate: true });
|
|||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<div v-else :class="$style.noData">{{ $locale.baseText('ndv.output.ai.waiting') }}</div>
|
||||
<div v-else :class="$style.noData">{{ i18n.baseText('ndv.output.ai.waiting') }}</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@ import { computed } from 'vue';
|
|||
import NodeIcon from '@/components/NodeIcon.vue';
|
||||
import AiRunContentBlock from './AiRunContentBlock.vue';
|
||||
import { useExecutionHelpers } from '@/composables/useExecutionHelpers';
|
||||
import { useI18n } from '@/composables/useI18n';
|
||||
|
||||
interface RunMeta {
|
||||
startTimeMs: number;
|
||||
|
@ -33,6 +34,7 @@ const nodeTypesStore = useNodeTypesStore();
|
|||
const workflowsStore = useWorkflowsStore();
|
||||
|
||||
const { trackOpeningRelatedExecution, resolveRelatedExecutionUrl } = useExecutionHelpers();
|
||||
const i18n = useI18n();
|
||||
|
||||
type TokenUsageData = {
|
||||
completionTokens: number;
|
||||
|
@ -131,7 +133,7 @@ const outputError = computed(() => {
|
|||
{{ new Date(runMeta?.startTimeMs).toLocaleString() }}
|
||||
</template>
|
||||
{{
|
||||
$locale.baseText('runData.aiContentBlock.startedAt', {
|
||||
i18n.baseText('runData.aiContentBlock.startedAt', {
|
||||
interpolate: {
|
||||
startTime: new Date(runMeta?.startTimeMs).toLocaleTimeString(),
|
||||
},
|
||||
|
@ -147,7 +149,7 @@ const outputError = computed(() => {
|
|||
>
|
||||
<N8nIcon icon="external-link-alt" size="xsmall" />
|
||||
{{
|
||||
$locale.baseText('runData.openSubExecution', {
|
||||
i18n.baseText('runData.openSubExecution', {
|
||||
interpolate: {
|
||||
id: runMeta.subExecution?.executionId,
|
||||
},
|
||||
|
@ -157,7 +159,7 @@ const outputError = computed(() => {
|
|||
</li>
|
||||
<li v-if="(consumedTokensSum?.totalTokens ?? 0) > 0" :class="$style.tokensUsage">
|
||||
{{
|
||||
$locale.baseText('runData.aiContentBlock.tokens', {
|
||||
i18n.baseText('runData.aiContentBlock.tokens', {
|
||||
interpolate: {
|
||||
count: formatTokenUsageCount(consumedTokensSum?.totalTokens ?? 0),
|
||||
},
|
||||
|
@ -166,9 +168,9 @@ const outputError = computed(() => {
|
|||
<n8n-info-tip type="tooltip" theme="info-light" tooltip-placement="right">
|
||||
<div>
|
||||
<n8n-text :bold="true" size="small">
|
||||
{{ $locale.baseText('runData.aiContentBlock.tokens.prompt') }}
|
||||
{{ i18n.baseText('runData.aiContentBlock.tokens.prompt') }}
|
||||
{{
|
||||
$locale.baseText('runData.aiContentBlock.tokens', {
|
||||
i18n.baseText('runData.aiContentBlock.tokens', {
|
||||
interpolate: {
|
||||
count: formatTokenUsageCount(consumedTokensSum?.promptTokens ?? 0),
|
||||
},
|
||||
|
@ -177,9 +179,9 @@ const outputError = computed(() => {
|
|||
</n8n-text>
|
||||
<br />
|
||||
<n8n-text :bold="true" size="small">
|
||||
{{ $locale.baseText('runData.aiContentBlock.tokens.completion') }}
|
||||
{{ i18n.baseText('runData.aiContentBlock.tokens.completion') }}
|
||||
{{
|
||||
$locale.baseText('runData.aiContentBlock.tokens', {
|
||||
i18n.baseText('runData.aiContentBlock.tokens', {
|
||||
interpolate: {
|
||||
count: formatTokenUsageCount(consumedTokensSum?.completionTokens ?? 0),
|
||||
},
|
||||
|
|
|
@ -271,14 +271,12 @@ watch(
|
|||
:class="[$style.schemaWrapper, { highlightSchema: highlight }]"
|
||||
>
|
||||
<div v-if="search && nodes.length > 0 && filteredNodes.length === 0" :class="$style.noMatch">
|
||||
<n8n-text tag="h3" size="large">{{
|
||||
$locale.baseText('ndv.search.noNodeMatch.title')
|
||||
}}</n8n-text>
|
||||
<n8n-text tag="h3" size="large">{{ i18n.baseText('ndv.search.noNodeMatch.title') }}</n8n-text>
|
||||
<n8n-text>
|
||||
<i18n-t keypath="ndv.search.noMatch.description" tag="span">
|
||||
<template #link>
|
||||
<a href="#" @click="emit('clear:search')">
|
||||
{{ $locale.baseText('ndv.search.noMatch.description.link') }}
|
||||
{{ i18n.baseText('ndv.search.noMatch.description.link') }}
|
||||
</a>
|
||||
</template>
|
||||
</i18n-t>
|
||||
|
@ -399,19 +397,17 @@ watch(
|
|||
|
||||
<div v-else :class="[$style.schemaWrapper, { highlightSchema: highlight }]">
|
||||
<div v-if="isDataEmpty(nodeSchema) && search" :class="$style.noMatch">
|
||||
<n8n-text tag="h3" size="large">{{
|
||||
$locale.baseText('ndv.search.noNodeMatch.title')
|
||||
}}</n8n-text>
|
||||
<n8n-text tag="h3" size="large">{{ i18n.baseText('ndv.search.noNodeMatch.title') }}</n8n-text>
|
||||
<n8n-text>
|
||||
<i18n-t keypath="ndv.search.noMatch.description" tag="span">
|
||||
<template #link>
|
||||
<a href="#" @click="emit('clear:search')">
|
||||
{{ $locale.baseText('ndv.search.noMatch.description.link') }}
|
||||
{{ i18n.baseText('ndv.search.noMatch.description.link') }}
|
||||
</a>
|
||||
</template>
|
||||
</i18n-t>
|
||||
</n8n-text>
|
||||
<n8n-text>{{ $locale.baseText('ndv.search.noMatchSchema.description') }}</n8n-text>
|
||||
<n8n-text>{{ i18n.baseText('ndv.search.noMatchSchema.description') }}</n8n-text>
|
||||
</div>
|
||||
|
||||
<div v-else :class="$style.schema" data-test-id="run-data-schema-node-schema">
|
||||
|
|
|
@ -36,7 +36,7 @@ const shortcutTooltipLabel = computed(() => {
|
|||
|
||||
<template>
|
||||
<span :class="$style.container" data-test-id="save-button">
|
||||
<span v-if="saved" :class="$style.saved">{{ $locale.baseText('saveButton.saved') }}</span>
|
||||
<span v-if="saved" :class="$style.saved">{{ i18n.baseText('saveButton.saved') }}</span>
|
||||
<template v-else>
|
||||
<KeyboardShortcutTooltip
|
||||
v-if="withShortcut"
|
||||
|
|
|
@ -3,8 +3,10 @@ import { ElCheckbox as Checkbox, type CheckboxValueType } from 'element-plus';
|
|||
import { mapStores } from 'pinia';
|
||||
import type { BaseTextKey } from '@/plugins/i18n';
|
||||
import { useLogStreamingStore } from '@/stores/logStreaming.store';
|
||||
import { defineComponent } from 'vue';
|
||||
import { useI18n } from '@/composables/useI18n';
|
||||
|
||||
export default {
|
||||
export default defineComponent({
|
||||
name: 'EventSelection',
|
||||
components: {
|
||||
Checkbox,
|
||||
|
@ -16,6 +18,13 @@ export default {
|
|||
},
|
||||
readonly: Boolean,
|
||||
},
|
||||
setup() {
|
||||
const i18n = useI18n();
|
||||
|
||||
return {
|
||||
i18n,
|
||||
};
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
unchanged: true,
|
||||
|
@ -42,16 +51,16 @@ export default {
|
|||
this.$forceUpdate();
|
||||
},
|
||||
groupLabelName(t: string): string {
|
||||
return this.$locale.baseText(`settings.log-streaming.eventGroup.${t}` as BaseTextKey) ?? t;
|
||||
return this.i18n.baseText(`settings.log-streaming.eventGroup.${t}` as BaseTextKey) ?? t;
|
||||
},
|
||||
groupLabelInfo(t: string): string | undefined {
|
||||
const labelInfo = `settings.log-streaming.eventGroup.${t}.info`;
|
||||
const infoText = this.$locale.baseText(labelInfo as BaseTextKey);
|
||||
const infoText = this.i18n.baseText(labelInfo as BaseTextKey);
|
||||
if (infoText === labelInfo || infoText === '') return;
|
||||
return infoText;
|
||||
},
|
||||
},
|
||||
};
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
@ -89,11 +98,11 @@ export default {
|
|||
@update:model-value="onInput"
|
||||
@change="anonymizeAuditMessagesChanged"
|
||||
>
|
||||
{{ $locale.baseText('settings.log-streaming.tab.events.anonymize') }}
|
||||
{{ i18n.baseText('settings.log-streaming.tab.events.anonymize') }}
|
||||
<n8n-tooltip placement="top" :popper-class="$style.tooltipPopper">
|
||||
<n8n-icon icon="question-circle" size="small" class="ml-4xs" />
|
||||
<template #content>
|
||||
{{ $locale.baseText('settings.log-streaming.tab.events.anonymize.info') }}
|
||||
{{ i18n.baseText('settings.log-streaming.tab.events.anonymize.info') }}
|
||||
</template>
|
||||
</n8n-tooltip>
|
||||
</Checkbox>
|
||||
|
|
|
@ -21,6 +21,7 @@ import type { BrowserJsPlumbInstance } from '@jsplumb/browser-ui';
|
|||
import { useNodeBase } from '@/composables/useNodeBase';
|
||||
import { useTelemetry } from '@/composables/useTelemetry';
|
||||
import { useStyles } from '@/composables/useStyles';
|
||||
import { useI18n } from '@/composables/useI18n';
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
|
@ -56,6 +57,7 @@ const nodeTypesStore = useNodeTypesStore();
|
|||
const uiStore = useUIStore();
|
||||
const workflowsStore = useWorkflowsStore();
|
||||
const { APP_Z_INDEXES } = useStyles();
|
||||
const i18n = useI18n();
|
||||
|
||||
const isResizing = ref<boolean>(false);
|
||||
const isTouchActive = ref<boolean>(false);
|
||||
|
@ -361,7 +363,7 @@ const onContextMenu = (e: MouseEvent): void => {
|
|||
v-touch:tap="deleteNode"
|
||||
class="option"
|
||||
data-test-id="delete-sticky"
|
||||
:title="$locale.baseText('node.delete')"
|
||||
:title="i18n.baseText('node.delete')"
|
||||
>
|
||||
<font-awesome-icon icon="trash" />
|
||||
</div>
|
||||
|
@ -378,7 +380,7 @@ const onContextMenu = (e: MouseEvent): void => {
|
|||
<div
|
||||
class="option"
|
||||
data-test-id="change-sticky-color"
|
||||
:title="$locale.baseText('node.changeColor')"
|
||||
:title="i18n.baseText('node.changeColor')"
|
||||
@click="() => setColorPopoverVisible(!isColorPopoverVisible)"
|
||||
>
|
||||
<font-awesome-icon icon="palette" />
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
<script setup lang="ts">
|
||||
import { useI18n } from '@/composables/useI18n';
|
||||
import type { BaseTextKey } from '@/plugins/i18n';
|
||||
|
||||
type Props = {
|
||||
|
@ -10,6 +11,8 @@ withDefaults(defineProps<Props>(), {
|
|||
titleLocaleKey: 'noTagsView.readyToOrganizeYourWorkflows',
|
||||
descriptionLocaleKey: 'noTagsView.withWorkflowTagsYouReFree',
|
||||
});
|
||||
|
||||
const i18n = useI18n();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
@ -19,11 +22,11 @@ withDefaults(defineProps<Props>(), {
|
|||
<div>
|
||||
<div class="mb-s">
|
||||
<n8n-heading size="large">
|
||||
{{ $locale.baseText(titleLocaleKey) }}
|
||||
{{ i18n.baseText(titleLocaleKey) }}
|
||||
</n8n-heading>
|
||||
</div>
|
||||
<div class="description">
|
||||
{{ $locale.baseText(descriptionLocaleKey) }}
|
||||
{{ i18n.baseText(descriptionLocaleKey) }}
|
||||
</div>
|
||||
</div>
|
||||
<n8n-button label="Create a tag" size="large" @click="$emit('enableCreate')" />
|
||||
|
|
|
@ -5,6 +5,7 @@ import type { ITagRow } from '@/Interface';
|
|||
import { onMounted, ref, watch } from 'vue';
|
||||
import { N8nInput } from 'n8n-design-system';
|
||||
import type { BaseTextKey } from '@/plugins/i18n';
|
||||
import { useI18n } from '@/composables/useI18n';
|
||||
|
||||
interface Props {
|
||||
rows: ITagRow[];
|
||||
|
@ -26,6 +27,8 @@ const emit = defineEmits<{
|
|||
applyOperation: [];
|
||||
}>();
|
||||
|
||||
const i18n = useI18n();
|
||||
|
||||
const INPUT_TRANSITION_TIMEOUT = 350;
|
||||
const DELETE_TRANSITION_TIMEOUT = 100;
|
||||
|
||||
|
@ -135,12 +138,12 @@ onMounted(() => {
|
|||
:class="$style['tags-table']"
|
||||
stripe
|
||||
max-height="450"
|
||||
:empty-text="$locale.baseText('tagsTable.noMatchingTagsExist')"
|
||||
:empty-text="i18n.baseText('tagsTable.noMatchingTagsExist')"
|
||||
:data="rows"
|
||||
:span-method="getSpan"
|
||||
:row-class-name="getRowClasses"
|
||||
>
|
||||
<el-table-column :label="$locale.baseText('tagsTable.name')">
|
||||
<el-table-column :label="i18n.baseText('tagsTable.name')">
|
||||
<template #default="scope">
|
||||
<div :key="scope.row.id" :class="$style.name" @keydown.stop>
|
||||
<transition name="fade" mode="out-in">
|
||||
|
@ -152,7 +155,7 @@ onMounted(() => {
|
|||
@update:model-value="onNewNameChange"
|
||||
></N8nInput>
|
||||
<span v-else-if="scope.row.delete">
|
||||
<span>{{ $locale.baseText('tagsTable.areYouSureYouWantToDeleteThisTag') }}</span>
|
||||
<span>{{ i18n.baseText('tagsTable.areYouSureYouWantToDeleteThisTag') }}</span>
|
||||
<input ref="deleteHiddenInput" :class="$style.hidden" />
|
||||
</span>
|
||||
<span v-else :class="{ [$style.disabled]: scope.row.disable }">
|
||||
|
@ -162,7 +165,7 @@ onMounted(() => {
|
|||
</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$locale.baseText(usageColumnTitleLocaleKey)" width="170">
|
||||
<el-table-column :label="i18n.baseText(usageColumnTitleLocaleKey)" width="170">
|
||||
<template #default="scope">
|
||||
<transition name="fade" mode="out-in">
|
||||
<div
|
||||
|
@ -179,53 +182,53 @@ onMounted(() => {
|
|||
<transition name="fade" mode="out-in">
|
||||
<div v-if="scope.row.create" :class="$style.ops">
|
||||
<n8n-button
|
||||
:label="$locale.baseText('tagsTable.cancel')"
|
||||
:label="i18n.baseText('tagsTable.cancel')"
|
||||
type="secondary"
|
||||
:disabled="isSaving"
|
||||
@click.stop="cancel"
|
||||
/>
|
||||
<n8n-button
|
||||
:label="$locale.baseText('tagsTable.createTag')"
|
||||
:label="i18n.baseText('tagsTable.createTag')"
|
||||
:loading="isSaving"
|
||||
@click.stop="apply"
|
||||
/>
|
||||
</div>
|
||||
<div v-else-if="scope.row.update" :class="$style.ops">
|
||||
<n8n-button
|
||||
:label="$locale.baseText('tagsTable.cancel')"
|
||||
:label="i18n.baseText('tagsTable.cancel')"
|
||||
type="secondary"
|
||||
:disabled="isSaving"
|
||||
@click.stop="cancel"
|
||||
/>
|
||||
<n8n-button
|
||||
:label="$locale.baseText('tagsTable.saveChanges')"
|
||||
:label="i18n.baseText('tagsTable.saveChanges')"
|
||||
:loading="isSaving"
|
||||
@click.stop="apply"
|
||||
/>
|
||||
</div>
|
||||
<div v-else-if="scope.row.delete" :class="$style.ops">
|
||||
<n8n-button
|
||||
:label="$locale.baseText('tagsTable.cancel')"
|
||||
:label="i18n.baseText('tagsTable.cancel')"
|
||||
type="secondary"
|
||||
:disabled="isSaving"
|
||||
@click.stop="cancel"
|
||||
/>
|
||||
<n8n-button
|
||||
:label="$locale.baseText('tagsTable.deleteTag')"
|
||||
:label="i18n.baseText('tagsTable.deleteTag')"
|
||||
:loading="isSaving"
|
||||
@click.stop="apply"
|
||||
/>
|
||||
</div>
|
||||
<div v-else-if="!scope.row.disable" :class="[$style.ops, $style.main]">
|
||||
<n8n-icon-button
|
||||
:title="$locale.baseText('tagsTable.editTag')"
|
||||
:title="i18n.baseText('tagsTable.editTag')"
|
||||
icon="pen"
|
||||
data-test-id="edit-tag-button"
|
||||
@click.stop="enableUpdate(scope.row)"
|
||||
/>
|
||||
<n8n-icon-button
|
||||
v-if="scope.row.canDelete"
|
||||
:title="$locale.baseText('tagsTable.deleteTag')"
|
||||
:title="i18n.baseText('tagsTable.deleteTag')"
|
||||
icon="trash"
|
||||
data-test-id="delete-tag-button"
|
||||
@click.stop="enableDelete(scope.row)"
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<script setup lang="ts">
|
||||
import { ref } from 'vue';
|
||||
import { MAX_TAG_NAME_LENGTH } from '@/constants';
|
||||
import { useI18n } from '@/composables/useI18n';
|
||||
|
||||
withDefaults(
|
||||
defineProps<{
|
||||
|
@ -13,6 +14,8 @@ withDefaults(
|
|||
},
|
||||
);
|
||||
|
||||
const i18n = useI18n();
|
||||
|
||||
const emit = defineEmits<{
|
||||
searchChange: [value: string];
|
||||
createEnable: [];
|
||||
|
@ -33,7 +36,7 @@ const onSearchChange = (search: string) => {
|
|||
<el-row class="tags-header">
|
||||
<el-col :span="10">
|
||||
<n8n-input
|
||||
:placeholder="$locale.baseText('tagsTableHeader.searchTags')"
|
||||
:placeholder="i18n.baseText('tagsTableHeader.searchTags')"
|
||||
:model-value="search"
|
||||
:disabled="disabled"
|
||||
:maxlength="maxLength"
|
||||
|
@ -49,7 +52,7 @@ const onSearchChange = (search: string) => {
|
|||
<n8n-button
|
||||
:disabled="disabled"
|
||||
icon="plus"
|
||||
:label="$locale.baseText('tagsTableHeader.addNew')"
|
||||
:label="i18n.baseText('tagsTableHeader.addNew')"
|
||||
size="large"
|
||||
float="right"
|
||||
@click="onAddNew"
|
||||
|
|
|
@ -63,7 +63,7 @@ const redirectToSearchPage = (node: ITemplatesNode) => {
|
|||
|
||||
<TemplateDetailsBlock
|
||||
v-if="!loading && isFullTemplatesCollection(template) && template.categories.length > 0"
|
||||
:title="$locale.baseText('template.details.categories')"
|
||||
:title="i18n.baseText('template.details.categories')"
|
||||
>
|
||||
<n8n-tags :tags="template.categories" @click:tag="redirectToCategory" />
|
||||
</TemplateDetailsBlock>
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
import { onBeforeUnmount, onMounted, ref } from 'vue';
|
||||
import TemplateCard from './TemplateCard.vue';
|
||||
import type { ITemplatesWorkflow } from '@/Interface';
|
||||
import { useI18n } from '@/composables/useI18n';
|
||||
|
||||
interface Props {
|
||||
workflows?: ITemplatesWorkflow[];
|
||||
|
@ -29,6 +30,8 @@ const props = withDefaults(defineProps<Props>(), {
|
|||
totalCount: 0,
|
||||
});
|
||||
|
||||
const i18n = useI18n();
|
||||
|
||||
const loader = ref<HTMLElement | null>(null);
|
||||
|
||||
onMounted(() => {
|
||||
|
@ -76,7 +79,7 @@ function onUseWorkflow(event: MouseEvent, id: number) {
|
|||
<div v-if="loading || workflows.length" :class="$style.list">
|
||||
<div v-if="!simpleView" :class="$style.header">
|
||||
<n8n-heading :bold="true" size="medium" color="text-light">
|
||||
{{ $locale.baseText('templates.workflows') }}
|
||||
{{ i18n.baseText('templates.workflows') }}
|
||||
<span v-if="totalCount > 0" data-test-id="template-count-label">({{ totalCount }})</span>
|
||||
<span v-if="!loading && totalWorkflows" v-text="`(${totalWorkflows})`" />
|
||||
</n8n-heading>
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
import { ref, watch, onMounted, nextTick } from 'vue';
|
||||
import type { INodeProperties } from 'n8n-workflow';
|
||||
import { APP_MODALS_ELEMENT_ID } from '@/constants';
|
||||
import { useI18n } from '@/composables/useI18n';
|
||||
|
||||
const props = defineProps<{
|
||||
dialogVisible: boolean;
|
||||
|
@ -19,6 +20,8 @@ const emit = defineEmits<{
|
|||
const inputField = ref<HTMLInputElement | null>(null);
|
||||
const tempValue = ref('');
|
||||
|
||||
const i18n = useI18n();
|
||||
|
||||
watch(
|
||||
() => props.dialogVisible,
|
||||
async (newValue) => {
|
||||
|
@ -63,19 +66,19 @@ const closeDialog = () => {
|
|||
:model-value="dialogVisible"
|
||||
:append-to="`#${APP_MODALS_ELEMENT_ID}`"
|
||||
width="80%"
|
||||
:title="`${$locale.baseText('textEdit.edit')} ${$locale
|
||||
:title="`${i18n.baseText('textEdit.edit')} ${i18n
|
||||
.nodeText()
|
||||
.inputLabelDisplayName(parameter, path)}`"
|
||||
:before-close="closeDialog"
|
||||
>
|
||||
<div class="ignore-key-press-canvas">
|
||||
<n8n-input-label :label="$locale.nodeText().inputLabelDisplayName(parameter, path)">
|
||||
<n8n-input-label :label="i18n.nodeText().inputLabelDisplayName(parameter, path)">
|
||||
<div @keydown.stop @keydown.esc="onKeyDownEsc">
|
||||
<n8n-input
|
||||
ref="inputField"
|
||||
v-model="tempValue"
|
||||
type="textarea"
|
||||
:placeholder="$locale.nodeText().placeholder(parameter, path)"
|
||||
:placeholder="i18n.nodeText().placeholder(parameter, path)"
|
||||
:read-only="isReadOnly"
|
||||
:rows="15"
|
||||
@update:model-value="valueChanged"
|
||||
|
|
|
@ -28,24 +28,24 @@ const nodeName = (node: IVersionNode): string => {
|
|||
<div :class="$style.header">
|
||||
<div>
|
||||
<div :class="$style.name">
|
||||
{{ `${$locale.baseText('versionCard.version')} ${version.name}` }}
|
||||
{{ `${i18n.baseText('versionCard.version')} ${version.name}` }}
|
||||
</div>
|
||||
<WarningTooltip v-if="version.hasSecurityIssue">
|
||||
<span v-n8n-html="$locale.baseText('versionCard.thisVersionHasASecurityIssue')"></span>
|
||||
<span v-n8n-html="i18n.baseText('versionCard.thisVersionHasASecurityIssue')"></span>
|
||||
</WarningTooltip>
|
||||
<Badge
|
||||
v-if="version.hasSecurityFix"
|
||||
:text="$locale.baseText('versionCard.securityUpdate')"
|
||||
:text="i18n.baseText('versionCard.securityUpdate')"
|
||||
type="danger"
|
||||
/>
|
||||
<Badge
|
||||
v-if="version.hasBreakingChange"
|
||||
:text="$locale.baseText('versionCard.breakingChanges')"
|
||||
:text="i18n.baseText('versionCard.breakingChanges')"
|
||||
type="warning"
|
||||
/>
|
||||
</div>
|
||||
<div :class="$style['release-date']">
|
||||
{{ $locale.baseText('versionCard.released') }} <TimeAgo :date="version.createdAt" />
|
||||
{{ i18n.baseText('versionCard.released') }} <TimeAgo :date="version.createdAt" />
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
|
|
|
@ -8,11 +8,14 @@ import WorkerJobAccordion from './WorkerJobAccordion.ee.vue';
|
|||
import WorkerNetAccordion from './WorkerNetAccordion.ee.vue';
|
||||
import WorkerChartsAccordion from './WorkerChartsAccordion.ee.vue';
|
||||
import { sortByProperty } from '@/utils/sortUtils';
|
||||
import { useI18n } from '@/composables/useI18n';
|
||||
|
||||
let interval: NodeJS.Timer;
|
||||
|
||||
const orchestrationStore = useOrchestrationStore();
|
||||
|
||||
const i18n = useI18n();
|
||||
|
||||
const props = defineProps<{
|
||||
workerId: string;
|
||||
}>();
|
||||
|
@ -73,7 +76,7 @@ onBeforeUnmount(() => {
|
|||
<div :class="$style.cardDescription">
|
||||
<n8n-text color="text-light" size="small" :class="$style.container">
|
||||
<span
|
||||
>{{ $locale.baseText('workerList.item.lastUpdated') }} {{ secondsSinceLastUpdateString }}s
|
||||
>{{ i18n.baseText('workerList.item.lastUpdated') }} {{ secondsSinceLastUpdateString }}s
|
||||
ago | n8n-Version: {{ worker.version }} | Architecture: {{ worker.arch }} (
|
||||
{{ worker.platform }}) | Uptime: {{ upTime(worker.uptime) }}</span
|
||||
>
|
||||
|
|
|
@ -6,11 +6,14 @@ import type { ChartData, ChartOptions } from 'chart.js';
|
|||
import type { ChartComponentRef } from 'vue-chartjs';
|
||||
import { Chart } from 'vue-chartjs';
|
||||
import { averageWorkerLoadFromLoads, memAsGb } from '@/utils/workerUtils';
|
||||
import { useI18n } from '@/composables/useI18n';
|
||||
|
||||
const props = defineProps<{
|
||||
workerId: string;
|
||||
}>();
|
||||
|
||||
const i18n = useI18n();
|
||||
|
||||
const blankDataSet = (label: string, color: string, prefill: number = 0) => ({
|
||||
datasets: [
|
||||
{
|
||||
|
@ -94,7 +97,7 @@ orchestrationStore.$onAction(({ name, store }) => {
|
|||
<template>
|
||||
<WorkerAccordion icon="tasks" icon-color="black" :initial-expanded="false">
|
||||
<template #title>
|
||||
{{ $locale.baseText('workerList.item.chartsTitle') }}
|
||||
{{ i18n.baseText('workerList.item.chartsTitle') }}
|
||||
</template>
|
||||
<template #content>
|
||||
<div :class="$style.charts">
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
<script setup lang="ts">
|
||||
import type { RunningJobSummary } from '@n8n/api-types';
|
||||
import WorkerAccordion from './WorkerAccordion.ee.vue';
|
||||
import { useI18n } from '@/composables/useI18n';
|
||||
|
||||
const props = defineProps<{
|
||||
items: RunningJobSummary[];
|
||||
}>();
|
||||
|
||||
const i18n = useI18n();
|
||||
|
||||
function runningSince(started: Date): string {
|
||||
let seconds = Math.floor((new Date().getTime() - started.getTime()) / 1000);
|
||||
const hrs = Math.floor(seconds / 3600);
|
||||
|
@ -19,7 +22,7 @@ function runningSince(started: Date): string {
|
|||
<template>
|
||||
<WorkerAccordion icon="tasks" icon-color="black" :initial-expanded="true">
|
||||
<template #title>
|
||||
{{ $locale.baseText('workerList.item.jobListTitle') }} ({{ items.length }})
|
||||
{{ i18n.baseText('workerList.item.jobListTitle') }} ({{ items.length }})
|
||||
</template>
|
||||
<template #content>
|
||||
<div v-if="props.items.length > 0" :class="$style.accordionItems">
|
||||
|
@ -38,7 +41,7 @@ function runningSince(started: Date): string {
|
|||
</div>
|
||||
<div v-else :class="$style.accordionItems">
|
||||
<span :class="$style.empty">
|
||||
{{ $locale.baseText('workerList.item.jobList.empty') }}
|
||||
{{ i18n.baseText('workerList.item.jobList.empty') }}
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
@ -27,7 +27,7 @@ function onCopyToClipboard(content: string) {
|
|||
<template>
|
||||
<WorkerAccordion icon="tasks" icon-color="black" :initial-expanded="false">
|
||||
<template #title>
|
||||
{{ $locale.baseText('workerList.item.netListTitle') }} ({{ items.length }})
|
||||
{{ i18n.baseText('workerList.item.netListTitle') }} ({{ items.length }})
|
||||
</template>
|
||||
<template #content>
|
||||
<div v-if="props.items.length > 0" :class="$style.accordionItems">
|
||||
|
|
|
@ -472,7 +472,7 @@ onMounted(async () => {
|
|||
width="65%"
|
||||
max-height="80%"
|
||||
:title="
|
||||
$locale.baseText('workflowSettings.settingsFor', {
|
||||
i18n.baseText('workflowSettings.settingsFor', {
|
||||
interpolate: { workflowName, workflowId },
|
||||
})
|
||||
"
|
||||
|
@ -483,7 +483,7 @@ onMounted(async () => {
|
|||
<div v-loading="isLoading" class="workflow-settings" data-test-id="workflow-settings-dialog">
|
||||
<el-row>
|
||||
<el-col :span="10" class="setting-name">
|
||||
{{ $locale.baseText('workflowSettings.executionOrder') + ':' }}
|
||||
{{ i18n.baseText('workflowSettings.executionOrder') + ':' }}
|
||||
</el-col>
|
||||
<el-col :span="14" class="ignore-key-press-canvas">
|
||||
<n8n-select
|
||||
|
@ -508,7 +508,7 @@ onMounted(async () => {
|
|||
|
||||
<el-row>
|
||||
<el-col :span="10" class="setting-name">
|
||||
{{ $locale.baseText('workflowSettings.errorWorkflow') + ':' }}
|
||||
{{ i18n.baseText('workflowSettings.errorWorkflow') + ':' }}
|
||||
<n8n-tooltip placement="top">
|
||||
<template #content>
|
||||
<div v-n8n-html="helpTexts.errorWorkflow"></div>
|
||||
|
@ -538,7 +538,7 @@ onMounted(async () => {
|
|||
<div v-if="isSharingEnabled" data-test-id="workflow-caller-policy">
|
||||
<el-row>
|
||||
<el-col :span="10" class="setting-name">
|
||||
{{ $locale.baseText('workflowSettings.callerPolicy') + ':' }}
|
||||
{{ i18n.baseText('workflowSettings.callerPolicy') + ':' }}
|
||||
<n8n-tooltip placement="top">
|
||||
<template #content>
|
||||
<div v-text="helpTexts.workflowCallerPolicy"></div>
|
||||
|
@ -551,7 +551,7 @@ onMounted(async () => {
|
|||
<n8n-select
|
||||
v-model="workflowSettings.callerPolicy"
|
||||
:disabled="readOnlyEnv || !workflowPermissions.update"
|
||||
:placeholder="$locale.baseText('workflowSettings.selectOption')"
|
||||
:placeholder="i18n.baseText('workflowSettings.selectOption')"
|
||||
filterable
|
||||
:limit-popper-width="true"
|
||||
>
|
||||
|
@ -567,7 +567,7 @@ onMounted(async () => {
|
|||
</el-row>
|
||||
<el-row v-if="workflowSettings.callerPolicy === 'workflowsFromAList'">
|
||||
<el-col :span="10" class="setting-name">
|
||||
{{ $locale.baseText('workflowSettings.callerIds') + ':' }}
|
||||
{{ i18n.baseText('workflowSettings.callerIds') + ':' }}
|
||||
<n8n-tooltip placement="top">
|
||||
<template #content>
|
||||
<div v-text="helpTexts.workflowCallerIds"></div>
|
||||
|
@ -579,7 +579,7 @@ onMounted(async () => {
|
|||
<n8n-input
|
||||
v-model="workflowSettings.callerIds"
|
||||
:disabled="readOnlyEnv || !workflowPermissions.update"
|
||||
:placeholder="$locale.baseText('workflowSettings.callerIds.placeholder')"
|
||||
:placeholder="i18n.baseText('workflowSettings.callerIds.placeholder')"
|
||||
type="text"
|
||||
data-test-id="workflow-caller-policy-workflow-ids"
|
||||
@update:model-value="onCallerIdsInput"
|
||||
|
@ -589,7 +589,7 @@ onMounted(async () => {
|
|||
</div>
|
||||
<el-row>
|
||||
<el-col :span="10" class="setting-name">
|
||||
{{ $locale.baseText('workflowSettings.timezone') + ':' }}
|
||||
{{ i18n.baseText('workflowSettings.timezone') + ':' }}
|
||||
<n8n-tooltip placement="top">
|
||||
<template #content>
|
||||
<div v-text="helpTexts.timezone"></div>
|
||||
|
@ -618,7 +618,7 @@ onMounted(async () => {
|
|||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="10" class="setting-name">
|
||||
{{ $locale.baseText('workflowSettings.saveDataErrorExecution') + ':' }}
|
||||
{{ i18n.baseText('workflowSettings.saveDataErrorExecution') + ':' }}
|
||||
<n8n-tooltip placement="top">
|
||||
<template #content>
|
||||
<div v-text="helpTexts.saveDataErrorExecution"></div>
|
||||
|
@ -629,7 +629,7 @@ onMounted(async () => {
|
|||
<el-col :span="14" class="ignore-key-press-canvas">
|
||||
<n8n-select
|
||||
v-model="workflowSettings.saveDataErrorExecution"
|
||||
:placeholder="$locale.baseText('workflowSettings.selectOption')"
|
||||
:placeholder="i18n.baseText('workflowSettings.selectOption')"
|
||||
filterable
|
||||
:disabled="readOnlyEnv || !workflowPermissions.update"
|
||||
:limit-popper-width="true"
|
||||
|
@ -647,7 +647,7 @@ onMounted(async () => {
|
|||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="10" class="setting-name">
|
||||
{{ $locale.baseText('workflowSettings.saveDataSuccessExecution') + ':' }}
|
||||
{{ i18n.baseText('workflowSettings.saveDataSuccessExecution') + ':' }}
|
||||
<n8n-tooltip placement="top">
|
||||
<template #content>
|
||||
<div v-text="helpTexts.saveDataSuccessExecution"></div>
|
||||
|
@ -658,7 +658,7 @@ onMounted(async () => {
|
|||
<el-col :span="14" class="ignore-key-press-canvas">
|
||||
<n8n-select
|
||||
v-model="workflowSettings.saveDataSuccessExecution"
|
||||
:placeholder="$locale.baseText('workflowSettings.selectOption')"
|
||||
:placeholder="i18n.baseText('workflowSettings.selectOption')"
|
||||
filterable
|
||||
:disabled="readOnlyEnv || !workflowPermissions.update"
|
||||
:limit-popper-width="true"
|
||||
|
@ -676,7 +676,7 @@ onMounted(async () => {
|
|||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="10" class="setting-name">
|
||||
{{ $locale.baseText('workflowSettings.saveManualExecutions') + ':' }}
|
||||
{{ i18n.baseText('workflowSettings.saveManualExecutions') + ':' }}
|
||||
<n8n-tooltip placement="top">
|
||||
<template #content>
|
||||
<div v-text="helpTexts.saveManualExecutions"></div>
|
||||
|
@ -687,7 +687,7 @@ onMounted(async () => {
|
|||
<el-col :span="14" class="ignore-key-press-canvas">
|
||||
<n8n-select
|
||||
v-model="workflowSettings.saveManualExecutions"
|
||||
:placeholder="$locale.baseText('workflowSettings.selectOption')"
|
||||
:placeholder="i18n.baseText('workflowSettings.selectOption')"
|
||||
filterable
|
||||
:disabled="readOnlyEnv || !workflowPermissions.update"
|
||||
:limit-popper-width="true"
|
||||
|
@ -705,7 +705,7 @@ onMounted(async () => {
|
|||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="10" class="setting-name">
|
||||
{{ $locale.baseText('workflowSettings.saveExecutionProgress') + ':' }}
|
||||
{{ i18n.baseText('workflowSettings.saveExecutionProgress') + ':' }}
|
||||
<n8n-tooltip placement="top">
|
||||
<template #content>
|
||||
<div v-text="helpTexts.saveExecutionProgress"></div>
|
||||
|
@ -716,7 +716,7 @@ onMounted(async () => {
|
|||
<el-col :span="14" class="ignore-key-press-canvas">
|
||||
<n8n-select
|
||||
v-model="workflowSettings.saveExecutionProgress"
|
||||
:placeholder="$locale.baseText('workflowSettings.selectOption')"
|
||||
:placeholder="i18n.baseText('workflowSettings.selectOption')"
|
||||
filterable
|
||||
:disabled="readOnlyEnv || !workflowPermissions.update"
|
||||
:limit-popper-width="true"
|
||||
|
@ -734,7 +734,7 @@ onMounted(async () => {
|
|||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="10" class="setting-name">
|
||||
{{ $locale.baseText('workflowSettings.timeoutWorkflow') + ':' }}
|
||||
{{ i18n.baseText('workflowSettings.timeoutWorkflow') + ':' }}
|
||||
<n8n-tooltip placement="top">
|
||||
<template #content>
|
||||
<div v-text="helpTexts.executionTimeoutToggle"></div>
|
||||
|
@ -761,7 +761,7 @@ onMounted(async () => {
|
|||
>
|
||||
<el-row>
|
||||
<el-col :span="10" class="setting-name">
|
||||
{{ $locale.baseText('workflowSettings.timeoutAfter') + ':' }}
|
||||
{{ i18n.baseText('workflowSettings.timeoutAfter') + ':' }}
|
||||
<n8n-tooltip placement="top">
|
||||
<template #content>
|
||||
<div v-text="helpTexts.executionTimeout"></div>
|
||||
|
@ -776,7 +776,7 @@ onMounted(async () => {
|
|||
:min="0"
|
||||
@update:model-value="(value: string) => setTheTimeout('hours', value)"
|
||||
>
|
||||
<template #append>{{ $locale.baseText('workflowSettings.hours') }}</template>
|
||||
<template #append>{{ i18n.baseText('workflowSettings.hours') }}</template>
|
||||
</n8n-input>
|
||||
</el-col>
|
||||
<el-col :span="4" class="timeout-input">
|
||||
|
@ -787,7 +787,7 @@ onMounted(async () => {
|
|||
:max="60"
|
||||
@update:model-value="(value: string) => setTheTimeout('minutes', value)"
|
||||
>
|
||||
<template #append>{{ $locale.baseText('workflowSettings.minutes') }}</template>
|
||||
<template #append>{{ i18n.baseText('workflowSettings.minutes') }}</template>
|
||||
</n8n-input>
|
||||
</el-col>
|
||||
<el-col :span="4" class="timeout-input">
|
||||
|
@ -798,7 +798,7 @@ onMounted(async () => {
|
|||
:max="60"
|
||||
@update:model-value="(value: string) => setTheTimeout('seconds', value)"
|
||||
>
|
||||
<template #append>{{ $locale.baseText('workflowSettings.seconds') }}</template>
|
||||
<template #append>{{ i18n.baseText('workflowSettings.seconds') }}</template>
|
||||
</n8n-input>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
@ -809,7 +809,7 @@ onMounted(async () => {
|
|||
<div class="action-buttons" data-test-id="workflow-settings-save-button">
|
||||
<n8n-button
|
||||
:disabled="readOnlyEnv || !workflowPermissions.update"
|
||||
:label="$locale.baseText('workflowSettings.save')"
|
||||
:label="i18n.baseText('workflowSettings.save')"
|
||||
size="large"
|
||||
float="right"
|
||||
@click="saveSettings"
|
||||
|
|
|
@ -4,6 +4,7 @@ import KeyboardShortcutTooltip from '@/components/KeyboardShortcutTooltip.vue';
|
|||
import { computed } from 'vue';
|
||||
import { useBugReporting } from '@/composables/useBugReporting';
|
||||
import { useTelemetry } from '@/composables/useTelemetry';
|
||||
import { useI18n } from '@/composables/useI18n';
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
|
@ -25,6 +26,7 @@ const emit = defineEmits<{
|
|||
|
||||
const { getReportingURL } = useBugReporting();
|
||||
const telemetry = useTelemetry();
|
||||
const i18n = useI18n();
|
||||
|
||||
const isResetZoomVisible = computed(() => props.zoom !== 1);
|
||||
|
||||
|
@ -51,7 +53,7 @@ function trackBugReport() {
|
|||
<template>
|
||||
<Controls :show-zoom="false" :show-fit-view="false">
|
||||
<KeyboardShortcutTooltip
|
||||
:label="$locale.baseText('nodeView.zoomToFit')"
|
||||
:label="i18n.baseText('nodeView.zoomToFit')"
|
||||
:shortcut="{ keys: ['1'] }"
|
||||
>
|
||||
<N8nIconButton
|
||||
|
@ -62,10 +64,7 @@ function trackBugReport() {
|
|||
@click="onZoomToFit"
|
||||
/>
|
||||
</KeyboardShortcutTooltip>
|
||||
<KeyboardShortcutTooltip
|
||||
:label="$locale.baseText('nodeView.zoomIn')"
|
||||
:shortcut="{ keys: ['+'] }"
|
||||
>
|
||||
<KeyboardShortcutTooltip :label="i18n.baseText('nodeView.zoomIn')" :shortcut="{ keys: ['+'] }">
|
||||
<N8nIconButton
|
||||
type="tertiary"
|
||||
size="large"
|
||||
|
@ -74,10 +73,7 @@ function trackBugReport() {
|
|||
@click="onZoomIn"
|
||||
/>
|
||||
</KeyboardShortcutTooltip>
|
||||
<KeyboardShortcutTooltip
|
||||
:label="$locale.baseText('nodeView.zoomOut')"
|
||||
:shortcut="{ keys: ['-'] }"
|
||||
>
|
||||
<KeyboardShortcutTooltip :label="i18n.baseText('nodeView.zoomOut')" :shortcut="{ keys: ['-'] }">
|
||||
<N8nIconButton
|
||||
type="tertiary"
|
||||
size="large"
|
||||
|
@ -88,7 +84,7 @@ function trackBugReport() {
|
|||
</KeyboardShortcutTooltip>
|
||||
<KeyboardShortcutTooltip
|
||||
v-if="isResetZoomVisible"
|
||||
:label="$locale.baseText('nodeView.resetZoom')"
|
||||
:label="i18n.baseText('nodeView.resetZoom')"
|
||||
:shortcut="{ keys: ['0'] }"
|
||||
>
|
||||
<N8nIconButton
|
||||
|
@ -101,7 +97,7 @@ function trackBugReport() {
|
|||
</KeyboardShortcutTooltip>
|
||||
<KeyboardShortcutTooltip
|
||||
v-if="props.showBugReportingButton"
|
||||
:label="$locale.baseText('nodeView.reportBug')"
|
||||
:label="i18n.baseText('nodeView.reportBug')"
|
||||
>
|
||||
<a :href="getReportingURL()" target="_blank" @click="trackBugReport">
|
||||
<N8nIconButton type="tertiary" size="large" icon="bug" data-test-id="report-bug" />
|
||||
|
|
|
@ -3,8 +3,10 @@ import { onBeforeUnmount, onMounted, ref } from 'vue';
|
|||
import { useNodeCreatorStore } from '@/stores/nodeCreator.store';
|
||||
import { NODE_CREATOR_OPEN_SOURCES } from '@/constants';
|
||||
import { nodeViewEventBus } from '@/event-bus';
|
||||
import { useI18n } from '@/composables/useI18n';
|
||||
|
||||
const nodeCreatorStore = useNodeCreatorStore();
|
||||
const i18n = useI18n();
|
||||
|
||||
const isTooltipVisible = ref(false);
|
||||
|
||||
|
@ -45,10 +47,10 @@ function onClick() {
|
|||
<FontAwesomeIcon icon="plus" size="lg" />
|
||||
</button>
|
||||
<template #content>
|
||||
{{ $locale.baseText('nodeView.canvasAddButton.addATriggerNodeBeforeExecuting') }}
|
||||
{{ i18n.baseText('nodeView.canvasAddButton.addATriggerNodeBeforeExecuting') }}
|
||||
</template>
|
||||
</N8nTooltip>
|
||||
<p :class="$style.label" v-text="$locale.baseText('nodeView.canvasAddButton.addFirstStep')" />
|
||||
<p :class="$style.label" v-text="i18n.baseText('nodeView.canvasAddButton.addFirstStep')" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
|
@ -115,7 +115,7 @@ function openContextMenu(event: MouseEvent) {
|
|||
<slot />
|
||||
<N8nTooltip v-if="renderOptions.trigger" placement="bottom">
|
||||
<template #content>
|
||||
<span v-n8n-html="$locale.baseText('node.thisIsATriggerNode')" />
|
||||
<span v-n8n-html="i18n.baseText('node.thisIsATriggerNode')" />
|
||||
</template>
|
||||
<div :class="$style.triggerIcon">
|
||||
<FontAwesomeIcon icon="bolt" size="lg" />
|
||||
|
|
|
@ -3,8 +3,10 @@ import { computed } from 'vue';
|
|||
import TitledList from '@/components/TitledList.vue';
|
||||
import { useNodeHelpers } from '@/composables/useNodeHelpers';
|
||||
import { useCanvasNode } from '@/composables/useCanvasNode';
|
||||
import { useI18n } from '@/composables/useI18n';
|
||||
|
||||
const nodeHelpers = useNodeHelpers();
|
||||
const i18n = useI18n();
|
||||
|
||||
const {
|
||||
hasPinnedData,
|
||||
|
@ -29,7 +31,7 @@ const hideNodeIssues = computed(() => false); // @TODO Implement this
|
|||
>
|
||||
<N8nTooltip :show-after="500" placement="bottom">
|
||||
<template #content>
|
||||
<TitledList :title="`${$locale.baseText('node.issues')}:`" :items="issues" />
|
||||
<TitledList :title="`${i18n.baseText('node.issues')}:`" :items="issues" />
|
||||
</template>
|
||||
<FontAwesomeIcon icon="exclamation-triangle" />
|
||||
</N8nTooltip>
|
||||
|
|
|
@ -16,7 +16,7 @@ const time = computed(() => {
|
|||
return '...';
|
||||
}
|
||||
const msPassed = nowTime.value - new Date(props.startTime).getTime();
|
||||
return i18n.displayTimer(msPassed); // Note: Adjust for $locale usage in setup
|
||||
return i18n.displayTimer(msPassed);
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
|
|
|
@ -6,10 +6,12 @@ import AnnotationTagsDropdown from '@/components/AnnotationTagsDropdown.ee.vue';
|
|||
import { createEventBus } from 'n8n-design-system';
|
||||
import VoteButtons from '@/components/executions/workflow/VoteButtons.vue';
|
||||
import { useToast } from '@/composables/useToast';
|
||||
import { useI18n } from '@/composables/useI18n';
|
||||
|
||||
const executionsStore = useExecutionsStore();
|
||||
|
||||
const { showError } = useToast();
|
||||
const i18n = useI18n();
|
||||
|
||||
const tagsEventBus = createEventBus();
|
||||
const isTagsEditEnabled = ref(false);
|
||||
|
@ -100,7 +102,7 @@ const onTagsEditEsc = () => {
|
|||
>
|
||||
<div :class="$style.section">
|
||||
<div :class="$style.vote">
|
||||
<div>{{ $locale.baseText('generic.rating') }}</div>
|
||||
<div>{{ i18n.baseText('generic.rating') }}</div>
|
||||
<VoteButtons :vote="vote" @vote-click="onVoteClick" />
|
||||
</div>
|
||||
<span :class="$style.tags" data-test-id="annotation-tags-container">
|
||||
|
@ -110,7 +112,7 @@ const onTagsEditEsc = () => {
|
|||
v-model="appliedTagIds"
|
||||
:create-enabled="true"
|
||||
:event-bus="tagsEventBus"
|
||||
:placeholder="$locale.baseText('executionAnnotationView.chooseOrCreateATag')"
|
||||
:placeholder="i18n.baseText('executionAnnotationView.chooseOrCreateATag')"
|
||||
class="tags-edit"
|
||||
data-test-id="workflow-tags-dropdown"
|
||||
@blur="onTagsBlur"
|
||||
|
@ -122,7 +124,7 @@ const onTagsEditEsc = () => {
|
|||
data-test-id="new-tag-link"
|
||||
@click="onTagsEditEnable"
|
||||
>
|
||||
+ {{ $locale.baseText('executionAnnotationView.addTag') }}
|
||||
+ {{ i18n.baseText('executionAnnotationView.addTag') }}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
|
@ -143,7 +145,7 @@ const onTagsEditEsc = () => {
|
|||
<span :class="$style.addTagWrapper">
|
||||
<n8n-button
|
||||
:class="$style.addTag"
|
||||
:label="`+ ` + $locale.baseText('executionAnnotationView.addTag')"
|
||||
:label="`+ ` + i18n.baseText('executionAnnotationView.addTag')"
|
||||
type="secondary"
|
||||
size="mini"
|
||||
:outline="false"
|
||||
|
@ -157,7 +159,7 @@ const onTagsEditEsc = () => {
|
|||
<div :class="$style.section">
|
||||
<div :class="$style.heading">
|
||||
<n8n-heading tag="h3" size="small" color="text-dark">
|
||||
{{ $locale.baseText('generic.annotationData') }}
|
||||
{{ i18n.baseText('generic.annotationData') }}
|
||||
</n8n-heading>
|
||||
</div>
|
||||
<div
|
||||
|
@ -179,7 +181,7 @@ const onTagsEditEsc = () => {
|
|||
</div>
|
||||
<div v-else :class="$style.noResultsContainer" data-test-id="execution-annotation-data-empty">
|
||||
<n8n-text color="text-base" size="small" align="center">
|
||||
<span v-n8n-html="$locale.baseText('executionAnnotationView.data.notFound')" />
|
||||
<span v-n8n-html="i18n.baseText('executionAnnotationView.data.notFound')" />
|
||||
</n8n-text>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -26,6 +26,7 @@ const props = withDefaults(
|
|||
},
|
||||
);
|
||||
|
||||
const i18n = useI18n();
|
||||
const router = useRouter();
|
||||
const workflowHelpers = useWorkflowHelpers({ router });
|
||||
const locale = useI18n();
|
||||
|
@ -190,7 +191,7 @@ async function onSaveWorkflowClick(): Promise<void> {
|
|||
<template>
|
||||
<N8nInfoAccordion
|
||||
:class="[$style.accordion, 'mt-2xl']"
|
||||
:title="$locale.baseText('executionsLandingPage.emptyState.accordion.title')"
|
||||
:title="i18n.baseText('executionsLandingPage.emptyState.accordion.title')"
|
||||
:items="accordionItems"
|
||||
:initially-expanded="shouldExpandAccordion"
|
||||
:header-icon="accordionIcon"
|
||||
|
@ -199,16 +200,14 @@ async function onSaveWorkflowClick(): Promise<void> {
|
|||
>
|
||||
<template #customContent>
|
||||
<footer class="mt-2xs">
|
||||
{{ $locale.baseText('executionsLandingPage.emptyState.accordion.footer') }}
|
||||
{{ i18n.baseText('executionsLandingPage.emptyState.accordion.footer') }}
|
||||
<N8nTooltip :disabled="!isNewWorkflow">
|
||||
<template #content>
|
||||
<div>
|
||||
<N8nLink @click.prevent="onSaveWorkflowClick">{{
|
||||
$locale.baseText('executionsLandingPage.emptyState.accordion.footer.tooltipLink')
|
||||
i18n.baseText('executionsLandingPage.emptyState.accordion.footer.tooltipLink')
|
||||
}}</N8nLink>
|
||||
{{
|
||||
$locale.baseText('executionsLandingPage.emptyState.accordion.footer.tooltipText')
|
||||
}}
|
||||
{{ i18n.baseText('executionsLandingPage.emptyState.accordion.footer.tooltipText') }}
|
||||
</div>
|
||||
</template>
|
||||
<N8nLink
|
||||
|
@ -216,7 +215,7 @@ async function onSaveWorkflowClick(): Promise<void> {
|
|||
size="small"
|
||||
@click.prevent="openWorkflowSettings"
|
||||
>
|
||||
{{ $locale.baseText('executionsLandingPage.emptyState.accordion.footer.settingsLink') }}
|
||||
{{ i18n.baseText('executionsLandingPage.emptyState.accordion.footer.settingsLink') }}
|
||||
</N8nLink>
|
||||
</N8nTooltip>
|
||||
</footer>
|
||||
|
|
|
@ -12,6 +12,7 @@ import { useExecutionsStore } from '@/stores/executions.store';
|
|||
import type { ExecutionFilterType, IWorkflowDb } from '@/Interface';
|
||||
import { isComponentPublicInstance } from '@/utils/typeGuards';
|
||||
import { getResourcePermissions } from '@/permissions';
|
||||
import { useI18n } from '@/composables/useI18n';
|
||||
|
||||
type AutoScrollDeps = { activeExecutionSet: boolean; cardsMounted: boolean; scroll: boolean };
|
||||
|
||||
|
@ -32,6 +33,7 @@ const emit = defineEmits<{
|
|||
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
const i18n = useI18n();
|
||||
|
||||
const executionsStore = useExecutionsStore();
|
||||
|
||||
|
@ -170,7 +172,7 @@ function scrollToActiveCard(): void {
|
|||
>
|
||||
<div :class="$style.heading">
|
||||
<n8n-heading tag="h2" size="medium" color="text-dark">
|
||||
{{ $locale.baseText('generic.executions') }}
|
||||
{{ i18n.baseText('generic.executions') }}
|
||||
</n8n-heading>
|
||||
</div>
|
||||
<div :class="$style.controls">
|
||||
|
@ -179,7 +181,7 @@ function scrollToActiveCard(): void {
|
|||
data-test-id="auto-refresh-checkbox"
|
||||
@update:model-value="onAutoRefreshChange"
|
||||
>
|
||||
{{ $locale.baseText('executionsList.autoRefresh') }}
|
||||
{{ i18n.baseText('executionsList.autoRefresh') }}
|
||||
</el-checkbox>
|
||||
<ExecutionsFilter popover-placement="left-start" @filter-changed="onFilterChanged" />
|
||||
</div>
|
||||
|
@ -198,7 +200,7 @@ function scrollToActiveCard(): void {
|
|||
data-test-id="execution-list-empty"
|
||||
>
|
||||
<n8n-text color="text-base" size="medium" align="center">
|
||||
{{ $locale.baseText('executionsLandingPage.noResults') }}
|
||||
{{ i18n.baseText('executionsLandingPage.noResults') }}
|
||||
</n8n-text>
|
||||
</div>
|
||||
<WorkflowExecutionsCard
|
||||
|
|
|
@ -21,7 +21,7 @@ import App from '@/App.vue';
|
|||
import router from './router';
|
||||
|
||||
import { TelemetryPlugin } from './plugins/telemetry';
|
||||
import { I18nPlugin, i18nInstance } from './plugins/i18n';
|
||||
import { i18nInstance } from './plugins/i18n';
|
||||
import { GlobalComponentsPlugin } from './plugins/components';
|
||||
import { GlobalDirectivesPlugin } from './plugins/directives';
|
||||
import { FontAwesomePlugin } from './plugins/icons';
|
||||
|
@ -38,7 +38,6 @@ const app = createApp(App);
|
|||
app.use(SentryPlugin);
|
||||
app.use(TelemetryPlugin);
|
||||
app.use(PiniaVuePlugin);
|
||||
app.use(I18nPlugin);
|
||||
app.use(FontAwesomePlugin);
|
||||
app.use(GlobalComponentsPlugin);
|
||||
app.use(GlobalDirectivesPlugin);
|
||||
|
|
|
@ -72,7 +72,7 @@ The base text file for each locale is located at `/packages/editor-ui/src/plugin
|
|||
cp ./packages/editor-ui/src/plugins/i18n/locales/en.json ./packages/editor-ui/src/plugins/i18n/locales/de.json
|
||||
```
|
||||
|
||||
2. Find in the UI a string to translate, and search for it in the newly created base text file. Alternatively, find in `/editor-ui` a call to `$locale.baseText(key)`, e.g. `$locale.baseText('workflowActivator.deactivateWorkflow')`, and take note of the key and find it in the newly created base text file.
|
||||
2. Find in the UI a string to translate, and search for it in the newly created base text file. Alternatively, find in `/editor-ui` a call to `i18n.baseText(key)`, e.g. `i18n.baseText('workflowActivator.deactivateWorkflow')`, and take note of the key and find it in the newly created base text file.
|
||||
|
||||
> **Note**: If you cannot find a string in the new base text file, either it does not belong to base text (i.e., the string might be part of header text, credential text, or node text), or the string might belong to the backend, where i18n is currently unsupported.
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import type { Plugin } from 'vue';
|
||||
import axios from 'axios';
|
||||
import { createI18n } from 'vue-i18n';
|
||||
import { locale, type N8nLocaleTranslateFn } from 'n8n-design-system';
|
||||
import { locale } from 'n8n-design-system';
|
||||
import type { INodeProperties, INodePropertyCollection, INodePropertyOptions } from 'n8n-workflow';
|
||||
|
||||
import type { INodeTranslationHeaders } from '@/Interface';
|
||||
|
@ -437,17 +436,6 @@ export function addHeaders(headers: INodeTranslationHeaders, language: string) {
|
|||
|
||||
export const i18n: I18nClass = new I18nClass();
|
||||
|
||||
export const I18nPlugin: Plugin = {
|
||||
async install(app) {
|
||||
locale.i18n(((key: string, options?: BaseTextOptions) =>
|
||||
i18nInstance.global.t(key, options?.interpolate ?? {})) as N8nLocaleTranslateFn);
|
||||
|
||||
app.config.globalProperties.$locale = i18n;
|
||||
|
||||
await locale.use('en');
|
||||
},
|
||||
};
|
||||
|
||||
// ----------------------------------
|
||||
// typings
|
||||
// ----------------------------------
|
||||
|
|
1
packages/editor-ui/src/shims-vue.d.ts
vendored
1
packages/editor-ui/src/shims-vue.d.ts
vendored
|
@ -21,7 +21,6 @@ declare module '@vue/runtime-core' {
|
|||
|
||||
interface ComponentCustomProperties {
|
||||
$style: Record<string, string>;
|
||||
$locale: I18nClass;
|
||||
$telemetry: Telemetry;
|
||||
$route: RouteLocation;
|
||||
$router: Router;
|
||||
|
|
|
@ -2,12 +2,15 @@
|
|||
import { computed } from 'vue';
|
||||
import type { XYPosition } from '@/Interface';
|
||||
import { useNodeCreatorStore } from '@/stores/nodeCreator.store';
|
||||
import { useI18n } from '@/composables/useI18n';
|
||||
|
||||
export interface Props {
|
||||
showTooltip: boolean;
|
||||
position: XYPosition;
|
||||
}
|
||||
|
||||
const i18n = useI18n();
|
||||
|
||||
const props = defineProps<Props>();
|
||||
|
||||
const nodeCreatorStore = useNodeCreatorStore();
|
||||
|
@ -35,10 +38,10 @@ const containerCssVars = computed(() => ({
|
|||
<font-awesome-icon icon="plus" size="lg" />
|
||||
</button>
|
||||
<template #content>
|
||||
{{ $locale.baseText('nodeView.canvasAddButton.addATriggerNodeBeforeExecuting') }}
|
||||
{{ i18n.baseText('nodeView.canvasAddButton.addATriggerNodeBeforeExecuting') }}
|
||||
</template>
|
||||
</n8n-tooltip>
|
||||
<p :class="$style.label" v-text="$locale.baseText('nodeView.canvasAddButton.addFirstStep')" />
|
||||
<p :class="$style.label" v-text="i18n.baseText('nodeView.canvasAddButton.addFirstStep')" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
import type { BaseTextKey } from '@/plugins/i18n';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { VIEWS } from '@/constants';
|
||||
import { useI18n } from '@/composables/useI18n';
|
||||
const router = useRouter();
|
||||
|
||||
const props = defineProps<{
|
||||
|
@ -11,6 +12,8 @@ const props = defineProps<{
|
|||
redirectPage?: keyof typeof VIEWS;
|
||||
}>();
|
||||
|
||||
const i18n = useI18n();
|
||||
|
||||
function onButtonClick() {
|
||||
void router.push({ name: props.redirectPage ?? VIEWS.HOMEPAGE });
|
||||
}
|
||||
|
@ -22,16 +25,16 @@ function onButtonClick() {
|
|||
<div :class="$style.message">
|
||||
<div>
|
||||
<n8n-heading size="2xlarge">
|
||||
{{ $locale.baseText(messageKey) }}
|
||||
{{ i18n.baseText(messageKey) }}
|
||||
</n8n-heading>
|
||||
</div>
|
||||
<div>
|
||||
<n8n-text v-if="errorCode" size="large">
|
||||
{{ errorCode }} {{ $locale.baseText('error') }}
|
||||
{{ errorCode }} {{ i18n.baseText('error') }}
|
||||
</n8n-text>
|
||||
</div>
|
||||
</div>
|
||||
<n8n-button :label="$locale.baseText(redirectTextKey)" @click="onButtonClick" />
|
||||
<n8n-button :label="i18n.baseText(redirectTextKey)" @click="onButtonClick" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
|
|
@ -221,7 +221,7 @@ export default defineComponent({
|
|||
|
||||
const ndvStore = useNDVStore();
|
||||
const externalHooks = useExternalHooks();
|
||||
const locale = useI18n();
|
||||
const i18n = useI18n();
|
||||
const contextMenu = useContextMenu();
|
||||
const dataSchema = useDataSchema();
|
||||
const nodeHelpers = useNodeHelpers();
|
||||
|
@ -240,7 +240,7 @@ export default defineComponent({
|
|||
});
|
||||
|
||||
return {
|
||||
locale,
|
||||
i18n,
|
||||
contextMenu,
|
||||
dataSchema,
|
||||
nodeHelpers,
|
||||
|
@ -366,14 +366,14 @@ export default defineComponent({
|
|||
},
|
||||
runButtonText(): string {
|
||||
if (!this.workflowRunning) {
|
||||
return this.$locale.baseText('nodeView.runButtonText.executeWorkflow');
|
||||
return this.i18n.baseText('nodeView.runButtonText.executeWorkflow');
|
||||
}
|
||||
|
||||
if (this.executionWaitingForWebhook) {
|
||||
return this.$locale.baseText('nodeView.runButtonText.waitingForTriggerEvent');
|
||||
return this.i18n.baseText('nodeView.runButtonText.waitingForTriggerEvent');
|
||||
}
|
||||
|
||||
return this.$locale.baseText('nodeView.runButtonText.executingWorkflow');
|
||||
return this.i18n.baseText('nodeView.runButtonText.executingWorkflow');
|
||||
},
|
||||
workflowStyle() {
|
||||
const offsetPosition = this.uiStore.nodeViewOffsetPosition;
|
||||
|
@ -589,8 +589,8 @@ export default defineComponent({
|
|||
if (!this.nodeViewRef) {
|
||||
this.showError(
|
||||
new Error('NodeView reference not found'),
|
||||
this.$locale.baseText('nodeView.showError.mounted1.title'),
|
||||
this.$locale.baseText('nodeView.showError.mounted1.message') + ':',
|
||||
this.i18n.baseText('nodeView.showError.mounted1.title'),
|
||||
this.i18n.baseText('nodeView.showError.mounted1.message') + ':',
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
@ -624,8 +624,8 @@ export default defineComponent({
|
|||
} catch (error) {
|
||||
this.showError(
|
||||
error,
|
||||
this.$locale.baseText('nodeView.showError.mounted1.title'),
|
||||
this.$locale.baseText('nodeView.showError.mounted1.message') + ':',
|
||||
this.i18n.baseText('nodeView.showError.mounted1.title'),
|
||||
this.i18n.baseText('nodeView.showError.mounted1.message') + ':',
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
@ -645,8 +645,8 @@ export default defineComponent({
|
|||
} catch (error) {
|
||||
this.showError(
|
||||
error,
|
||||
this.$locale.baseText('nodeView.showError.mounted2.title'),
|
||||
this.$locale.baseText('nodeView.showError.mounted2.message') + ':',
|
||||
this.i18n.baseText('nodeView.showError.mounted2.title'),
|
||||
this.i18n.baseText('nodeView.showError.mounted2.message') + ':',
|
||||
);
|
||||
}
|
||||
this.canvasStore.stopLoading();
|
||||
|
@ -814,12 +814,12 @@ export default defineComponent({
|
|||
}
|
||||
if (this.isReadOnlyRoute || this.readOnlyEnv) {
|
||||
this.readOnlyNotification = this.showMessage({
|
||||
title: this.$locale.baseText(
|
||||
title: this.i18n.baseText(
|
||||
this.readOnlyEnv
|
||||
? `readOnlyEnv.showMessage.${this.isReadOnlyRoute ? 'executions' : 'workflows'}.title`
|
||||
: 'readOnly.showMessage.executions.title',
|
||||
),
|
||||
message: this.$locale.baseText(
|
||||
message: this.i18n.baseText(
|
||||
this.readOnlyEnv
|
||||
? `readOnlyEnv.showMessage.${
|
||||
this.isReadOnlyRoute ? 'executions' : 'workflows'
|
||||
|
@ -931,12 +931,12 @@ export default defineComponent({
|
|||
|
||||
const message =
|
||||
this.containsTrigger && this.allTriggersDisabled
|
||||
? this.$locale.baseText('nodeView.addOrEnableTriggerNode')
|
||||
: this.$locale.baseText('nodeView.addATriggerNodeFirst');
|
||||
? this.i18n.baseText('nodeView.addOrEnableTriggerNode')
|
||||
: this.i18n.baseText('nodeView.addATriggerNodeFirst');
|
||||
|
||||
const notice = this.showMessage({
|
||||
type: 'info',
|
||||
title: this.$locale.baseText('nodeView.cantExecuteNoTrigger'),
|
||||
title: this.i18n.baseText('nodeView.cantExecuteNoTrigger'),
|
||||
message,
|
||||
duration: 3000,
|
||||
onClick: () =>
|
||||
|
@ -973,7 +973,7 @@ export default defineComponent({
|
|||
}
|
||||
if (saved) {
|
||||
this.showMessage({
|
||||
title: this.$locale.baseText('generic.workflowSaved'),
|
||||
title: this.i18n.baseText('generic.workflowSaved'),
|
||||
type: 'success',
|
||||
});
|
||||
}
|
||||
|
@ -1001,7 +1001,7 @@ export default defineComponent({
|
|||
try {
|
||||
data = await this.workflowsStore.getExecution(executionId);
|
||||
} catch (error) {
|
||||
this.showError(error, this.$locale.baseText('nodeView.showError.openExecution.title'));
|
||||
this.showError(error, this.i18n.baseText('nodeView.showError.openExecution.title'));
|
||||
return;
|
||||
}
|
||||
if (data === undefined) {
|
||||
|
@ -1069,7 +1069,7 @@ export default defineComponent({
|
|||
console.error(`Execution ${executionId} error:`);
|
||||
console.error(data.data.resultData.error.stack);
|
||||
this.showMessage({
|
||||
title: this.$locale.baseText('nodeView.showError.workflowError'),
|
||||
title: this.i18n.baseText('nodeView.showError.workflowError'),
|
||||
message: data.data.resultData.error.message,
|
||||
type: 'error',
|
||||
duration: 0,
|
||||
|
@ -1078,7 +1078,7 @@ export default defineComponent({
|
|||
}
|
||||
if ((data as ExecutionSummary).waitTill) {
|
||||
this.showMessage({
|
||||
title: this.$locale.baseText('nodeView.thisExecutionHasntFinishedYet'),
|
||||
title: this.i18n.baseText('nodeView.thisExecutionHasntFinishedYet'),
|
||||
message: h(NodeViewUnfinishedWorkflowMessage),
|
||||
type: 'warning',
|
||||
duration: 0,
|
||||
|
@ -1103,7 +1103,7 @@ export default defineComponent({
|
|||
},
|
||||
async openWorkflowTemplate(templateId: string) {
|
||||
this.canvasStore.startLoading();
|
||||
this.canvasStore.setLoadingText(this.$locale.baseText('nodeView.loadingTemplate'));
|
||||
this.canvasStore.setLoadingText(this.i18n.baseText('nodeView.loadingTemplate'));
|
||||
this.resetWorkspace();
|
||||
|
||||
this.workflowsStore.currentWorkflowExecutions = [];
|
||||
|
@ -1116,13 +1116,13 @@ export default defineComponent({
|
|||
|
||||
if (!data) {
|
||||
throw new Error(
|
||||
this.$locale.baseText('nodeView.workflowTemplateWithIdCouldNotBeFound', {
|
||||
this.i18n.baseText('nodeView.workflowTemplateWithIdCouldNotBeFound', {
|
||||
interpolate: { templateId },
|
||||
}),
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
this.showError(error, this.$locale.baseText('nodeView.couldntImportWorkflow'));
|
||||
this.showError(error, this.i18n.baseText('nodeView.couldntImportWorkflow'));
|
||||
await this.$router.replace({ name: VIEWS.NEW_WORKFLOW });
|
||||
return;
|
||||
}
|
||||
|
@ -1367,7 +1367,7 @@ export default defineComponent({
|
|||
}
|
||||
|
||||
this.showMessage({
|
||||
title: this.$locale.baseText('nodeView.showMessage.keyDown.title'),
|
||||
title: this.i18n.baseText('nodeView.showMessage.keyDown.title'),
|
||||
type: 'success',
|
||||
});
|
||||
} else if (e.key === 'Enter' && noModifierKeys) {
|
||||
|
@ -1699,7 +1699,7 @@ export default defineComponent({
|
|||
if (data.nodes.length > 0) {
|
||||
if (!isCut) {
|
||||
this.showMessage({
|
||||
title: this.$locale.baseText('generic.copiedToClipboard'),
|
||||
title: this.i18n.baseText('generic.copiedToClipboard'),
|
||||
message: '',
|
||||
type: 'success',
|
||||
});
|
||||
|
@ -1732,10 +1732,8 @@ export default defineComponent({
|
|||
|
||||
this.workflowHelpers.setDocumentTitle(this.workflowsStore.workflowName, 'IDLE');
|
||||
this.showMessage({
|
||||
title: this.$locale.baseText('nodeView.showMessage.stopExecutionCatch.unsaved.title'),
|
||||
message: this.$locale.baseText(
|
||||
'nodeView.showMessage.stopExecutionCatch.unsaved.message',
|
||||
),
|
||||
title: this.i18n.baseText('nodeView.showMessage.stopExecutionCatch.unsaved.title'),
|
||||
message: this.i18n.baseText('nodeView.showMessage.stopExecutionCatch.unsaved.message'),
|
||||
type: 'success',
|
||||
});
|
||||
} else if (execution?.finished) {
|
||||
|
@ -1753,12 +1751,12 @@ export default defineComponent({
|
|||
this.workflowsStore.setWorkflowExecutionData(executedData as IExecutionResponse);
|
||||
this.uiStore.removeActiveAction('workflowRunning');
|
||||
this.showMessage({
|
||||
title: this.$locale.baseText('nodeView.showMessage.stopExecutionCatch.title'),
|
||||
message: this.$locale.baseText('nodeView.showMessage.stopExecutionCatch.message'),
|
||||
title: this.i18n.baseText('nodeView.showMessage.stopExecutionCatch.title'),
|
||||
message: this.i18n.baseText('nodeView.showMessage.stopExecutionCatch.message'),
|
||||
type: 'success',
|
||||
});
|
||||
} else {
|
||||
this.showError(error, this.$locale.baseText('nodeView.showError.stopExecution.title'));
|
||||
this.showError(error, this.i18n.baseText('nodeView.showError.stopExecution.title'));
|
||||
}
|
||||
}
|
||||
this.stopExecutionInProgress = false;
|
||||
|
@ -1782,10 +1780,7 @@ export default defineComponent({
|
|||
try {
|
||||
await this.workflowsStore.removeTestWebhook(this.workflowsStore.workflowId);
|
||||
} catch (error) {
|
||||
this.showError(
|
||||
error,
|
||||
this.$locale.baseText('nodeView.showError.stopWaitingForWebhook.title'),
|
||||
);
|
||||
this.showError(error, this.i18n.baseText('nodeView.showError.stopWaitingForWebhook.title'));
|
||||
return;
|
||||
}
|
||||
},
|
||||
|
@ -1816,16 +1811,16 @@ export default defineComponent({
|
|||
}
|
||||
|
||||
const importConfirm = await this.confirm(
|
||||
this.$locale.baseText('nodeView.confirmMessage.onClipboardPasteEvent.message', {
|
||||
this.i18n.baseText('nodeView.confirmMessage.onClipboardPasteEvent.message', {
|
||||
interpolate: { plainTextData },
|
||||
}),
|
||||
this.$locale.baseText('nodeView.confirmMessage.onClipboardPasteEvent.headline'),
|
||||
this.i18n.baseText('nodeView.confirmMessage.onClipboardPasteEvent.headline'),
|
||||
{
|
||||
type: 'warning',
|
||||
confirmButtonText: this.$locale.baseText(
|
||||
confirmButtonText: this.i18n.baseText(
|
||||
'nodeView.confirmMessage.onClipboardPasteEvent.confirmButtonText',
|
||||
),
|
||||
cancelButtonText: this.$locale.baseText(
|
||||
cancelButtonText: this.i18n.baseText(
|
||||
'nodeView.confirmMessage.onClipboardPasteEvent.cancelButtonText',
|
||||
),
|
||||
dangerouslyUseHTMLString: true,
|
||||
|
@ -1875,7 +1870,7 @@ export default defineComponent({
|
|||
this.canvasStore.stopLoading();
|
||||
this.showError(
|
||||
error,
|
||||
this.$locale.baseText('nodeView.showError.getWorkflowDataFromUrl.title'),
|
||||
this.i18n.baseText('nodeView.showError.getWorkflowDataFromUrl.title'),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
@ -2025,7 +2020,7 @@ export default defineComponent({
|
|||
});
|
||||
}
|
||||
} catch (error) {
|
||||
this.showError(error, this.$locale.baseText('nodeView.showError.importWorkflowData.title'));
|
||||
this.showError(error, this.i18n.baseText('nodeView.showError.importWorkflowData.title'));
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -2098,8 +2093,8 @@ export default defineComponent({
|
|||
showMaxNodeTypeError(nodeTypeData: INodeTypeDescription) {
|
||||
const maxNodes = nodeTypeData.maxNodes;
|
||||
this.showMessage({
|
||||
title: this.$locale.baseText('nodeView.showMessage.showMaxNodeTypeError.title'),
|
||||
message: this.$locale.baseText('nodeView.showMessage.showMaxNodeTypeError.message', {
|
||||
title: this.i18n.baseText('nodeView.showMessage.showMaxNodeTypeError.title'),
|
||||
message: this.i18n.baseText('nodeView.showMessage.showMaxNodeTypeError.message', {
|
||||
adjustToNumber: maxNodes,
|
||||
interpolate: { nodeTypeDataDisplayName: nodeTypeData.displayName },
|
||||
}),
|
||||
|
@ -2206,8 +2201,8 @@ export default defineComponent({
|
|||
|
||||
if (nodeTypeData === null) {
|
||||
this.showMessage({
|
||||
title: this.$locale.baseText('nodeView.showMessage.addNodeButton.title'),
|
||||
message: this.$locale.baseText('nodeView.showMessage.addNodeButton.message', {
|
||||
title: this.i18n.baseText('nodeView.showMessage.addNodeButton.title'),
|
||||
message: this.i18n.baseText('nodeView.showMessage.addNodeButton.message', {
|
||||
interpolate: { nodeTypeName },
|
||||
}),
|
||||
type: 'error',
|
||||
|
@ -2374,7 +2369,7 @@ export default defineComponent({
|
|||
newNodeData.position = NodeViewUtils.getNewNodePosition(this.nodes, position);
|
||||
}
|
||||
|
||||
const localizedName = this.locale.localizeNodeName(newNodeData.name, newNodeData.type);
|
||||
const localizedName = this.i18n.localizeNodeName(newNodeData.name, newNodeData.type);
|
||||
|
||||
newNodeData.name = this.uniqueNodeName(localizedName);
|
||||
|
||||
|
@ -2725,8 +2720,8 @@ export default defineComponent({
|
|||
if (!input.filter.nodes.includes(sourceNode.type)) {
|
||||
this.dropPrevented = true;
|
||||
this.showToast({
|
||||
title: this.$locale.baseText('nodeView.showError.nodeNodeCompatible.title'),
|
||||
message: this.$locale.baseText('nodeView.showError.nodeNodeCompatible.message', {
|
||||
title: this.i18n.baseText('nodeView.showError.nodeNodeCompatible.title'),
|
||||
message: this.i18n.baseText('nodeView.showError.nodeNodeCompatible.message', {
|
||||
interpolate: { sourceNodeName: sourceNode.name, targetNodeName: targetNode.name },
|
||||
}),
|
||||
type: 'error',
|
||||
|
@ -3376,14 +3371,14 @@ export default defineComponent({
|
|||
(this.workflowPermissions.update ?? this.projectPermissions.workflow.update)
|
||||
) {
|
||||
const confirmModal = await this.confirm(
|
||||
this.$locale.baseText('generic.unsavedWork.confirmMessage.message'),
|
||||
this.i18n.baseText('generic.unsavedWork.confirmMessage.message'),
|
||||
{
|
||||
title: this.$locale.baseText('generic.unsavedWork.confirmMessage.headline'),
|
||||
title: this.i18n.baseText('generic.unsavedWork.confirmMessage.headline'),
|
||||
type: 'warning',
|
||||
confirmButtonText: this.$locale.baseText(
|
||||
confirmButtonText: this.i18n.baseText(
|
||||
'generic.unsavedWork.confirmMessage.confirmButtonText',
|
||||
),
|
||||
cancelButtonText: this.$locale.baseText(
|
||||
cancelButtonText: this.i18n.baseText(
|
||||
'generic.unsavedWork.confirmMessage.cancelButtonText',
|
||||
),
|
||||
showClose: true,
|
||||
|
@ -3406,7 +3401,7 @@ export default defineComponent({
|
|||
try {
|
||||
workflow = await this.workflowsStore.fetchWorkflow(workflowId);
|
||||
} catch (error) {
|
||||
this.showError(error, this.$locale.baseText('openWorkflow.workflowNotFoundError'));
|
||||
this.showError(error, this.i18n.baseText('openWorkflow.workflowNotFoundError'));
|
||||
|
||||
void this.$router.push({
|
||||
name: VIEWS.NEW_WORKFLOW,
|
||||
|
@ -3704,17 +3699,17 @@ export default defineComponent({
|
|||
async renameNodePrompt(currentName: string) {
|
||||
try {
|
||||
const promptResponsePromise = this.prompt(
|
||||
this.$locale.baseText('nodeView.prompt.newName') + ':',
|
||||
this.$locale.baseText('nodeView.prompt.renameNode') + `: ${currentName}`,
|
||||
this.i18n.baseText('nodeView.prompt.newName') + ':',
|
||||
this.i18n.baseText('nodeView.prompt.renameNode') + `: ${currentName}`,
|
||||
{
|
||||
customClass: 'rename-prompt',
|
||||
confirmButtonText: this.$locale.baseText('nodeView.prompt.rename'),
|
||||
cancelButtonText: this.$locale.baseText('nodeView.prompt.cancel'),
|
||||
inputErrorMessage: this.$locale.baseText('nodeView.prompt.invalidName'),
|
||||
confirmButtonText: this.i18n.baseText('nodeView.prompt.rename'),
|
||||
cancelButtonText: this.i18n.baseText('nodeView.prompt.cancel'),
|
||||
inputErrorMessage: this.i18n.baseText('nodeView.prompt.invalidName'),
|
||||
inputValue: currentName,
|
||||
inputValidator: (value: string) => {
|
||||
if (!value.trim()) {
|
||||
return this.$locale.baseText('nodeView.prompt.invalidName');
|
||||
return this.i18n.baseText('nodeView.prompt.invalidName');
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
@ -3826,7 +3821,7 @@ export default defineComponent({
|
|||
|
||||
if (!data.nodes) {
|
||||
// No nodes to add
|
||||
throw new Error(this.$locale.baseText('nodeView.noNodesGivenToAdd'));
|
||||
throw new Error(this.i18n.baseText('nodeView.noNodesGivenToAdd'));
|
||||
}
|
||||
|
||||
// Get how many of the nodes of the types which have
|
||||
|
@ -3860,7 +3855,7 @@ export default defineComponent({
|
|||
|
||||
oldName = node.name;
|
||||
|
||||
const localized = this.locale.localizeNodeName(node.name, node.type);
|
||||
const localized = this.i18n.localizeNodeName(node.name, node.type);
|
||||
|
||||
newName = this.uniqueNodeName(localized, newNodeNames);
|
||||
|
||||
|
@ -3933,8 +3928,8 @@ export default defineComponent({
|
|||
// Pin data limit reached
|
||||
if (!pinDataSuccess) {
|
||||
this.showError(
|
||||
new Error(this.$locale.baseText('ndv.pinData.error.tooLarge.description')),
|
||||
this.$locale.baseText('ndv.pinData.error.tooLarge.title'),
|
||||
new Error(this.i18n.baseText('ndv.pinData.error.tooLarge.description')),
|
||||
this.i18n.baseText('ndv.pinData.error.tooLarge.title'),
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
@ -4142,13 +4137,13 @@ export default defineComponent({
|
|||
window.top.postMessage(
|
||||
JSON.stringify({
|
||||
command: 'error',
|
||||
message: this.$locale.baseText('openWorkflow.workflowImportError'),
|
||||
message: this.i18n.baseText('openWorkflow.workflowImportError'),
|
||||
}),
|
||||
'*',
|
||||
);
|
||||
}
|
||||
this.showMessage({
|
||||
title: this.$locale.baseText('openWorkflow.workflowImportError'),
|
||||
title: this.i18n.baseText('openWorkflow.workflowImportError'),
|
||||
message: (e as Error).message,
|
||||
type: 'error',
|
||||
});
|
||||
|
@ -4168,13 +4163,13 @@ export default defineComponent({
|
|||
window.top.postMessage(
|
||||
JSON.stringify({
|
||||
command: 'error',
|
||||
message: this.$locale.baseText('nodeView.showError.openExecution.title'),
|
||||
message: this.i18n.baseText('nodeView.showError.openExecution.title'),
|
||||
}),
|
||||
'*',
|
||||
);
|
||||
}
|
||||
this.showMessage({
|
||||
title: this.$locale.baseText('nodeView.showError.openExecution.title'),
|
||||
title: this.i18n.baseText('nodeView.showError.openExecution.title'),
|
||||
message: (e as Error).message,
|
||||
type: 'error',
|
||||
});
|
||||
|
@ -4539,7 +4534,7 @@ export default defineComponent({
|
|||
>
|
||||
<template #custom-tooltip>
|
||||
<span
|
||||
v-text="$locale.baseText('nodeView.canvasAddButton.addATriggerNodeBeforeExecuting')"
|
||||
v-text="i18n.baseText('nodeView.canvasAddButton.addATriggerNodeBeforeExecuting')"
|
||||
/>
|
||||
</template>
|
||||
</Node>
|
||||
|
@ -4655,8 +4650,8 @@ export default defineComponent({
|
|||
type="secondary"
|
||||
:title="
|
||||
stopExecutionInProgress
|
||||
? $locale.baseText('nodeView.stoppingCurrentExecution')
|
||||
: $locale.baseText('nodeView.stopCurrentExecution')
|
||||
? i18n.baseText('nodeView.stoppingCurrentExecution')
|
||||
: i18n.baseText('nodeView.stopCurrentExecution')
|
||||
"
|
||||
:loading="stopExecutionInProgress"
|
||||
data-test-id="stop-execution-button"
|
||||
|
@ -4668,7 +4663,7 @@ export default defineComponent({
|
|||
class="stop-execution"
|
||||
icon="stop"
|
||||
size="large"
|
||||
:title="$locale.baseText('nodeView.stopWaitingForWebhookCall')"
|
||||
:title="i18n.baseText('nodeView.stopWaitingForWebhookCall')"
|
||||
type="secondary"
|
||||
data-test-id="stop-execution-waiting-for-webhook-button"
|
||||
@click.stop="stopWaitingForWebhook"
|
||||
|
@ -4676,7 +4671,7 @@ export default defineComponent({
|
|||
|
||||
<n8n-icon-button
|
||||
v-if="workflowExecution && !workflowRunning && !allTriggersDisabled"
|
||||
:title="$locale.baseText('nodeView.deletesTheCurrentExecutionData')"
|
||||
:title="i18n.baseText('nodeView.deletesTheCurrentExecutionData')"
|
||||
icon="trash"
|
||||
size="large"
|
||||
data-test-id="clear-execution-data-button"
|
||||
|
|
|
@ -27,7 +27,7 @@ type FormDataDiff = {
|
|||
};
|
||||
|
||||
const usersStore = useUsersStore();
|
||||
const locale = useI18n();
|
||||
const i18n = useI18n();
|
||||
const projectsStore = useProjectsStore();
|
||||
const rolesStore = useRolesStore();
|
||||
const cloudPlanStore = useCloudPlanStore();
|
||||
|
@ -35,6 +35,7 @@ const toast = useToast();
|
|||
const router = useRouter();
|
||||
const telemetry = useTelemetry();
|
||||
const documentTitle = useDocumentTitle();
|
||||
|
||||
const dialogVisible = ref(false);
|
||||
const upgradeDialogVisible = ref(false);
|
||||
|
||||
|
@ -45,9 +46,9 @@ const formData = ref<Pick<Project, 'name' | 'relations'>>({
|
|||
relations: [],
|
||||
});
|
||||
const projectRoleTranslations = ref<{ [key: string]: string }>({
|
||||
'project:viewer': locale.baseText('projects.settings.role.viewer'),
|
||||
'project:editor': locale.baseText('projects.settings.role.editor'),
|
||||
'project:admin': locale.baseText('projects.settings.role.admin'),
|
||||
'project:viewer': i18n.baseText('projects.settings.role.viewer'),
|
||||
'project:editor': i18n.baseText('projects.settings.role.editor'),
|
||||
'project:admin': i18n.baseText('projects.settings.role.admin'),
|
||||
});
|
||||
const nameInput = ref<InstanceType<typeof N8nFormInput> | null>(null);
|
||||
|
||||
|
@ -192,14 +193,14 @@ const onSubmit = async () => {
|
|||
sendTelemetry(diff);
|
||||
isDirty.value = false;
|
||||
toast.showMessage({
|
||||
title: locale.baseText('projects.settings.save.successful.title', {
|
||||
title: i18n.baseText('projects.settings.save.successful.title', {
|
||||
interpolate: { projectName: formData.value.name ?? '' },
|
||||
}),
|
||||
type: 'success',
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
toast.showError(error, locale.baseText('projects.settings.save.error.title'));
|
||||
toast.showError(error, i18n.baseText('projects.settings.save.error.title'));
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -215,7 +216,7 @@ const onConfirmDelete = async (transferId?: string) => {
|
|||
await projectsStore.deleteProject(projectsStore.currentProject.id, transferId);
|
||||
await router.push({ name: VIEWS.HOMEPAGE });
|
||||
toast.showMessage({
|
||||
title: locale.baseText('projects.settings.delete.successful.title', {
|
||||
title: i18n.baseText('projects.settings.delete.successful.title', {
|
||||
interpolate: { projectName },
|
||||
}),
|
||||
type: 'success',
|
||||
|
@ -223,12 +224,12 @@ const onConfirmDelete = async (transferId?: string) => {
|
|||
dialogVisible.value = true;
|
||||
}
|
||||
} catch (error) {
|
||||
toast.showError(error, locale.baseText('projects.settings.delete.error.title'));
|
||||
toast.showError(error, i18n.baseText('projects.settings.delete.error.title'));
|
||||
}
|
||||
};
|
||||
|
||||
const selectProjectNameIfMatchesDefault = () => {
|
||||
if (formData.value.name === locale.baseText('projects.settings.newProjectName')) {
|
||||
if (formData.value.name === i18n.baseText('projects.settings.newProjectName')) {
|
||||
nameInput.value?.inputRef?.focus();
|
||||
nameInput.value?.inputRef?.select();
|
||||
}
|
||||
|
@ -252,7 +253,7 @@ onBeforeMount(async () => {
|
|||
});
|
||||
|
||||
onMounted(() => {
|
||||
documentTitle.set(locale.baseText('projects.settings'));
|
||||
documentTitle.set(i18n.baseText('projects.settings'));
|
||||
selectProjectNameIfMatchesDefault();
|
||||
});
|
||||
</script>
|
||||
|
@ -264,7 +265,7 @@ onMounted(() => {
|
|||
</div>
|
||||
<form @submit.prevent="onSubmit">
|
||||
<fieldset>
|
||||
<label for="projectName">{{ locale.baseText('projects.settings.name') }}</label>
|
||||
<label for="projectName">{{ i18n.baseText('projects.settings.name') }}</label>
|
||||
<N8nFormInput
|
||||
id="projectName"
|
||||
ref="nameInput"
|
||||
|
@ -279,16 +280,14 @@ onMounted(() => {
|
|||
/>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<label for="projectMembers">{{
|
||||
locale.baseText('projects.settings.projectMembers')
|
||||
}}</label>
|
||||
<label for="projectMembers">{{ i18n.baseText('projects.settings.projectMembers') }}</label>
|
||||
<N8nUserSelect
|
||||
id="projectMembers"
|
||||
class="mb-s"
|
||||
size="large"
|
||||
:users="usersList"
|
||||
:current-user-id="usersStore.currentUser?.id"
|
||||
:placeholder="$locale.baseText('workflows.shareModal.select.placeholder')"
|
||||
:placeholder="i18n.baseText('workflows.shareModal.select.placeholder')"
|
||||
data-test-id="project-members-select"
|
||||
@update:model-value="onAddMember"
|
||||
>
|
||||
|
@ -300,7 +299,7 @@ onMounted(() => {
|
|||
:actions="[]"
|
||||
:users="formData.relations"
|
||||
:current-user-id="usersStore.currentUser?.id"
|
||||
:delete-label="$locale.baseText('workflows.shareModal.list.delete')"
|
||||
:delete-label="i18n.baseText('workflows.shareModal.list.delete')"
|
||||
>
|
||||
<template #actions="{ user }">
|
||||
<div :class="$style.buttons">
|
||||
|
@ -324,7 +323,7 @@ onMounted(() => {
|
|||
:class="$style.upgrade"
|
||||
@click="upgradeDialogVisible = true"
|
||||
>
|
||||
- {{ locale.baseText('generic.upgrade') }}
|
||||
- {{ i18n.baseText('generic.upgrade') }}
|
||||
</span>
|
||||
</N8nOption>
|
||||
</N8nSelect>
|
||||
|
@ -343,7 +342,7 @@ onMounted(() => {
|
|||
<fieldset :class="$style.buttons">
|
||||
<div>
|
||||
<small v-if="isDirty" class="mr-2xs">{{
|
||||
locale.baseText('projects.settings.message.unsavedChanges')
|
||||
i18n.baseText('projects.settings.message.unsavedChanges')
|
||||
}}</small>
|
||||
<N8nButton
|
||||
:disabled="!isDirty"
|
||||
|
@ -352,20 +351,20 @@ onMounted(() => {
|
|||
class="mr-2xs"
|
||||
data-test-id="project-settings-cancel-button"
|
||||
@click.stop.prevent="onCancel"
|
||||
>{{ locale.baseText('projects.settings.button.cancel') }}</N8nButton
|
||||
>{{ i18n.baseText('projects.settings.button.cancel') }}</N8nButton
|
||||
>
|
||||
</div>
|
||||
<N8nButton
|
||||
:disabled="!isDirty || !isValid"
|
||||
type="primary"
|
||||
data-test-id="project-settings-save-button"
|
||||
>{{ locale.baseText('projects.settings.button.save') }}</N8nButton
|
||||
>{{ i18n.baseText('projects.settings.button.save') }}</N8nButton
|
||||
>
|
||||
</fieldset>
|
||||
<fieldset>
|
||||
<hr class="mb-2xl" />
|
||||
<h3 class="mb-xs">{{ locale.baseText('projects.settings.danger.title') }}</h3>
|
||||
<small>{{ locale.baseText('projects.settings.danger.message') }}</small>
|
||||
<h3 class="mb-xs">{{ i18n.baseText('projects.settings.danger.title') }}</h3>
|
||||
<small>{{ i18n.baseText('projects.settings.danger.message') }}</small>
|
||||
<br />
|
||||
<N8nButton
|
||||
type="tertiary"
|
||||
|
@ -373,7 +372,7 @@ onMounted(() => {
|
|||
class="mt-s"
|
||||
data-test-id="project-settings-delete-button"
|
||||
@click.stop.prevent="onDelete"
|
||||
>{{ locale.baseText('projects.settings.danger.deleteProject') }}</N8nButton
|
||||
>{{ i18n.baseText('projects.settings.danger.deleteProject') }}</N8nButton
|
||||
>
|
||||
</fieldset>
|
||||
</form>
|
||||
|
|
|
@ -292,7 +292,7 @@ onMounted(() => {
|
|||
data-test-id="resources-list-add"
|
||||
@click="addTemporaryVariable"
|
||||
>
|
||||
{{ $locale.baseText(`variables.add`) }}
|
||||
{{ i18n.baseText(`variables.add`) }}
|
||||
</n8n-button>
|
||||
</div>
|
||||
<template #content>
|
||||
|
@ -309,15 +309,15 @@ onMounted(() => {
|
|||
data-test-id="unavailable-resources-list"
|
||||
emoji="👋"
|
||||
:heading="
|
||||
$locale.baseText(contextBasedTranslationKeys.variables.unavailable.title as BaseTextKey)
|
||||
i18n.baseText(contextBasedTranslationKeys.variables.unavailable.title as BaseTextKey)
|
||||
"
|
||||
:description="
|
||||
$locale.baseText(
|
||||
i18n.baseText(
|
||||
contextBasedTranslationKeys.variables.unavailable.description as BaseTextKey,
|
||||
)
|
||||
"
|
||||
:button-text="
|
||||
$locale.baseText(contextBasedTranslationKeys.variables.unavailable.button as BaseTextKey)
|
||||
i18n.baseText(contextBasedTranslationKeys.variables.unavailable.button as BaseTextKey)
|
||||
"
|
||||
button-type="secondary"
|
||||
@click:button="goToUpgrade"
|
||||
|
@ -329,15 +329,15 @@ onMounted(() => {
|
|||
data-test-id="unavailable-resources-list"
|
||||
emoji="👋"
|
||||
:heading="
|
||||
$locale.baseText(contextBasedTranslationKeys.variables.unavailable.title as BaseTextKey)
|
||||
i18n.baseText(contextBasedTranslationKeys.variables.unavailable.title as BaseTextKey)
|
||||
"
|
||||
:description="
|
||||
$locale.baseText(
|
||||
i18n.baseText(
|
||||
contextBasedTranslationKeys.variables.unavailable.description as BaseTextKey,
|
||||
)
|
||||
"
|
||||
:button-text="
|
||||
$locale.baseText(contextBasedTranslationKeys.variables.unavailable.button as BaseTextKey)
|
||||
i18n.baseText(contextBasedTranslationKeys.variables.unavailable.button as BaseTextKey)
|
||||
"
|
||||
button-type="secondary"
|
||||
@click:button="goToUpgrade"
|
||||
|
@ -347,11 +347,11 @@ onMounted(() => {
|
|||
data-test-id="cannot-create-variables"
|
||||
emoji="👋"
|
||||
:heading="
|
||||
$locale.baseText('variables.empty.notAllowedToCreate.heading', {
|
||||
i18n.baseText('variables.empty.notAllowedToCreate.heading', {
|
||||
interpolate: { name: usersStore.currentUser?.firstName ?? '' },
|
||||
})
|
||||
"
|
||||
:description="$locale.baseText('variables.empty.notAllowedToCreate.description')"
|
||||
:description="i18n.baseText('variables.empty.notAllowedToCreate.description')"
|
||||
@click="goToUpgrade"
|
||||
/>
|
||||
</template>
|
||||
|
|
|
@ -2,9 +2,11 @@
|
|||
import WorkerList from '@/components/WorkerList.ee.vue';
|
||||
import { useSettingsStore } from '@/stores/settings.store';
|
||||
import { usePageRedirectionHelper } from '@/composables/usePageRedirectionHelper';
|
||||
import { useI18n } from '@/composables/useI18n';
|
||||
|
||||
const settingsStore = useSettingsStore();
|
||||
const pageRedirectionHelper = usePageRedirectionHelper();
|
||||
const i18n = useI18n();
|
||||
|
||||
const goToUpgrade = () => {
|
||||
void pageRedirectionHelper.goToUpgrade('worker-view', 'upgrade-worker-view');
|
||||
|
@ -20,17 +22,17 @@ const goToUpgrade = () => {
|
|||
v-else
|
||||
data-test-id="worker-view-unlicensed"
|
||||
:class="$style.actionBox"
|
||||
:description="$locale.baseText('workerList.actionBox.description')"
|
||||
:button-text="$locale.baseText('workerList.actionBox.buttonText')"
|
||||
:description="i18n.baseText('workerList.actionBox.description')"
|
||||
:button-text="i18n.baseText('workerList.actionBox.buttonText')"
|
||||
@click:button="goToUpgrade"
|
||||
>
|
||||
<template #heading>
|
||||
<span>{{ $locale.baseText('workerList.actionBox.title') }}</span>
|
||||
<span>{{ i18n.baseText('workerList.actionBox.title') }}</span>
|
||||
</template>
|
||||
<template #description>
|
||||
{{ $locale.baseText('workerList.actionBox.description') }}
|
||||
<a :href="$locale.baseText('workerList.docs.url')" target="_blank">
|
||||
{{ $locale.baseText('workerList.actionBox.description.link') }}
|
||||
{{ i18n.baseText('workerList.actionBox.description') }}
|
||||
<a :href="i18n.baseText('workerList.docs.url')" target="_blank">
|
||||
{{ i18n.baseText('workerList.actionBox.description.link') }}
|
||||
</a>
|
||||
</template>
|
||||
</n8n-action-box>
|
||||
|
|
Loading…
Reference in a new issue