Revert "refactor(editor): Turn showMessage mixin to composable" (#6243)

Revert "refactor(editor): Turn showMessage mixin to composable (#6081)"

This reverts commit b95fcd7323.
This commit is contained in:
Csaba Tuncsik 2023-05-12 16:43:34 +02:00 committed by GitHub
parent 13bcec1661
commit 638e3f209d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
75 changed files with 863 additions and 991 deletions

View file

@ -27,28 +27,29 @@
</template>
<script lang="ts">
import Modals from '@/components/Modals.vue';
import LoadingView from '@/views/LoadingView.vue';
import Telemetry from '@/components/Telemetry.vue';
import { HIRING_BANNER, LOCAL_STORAGE_THEME, VIEWS } from '@/constants';
import Modals from './components/Modals.vue';
import LoadingView from './views/LoadingView.vue';
import Telemetry from './components/Telemetry.vue';
import { HIRING_BANNER, LOCAL_STORAGE_THEME, VIEWS } from './constants';
import mixins from 'vue-typed-mixins';
import { showMessage } from '@/mixins/showMessage';
import { userHelpers } from '@/mixins/userHelpers';
import { loadLanguage } from '@/plugins/i18n';
import { useGlobalLinkActions, useToast } from '@/composables';
import { loadLanguage } from './plugins/i18n';
import useGlobalLinkActions from '@/composables/useGlobalLinkActions';
import { mapStores } from 'pinia';
import { useUIStore } from '@/stores/ui.store';
import { useSettingsStore } from '@/stores/settings.store';
import { useUsersStore } from '@/stores/users.store';
import { useRootStore } from '@/stores/n8nRoot.store';
import { useTemplatesStore } from '@/stores/templates.store';
import { useNodeTypesStore } from '@/stores/nodeTypes.store';
import { useUIStore } from './stores/ui.store';
import { useSettingsStore } from './stores/settings.store';
import { useUsersStore } from './stores/users.store';
import { useRootStore } from './stores/n8nRoot.store';
import { useTemplatesStore } from './stores/templates.store';
import { useNodeTypesStore } from './stores/nodeTypes.store';
import { useHistoryHelper } from '@/composables/useHistoryHelper';
import { newVersions } from '@/mixins/newVersions';
import { useRoute } from 'vue-router/composables';
import { useVersionControlStore } from '@/stores/versionControl.store';
export default mixins(newVersions, userHelpers).extend({
export default mixins(newVersions, showMessage, userHelpers).extend({
name: 'App',
components: {
LoadingView,
@ -59,7 +60,6 @@ export default mixins(newVersions, userHelpers).extend({
return {
...useGlobalLinkActions(),
...useHistoryHelper(useRoute()),
...useToast(),
};
},
computed: {
@ -86,7 +86,7 @@ export default mixins(newVersions, userHelpers).extend({
try {
await this.settingsStore.getSettings();
} catch (e) {
this.showToast({
this.$showToast({
title: this.$locale.baseText('startupError'),
message: this.$locale.baseText('startupError.message'),
type: 'error',

View file

@ -29,17 +29,17 @@
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import mixins from 'vue-typed-mixins';
import { useToast } from '@/composables';
import Modal from '@/components/Modal.vue';
import { showMessage } from '@/mixins/showMessage';
import Modal from './Modal.vue';
import type { IFormInputs } from '@/Interface';
import { CHANGE_PASSWORD_MODAL_KEY } from '@/constants';
import { CHANGE_PASSWORD_MODAL_KEY } from '../constants';
import { mapStores } from 'pinia';
import { useUsersStore } from '@/stores/users.store';
import { createEventBus } from '@/event-bus';
export default defineComponent({
export default mixins(showMessage).extend({
components: { Modal },
name: 'ChangePasswordModal',
props: {
@ -47,11 +47,6 @@ export default defineComponent({
type: String,
},
},
setup() {
return {
...useToast(),
};
},
data() {
return {
config: null as null | IFormInputs,
@ -132,7 +127,7 @@ export default defineComponent({
this.loading = true;
await this.usersStore.updateCurrentUserPassword(values);
this.showMessage({
this.$showMessage({
type: 'success',
title: this.$locale.baseText('auth.changePassword.passwordUpdated'),
message: this.$locale.baseText('auth.changePassword.passwordUpdatedMessage'),
@ -140,7 +135,7 @@ export default defineComponent({
this.modalBus.emit('close');
} catch (error) {
this.showError(error, this.$locale.baseText('auth.changePassword.error'));
this.$showError(error, this.$locale.baseText('auth.changePassword.error'));
}
this.loading = false;
},

View file

@ -65,10 +65,11 @@
import { useUIStore } from '@/stores/ui.store';
import type { PublicInstalledPackage } from 'n8n-workflow';
import { mapStores } from 'pinia';
import { defineComponent } from 'vue';
import { NPM_PACKAGE_DOCS_BASE_URL, COMMUNITY_PACKAGE_MANAGE_ACTIONS } from '@/constants';
import mixins from 'vue-typed-mixins';
import { NPM_PACKAGE_DOCS_BASE_URL, COMMUNITY_PACKAGE_MANAGE_ACTIONS } from '../constants';
import { showMessage } from '@/mixins/showMessage';
export default defineComponent({
export default mixins(showMessage).extend({
name: 'CommunityPackageCard',
props: {
communityPackage: {

View file

@ -88,29 +88,24 @@
</template>
<script lang="ts">
import Modal from '@/components/Modal.vue';
import Modal from './Modal.vue';
import {
COMMUNITY_PACKAGE_INSTALL_MODAL_KEY,
NPM_KEYWORD_SEARCH_URL,
COMMUNITY_NODES_INSTALLATION_DOCS_URL,
COMMUNITY_NODES_RISKS_DOCS_URL,
} from '@/constants';
import { defineComponent } from 'vue';
import { useToast } from '@/composables';
} from '../constants';
import mixins from 'vue-typed-mixins';
import { showMessage } from '@/mixins/showMessage';
import { mapStores } from 'pinia';
import { useCommunityNodesStore } from '@/stores/communityNodes.store';
import { createEventBus } from '@/event-bus';
export default defineComponent({
export default mixins(showMessage).extend({
name: 'CommunityPackageInstallModal',
components: {
Modal,
},
setup() {
return {
...useToast(),
};
},
data() {
return {
loading: false,
@ -149,7 +144,7 @@ export default defineComponent({
await this.communityNodesStore.fetchInstalledPackages();
this.loading = false;
this.modalBus.emit('close');
this.showMessage({
this.$showMessage({
title: this.$locale.baseText('settings.communityNodes.messages.install.success'),
type: 'success',
});
@ -157,7 +152,7 @@ export default defineComponent({
if (error.httpStatusCode && error.httpStatusCode === 400) {
this.infoTextErrorMessage = error.message;
} else {
this.showError(
this.$showError(
error,
this.$locale.baseText('settings.communityNodes.messages.install.error'),
);

View file

@ -35,15 +35,18 @@
</template>
<script>
import { defineComponent } from 'vue';
import Modal from '@/components/Modal.vue';
import { COMMUNITY_PACKAGE_CONFIRM_MODAL_KEY, COMMUNITY_PACKAGE_MANAGE_ACTIONS } from '@/constants';
import { useToast } from '@/composables';
import mixins from 'vue-typed-mixins';
import Modal from './Modal.vue';
import {
COMMUNITY_PACKAGE_CONFIRM_MODAL_KEY,
COMMUNITY_PACKAGE_MANAGE_ACTIONS,
} from '../constants';
import { showMessage } from '@/mixins/showMessage';
import { mapStores } from 'pinia';
import { useCommunityNodesStore } from '@/stores/communityNodes.store';
import { createEventBus } from '@/event-bus';
export default defineComponent({
export default mixins(showMessage).extend({
name: 'CommunityPackageManageConfirmModal',
components: {
Modal,
@ -61,11 +64,6 @@ export default defineComponent({
type: String,
},
},
setup() {
return {
...useToast(),
};
},
data() {
return {
loading: false,
@ -142,12 +140,12 @@ export default defineComponent({
});
this.loading = true;
await this.communityNodesStore.uninstallPackage(this.activePackageName);
this.showMessage({
this.$showMessage({
title: this.$locale.baseText('settings.communityNodes.messages.uninstall.success.title'),
type: 'success',
});
} catch (error) {
this.showError(
this.$showError(
error,
this.$locale.baseText('settings.communityNodes.messages.uninstall.error'),
);
@ -169,7 +167,7 @@ export default defineComponent({
this.loading = true;
const updatedVersion = this.activePackage.updateAvailable;
await this.communityNodesStore.updatePackage(this.activePackageName);
this.showMessage({
this.$showMessage({
title: this.$locale.baseText('settings.communityNodes.messages.update.success.title'),
message: this.$locale.baseText(
'settings.communityNodes.messages.update.success.message',
@ -183,7 +181,7 @@ export default defineComponent({
type: 'success',
});
} catch (error) {
this.showError(
this.$showError(
error,
this.$locale.baseText('settings.communityNodes.messages.update.error.title'),
);

View file

@ -38,22 +38,16 @@ import mixins from 'vue-typed-mixins';
import type { IN8nPromptResponse } from '@/Interface';
import { VALID_EMAIL_REGEX } from '@/constants';
import { workflowHelpers } from '@/mixins/workflowHelpers';
import Modal from '@/components/Modal.vue';
import Modal from './Modal.vue';
import { mapStores } from 'pinia';
import { useSettingsStore } from '@/stores/settings.store';
import { useRootStore } from '@/stores/n8nRoot.store';
import { createEventBus } from '@/event-bus';
import { useToast } from '@/composables';
export default mixins(workflowHelpers).extend({
components: { Modal },
name: 'ContactPromptModal',
props: ['modalName'],
setup() {
return {
...useToast(),
};
},
data() {
return {
email: '',
@ -100,7 +94,7 @@ export default mixins(workflowHelpers).extend({
instance_id: this.rootStore.instanceId,
email: this.email,
});
this.showMessage({
this.$showMessage({
title: 'Thanks!',
message: "It's people like you that help make n8n better",
type: 'success',

View file

@ -19,9 +19,9 @@
<script lang="ts">
import mixins from 'vue-typed-mixins';
import { copyPaste } from '@/mixins/copyPaste';
import { useToast } from '@/composables';
import { showMessage } from '@/mixins/showMessage';
export default mixins(copyPaste).extend({
export default mixins(copyPaste, showMessage).extend({
props: {
label: {
type: String,
@ -56,17 +56,12 @@ export default mixins(copyPaste).extend({
default: 'large',
},
},
setup() {
return {
...useToast(),
};
},
methods: {
copy(): void {
this.$emit('copy');
this.copyToClipboard(this.value);
this.showMessage({
this.$showMessage({
title: this.toastTitle,
message: this.toastMessage,
type: 'success',

View file

@ -31,11 +31,11 @@
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import mixins from 'vue-typed-mixins';
import type { ICredentialsResponse, IUser } from '@/Interface';
import type { ICredentialType } from 'n8n-workflow';
import { EnterpriseEditionFeature, MODAL_CONFIRM } from '@/constants';
import { useMessage } from '@/composables';
import { EnterpriseEditionFeature } from '@/constants';
import { showMessage } from '@/mixins/showMessage';
import CredentialIcon from '@/components/CredentialIcon.vue';
import type { IPermissions } from '@/permissions';
import { getCredentialPermissions } from '@/permissions';
@ -50,17 +50,12 @@ export const CREDENTIAL_LIST_ITEM_ACTIONS = {
DELETE: 'delete',
};
export default defineComponent({
export default mixins(showMessage).extend({
data() {
return {
EnterpriseEditionFeature,
};
},
setup() {
return {
...useMessage(),
};
},
components: {
CredentialIcon,
},
@ -133,7 +128,7 @@ export default defineComponent({
if (action === CREDENTIAL_LIST_ITEM_ACTIONS.OPEN) {
await this.onClick();
} else if (action === CREDENTIAL_LIST_ITEM_ACTIONS.DELETE) {
const deleteConfirmed = await this.confirm(
const deleteConfirmed = await this.confirmMessage(
this.$locale.baseText(
'credentialEdit.credentialEdit.confirmMessage.deleteCredential.message',
{
@ -143,14 +138,13 @@ export default defineComponent({
this.$locale.baseText(
'credentialEdit.credentialEdit.confirmMessage.deleteCredential.headline',
),
{
confirmButtonText: this.$locale.baseText(
'credentialEdit.credentialEdit.confirmMessage.deleteCredential.confirmButtonText',
),
},
null,
this.$locale.baseText(
'credentialEdit.credentialEdit.confirmMessage.deleteCredential.confirmButtonText',
),
);
if (deleteConfirmed === MODAL_CONFIRM) {
if (deleteConfirmed) {
await this.credentialsStore.deleteCredential({ id: this.data.id });
}
}

View file

@ -127,21 +127,21 @@ import type {
ITelemetryTrackProperties,
} from 'n8n-workflow';
import { NodeHelpers } from 'n8n-workflow';
import CredentialIcon from '@/components/CredentialIcon.vue';
import CredentialIcon from '../CredentialIcon.vue';
import mixins from 'vue-typed-mixins';
import { nodeHelpers } from '@/mixins/nodeHelpers';
import { useToast, useMessage } from '@/composables';
import { showMessage } from '@/mixins/showMessage';
import CredentialConfig from '@/components/CredentialEdit/CredentialConfig.vue';
import CredentialInfo from '@/components/CredentialEdit/CredentialInfo.vue';
import CredentialSharing from '@/components/CredentialEdit/CredentialSharing.ee.vue';
import SaveButton from '@/components/SaveButton.vue';
import Modal from '@/components/Modal.vue';
import InlineNameEdit from '@/components/InlineNameEdit.vue';
import { CREDENTIAL_EDIT_MODAL_KEY, EnterpriseEditionFeature, MODAL_CONFIRM } from '@/constants';
import CredentialConfig from './CredentialConfig.vue';
import CredentialInfo from './CredentialInfo.vue';
import CredentialSharing from './CredentialSharing.ee.vue';
import SaveButton from '../SaveButton.vue';
import Modal from '../Modal.vue';
import InlineNameEdit from '../InlineNameEdit.vue';
import { CREDENTIAL_EDIT_MODAL_KEY, EnterpriseEditionFeature } from '@/constants';
import type { IDataObject } from 'n8n-workflow';
import FeatureComingSoon from '@/components/FeatureComingSoon.vue';
import FeatureComingSoon from '../FeatureComingSoon.vue';
import type { IPermissions } from '@/permissions';
import { getCredentialPermissions } from '@/permissions';
import type { IMenuItem } from 'n8n-design-system';
@ -165,7 +165,7 @@ interface NodeAccessMap {
[nodeType: string]: ICredentialNodeAccess | null;
}
export default mixins(nodeHelpers).extend({
export default mixins(showMessage, nodeHelpers).extend({
name: 'CredentialEdit',
components: {
CredentialSharing,
@ -190,12 +190,6 @@ export default mixins(nodeHelpers).extend({
type: String,
},
},
setup() {
return {
...useToast(),
...useMessage(),
};
},
data() {
return {
activeTab: 'connection',
@ -492,7 +486,7 @@ export default mixins(nodeHelpers).extend({
if (this.hasUnsavedChanges) {
const displayName = this.credentialType ? this.credentialType.displayName : '';
const confirmAction = await this.confirm(
keepEditing = await this.confirmMessage(
this.$locale.baseText(
'credentialEdit.credentialEdit.confirmMessage.beforeClose1.message',
{ interpolate: { credentialDisplayName: displayName } },
@ -500,34 +494,30 @@ export default mixins(nodeHelpers).extend({
this.$locale.baseText(
'credentialEdit.credentialEdit.confirmMessage.beforeClose1.headline',
),
{
cancelButtonText: this.$locale.baseText(
'credentialEdit.credentialEdit.confirmMessage.beforeClose1.cancelButtonText',
),
confirmButtonText: this.$locale.baseText(
'credentialEdit.credentialEdit.confirmMessage.beforeClose1.confirmButtonText',
),
},
null,
this.$locale.baseText(
'credentialEdit.credentialEdit.confirmMessage.beforeClose1.cancelButtonText',
),
this.$locale.baseText(
'credentialEdit.credentialEdit.confirmMessage.beforeClose1.confirmButtonText',
),
);
keepEditing = confirmAction === MODAL_CONFIRM;
} else if (this.credentialPermissions.isOwner && this.isOAuthType && !this.isOAuthConnected) {
const confirmAction = await this.confirm(
keepEditing = await this.confirmMessage(
this.$locale.baseText(
'credentialEdit.credentialEdit.confirmMessage.beforeClose2.message',
),
this.$locale.baseText(
'credentialEdit.credentialEdit.confirmMessage.beforeClose2.headline',
),
{
cancelButtonText: this.$locale.baseText(
'credentialEdit.credentialEdit.confirmMessage.beforeClose2.cancelButtonText',
),
confirmButtonText: this.$locale.baseText(
'credentialEdit.credentialEdit.confirmMessage.beforeClose2.confirmButtonText',
),
},
null,
this.$locale.baseText(
'credentialEdit.credentialEdit.confirmMessage.beforeClose2.cancelButtonText',
),
this.$locale.baseText(
'credentialEdit.credentialEdit.confirmMessage.beforeClose2.confirmButtonText',
),
);
keepEditing = confirmAction === MODAL_CONFIRM;
}
if (!keepEditing) {
@ -606,7 +596,7 @@ export default mixins(nodeHelpers).extend({
this.nodeAccess[access.nodeType] = access;
});
} catch (error) {
this.showError(
this.$showError(
error,
this.$locale.baseText('credentialEdit.credentialEdit.showError.loadCredential.title'),
);
@ -850,7 +840,7 @@ export default mixins(nodeHelpers).extend({
credential = await this.credentialsStore.createNewCredential(credentialDetails);
this.hasUnsavedChanges = false;
} catch (error) {
this.showError(
this.$showError(
error,
this.$locale.baseText('credentialEdit.credentialEdit.showError.createCredential.title'),
);
@ -884,7 +874,7 @@ export default mixins(nodeHelpers).extend({
});
this.hasUnsavedChanges = false;
} catch (error) {
this.showError(
this.$showError(
error,
this.$locale.baseText('credentialEdit.credentialEdit.showError.updateCredential.title'),
);
@ -912,7 +902,7 @@ export default mixins(nodeHelpers).extend({
const savedCredentialName = this.currentCredential.name;
const deleteConfirmed = await this.confirm(
const deleteConfirmed = await this.confirmMessage(
this.$locale.baseText(
'credentialEdit.credentialEdit.confirmMessage.deleteCredential.message',
{ interpolate: { savedCredentialName } },
@ -920,14 +910,13 @@ export default mixins(nodeHelpers).extend({
this.$locale.baseText(
'credentialEdit.credentialEdit.confirmMessage.deleteCredential.headline',
),
{
confirmButtonText: this.$locale.baseText(
'credentialEdit.credentialEdit.confirmMessage.deleteCredential.confirmButtonText',
),
},
null,
this.$locale.baseText(
'credentialEdit.credentialEdit.confirmMessage.deleteCredential.confirmButtonText',
),
);
if (deleteConfirmed !== MODAL_CONFIRM) {
if (deleteConfirmed === false) {
return;
}
@ -936,7 +925,7 @@ export default mixins(nodeHelpers).extend({
await this.credentialsStore.deleteCredential({ id: this.credentialId });
this.hasUnsavedChanges = false;
} catch (error) {
this.showError(
this.$showError(
error,
this.$locale.baseText('credentialEdit.credentialEdit.showError.deleteCredential.title'),
);
@ -950,7 +939,7 @@ export default mixins(nodeHelpers).extend({
this.updateNodesCredentialsIssues();
this.credentialData = {};
this.showMessage({
this.$showMessage({
title: this.$locale.baseText('credentialEdit.credentialEdit.showMessage.title'),
type: 'success',
});
@ -979,7 +968,7 @@ export default mixins(nodeHelpers).extend({
}
}
} catch (error) {
this.showError(
this.$showError(
error,
this.$locale.baseText(
'credentialEdit.credentialEdit.showError.generateAuthorizationUrl.title',

View file

@ -81,17 +81,17 @@
<script lang="ts">
import type { IUser, IUserListAction } from '@/Interface';
import { defineComponent } from 'vue';
import { useMessage } from '@/composables';
import mixins from 'vue-typed-mixins';
import { showMessage } from '@/mixins/showMessage';
import { mapStores } from 'pinia';
import { useUsersStore } from '@/stores/users.store';
import { useSettingsStore } from '@/stores/settings.store';
import { useUIStore } from '@/stores/ui.store';
import { useCredentialsStore } from '@/stores/credentials.store';
import { useUsageStore } from '@/stores/usage.store';
import { EnterpriseEditionFeature, MODAL_CONFIRM, VIEWS } from '@/constants';
import { EnterpriseEditionFeature, VIEWS } from '@/constants';
export default defineComponent({
export default mixins(showMessage).extend({
name: 'CredentialSharing',
props: [
'credential',
@ -101,11 +101,6 @@ export default defineComponent({
'credentialPermissions',
'modalBus',
],
setup() {
return {
...useMessage(),
};
},
computed: {
...mapStores(useCredentialsStore, useUsersStore, useUsageStore, useUIStore, useSettingsStore),
usersListActions(): IUserListAction[] {
@ -153,22 +148,21 @@ export default defineComponent({
const user = this.usersStore.getUserById(userId);
if (user) {
const confirm = await this.confirm(
const confirm = await this.confirmMessage(
this.$locale.baseText('credentialEdit.credentialSharing.list.delete.confirm.message', {
interpolate: { name: user.fullName || '' },
}),
this.$locale.baseText('credentialEdit.credentialSharing.list.delete.confirm.title'),
{
confirmButtonText: this.$locale.baseText(
'credentialEdit.credentialSharing.list.delete.confirm.confirmButtonText',
),
cancelButtonText: this.$locale.baseText(
'credentialEdit.credentialSharing.list.delete.confirm.cancelButtonText',
),
},
null,
this.$locale.baseText(
'credentialEdit.credentialSharing.list.delete.confirm.confirmButtonText',
),
this.$locale.baseText(
'credentialEdit.credentialSharing.list.delete.confirm.cancelButtonText',
),
);
if (confirm === MODAL_CONFIRM) {
if (confirm) {
this.$emit(
'change',
this.credentialData.sharedWith.filter((sharee: IUser) => {

View file

@ -70,15 +70,16 @@
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import { useToast } from '@/composables';
import Modal from '@/components/Modal.vue';
import type { IUser } from '@/Interface';
import mixins from 'vue-typed-mixins';
import { showMessage } from '@/mixins/showMessage';
import Modal from './Modal.vue';
import type { IUser } from '../Interface';
import { mapStores } from 'pinia';
import { useUsersStore } from '@/stores/users.store';
import { createEventBus } from '@/event-bus';
export default defineComponent({
export default mixins(showMessage).extend({
components: {
Modal,
},
@ -91,11 +92,6 @@ export default defineComponent({
type: String,
},
},
setup() {
return {
...useToast(),
};
},
data() {
return {
modalBus: createEventBus(),
@ -173,7 +169,7 @@ export default defineComponent({
}
}
this.showMessage({
this.$showMessage({
type: 'success',
title: this.$locale.baseText('settings.users.userDeleted'),
message,
@ -181,7 +177,7 @@ export default defineComponent({
this.modalBus.emit('close');
} catch (error) {
this.showError(error, this.$locale.baseText('settings.users.userDeletedError'));
this.$showError(error, this.$locale.baseText('settings.users.userDeletedError'));
}
this.loading = false;
},

View file

@ -53,9 +53,9 @@ import mixins from 'vue-typed-mixins';
import { MAX_WORKFLOW_NAME_LENGTH, PLACEHOLDER_EMPTY_WORKFLOW_ID } from '@/constants';
import { workflowHelpers } from '@/mixins/workflowHelpers';
import { useToast } from '@/composables';
import { showMessage } from '@/mixins/showMessage';
import TagsDropdown from '@/components/TagsDropdown.vue';
import Modal from '@/components/Modal.vue';
import Modal from './Modal.vue';
import { mapStores } from 'pinia';
import { useSettingsStore } from '@/stores/settings.store';
import { useWorkflowsStore } from '@/stores/workflows.store';
@ -66,15 +66,10 @@ import { useUsersStore } from '@/stores/users.store';
import { createEventBus } from '@/event-bus';
import { useCredentialsStore } from '@/stores';
export default mixins(workflowHelpers).extend({
export default mixins(showMessage, workflowHelpers).extend({
components: { TagsDropdown, Modal },
name: 'DuplicateWorkflow',
props: ['modalName', 'isActive', 'data'],
setup() {
return {
...useToast(),
};
},
data() {
const currentTagIds = this.data.tags;
@ -139,7 +134,7 @@ export default mixins(workflowHelpers).extend({
async save(): Promise<void> {
const name = this.name.trim();
if (!name) {
this.showMessage({
this.$showMessage({
title: this.$locale.baseText('duplicateWorkflowDialog.errors.missingName.title'),
message: this.$locale.baseText('duplicateWorkflowDialog.errors.missingName.message'),
type: 'error',
@ -186,12 +181,12 @@ export default mixins(workflowHelpers).extend({
if (error.httpStatusCode === 403) {
error.message = this.$locale.baseText('duplicateWorkflowDialog.errors.forbidden.message');
this.showError(
this.$showError(
error,
this.$locale.baseText('duplicateWorkflowDialog.errors.forbidden.title'),
);
} else {
this.showError(
this.$showError(
error,
this.$locale.baseText('duplicateWorkflowDialog.errors.generic.title'),
);

View file

@ -118,9 +118,10 @@
</template>
<script lang="ts">
//@ts-ignore
import VueJsonPretty from 'vue-json-pretty';
import { copyPaste } from '@/mixins/copyPaste';
import { useToast } from '@/composables';
import { showMessage } from '@/mixins/showMessage';
import mixins from 'vue-typed-mixins';
import { MAX_DISPLAY_DATA_SIZE } from '@/constants';
@ -130,17 +131,12 @@ import { mapStores } from 'pinia';
import { useNDVStore } from '@/stores/ndv.store';
import { useNodeTypesStore } from '@/stores/nodeTypes.store';
export default mixins(copyPaste).extend({
export default mixins(copyPaste, showMessage).extend({
name: 'NodeErrorView',
props: ['error'],
components: {
VueJsonPretty,
},
setup() {
return {
...useToast(),
};
},
computed: {
...mapStores(useNodeTypesStore, useNDVStore),
displayCause(): boolean {
@ -255,7 +251,7 @@ export default mixins(copyPaste).extend({
this.copySuccess();
},
copySuccess() {
this.showMessage({
this.$showMessage({
title: this.$locale.baseText('nodeErrorView.showMessage.title'),
type: 'info',
});

View file

@ -285,10 +285,10 @@ import ExecutionTime from '@/components/ExecutionTime.vue';
import WorkflowActivator from '@/components/WorkflowActivator.vue';
import ExecutionFilter from '@/components/ExecutionFilter.vue';
import { externalHooks } from '@/mixins/externalHooks';
import { MODAL_CONFIRM, VIEWS, WAIT_TIME_UNLIMITED } from '@/constants';
import { VIEWS, WAIT_TIME_UNLIMITED } from '@/constants';
import { genericHelpers } from '@/mixins/genericHelpers';
import { executionHelpers } from '@/mixins/executionsHelpers';
import { useToast, useMessage } from '@/composables';
import { showMessage } from '@/mixins/showMessage';
import type {
IExecutionsCurrentSummaryExtended,
IExecutionDeleteFilter,
@ -306,19 +306,13 @@ import { useWorkflowsStore } from '@/stores/workflows.store';
import { isEmpty, setPageTitle } from '@/utils';
import { executionFilterToQueryFilter } from '@/utils/executionUtils';
export default mixins(externalHooks, genericHelpers, executionHelpers).extend({
export default mixins(externalHooks, genericHelpers, executionHelpers, showMessage).extend({
name: 'ExecutionsList',
components: {
ExecutionTime,
WorkflowActivator,
ExecutionFilter,
},
setup() {
return {
...useToast(),
...useMessage(),
};
},
data() {
return {
isMounting: true,
@ -450,21 +444,17 @@ export default mixins(externalHooks, genericHelpers, executionHelpers).extend({
Object.keys(this.selectedItems).length === this.finishedExecutionsCount;
},
async handleDeleteSelected() {
const deleteExecutions = await this.confirm(
const deleteExecutions = await this.confirmMessage(
this.$locale.baseText('executionsList.confirmMessage.message', {
interpolate: { numSelected: this.numSelected.toString() },
}),
this.$locale.baseText('executionsList.confirmMessage.headline'),
{
type: 'warning',
confirmButtonText: this.$locale.baseText(
'executionsList.confirmMessage.confirmButtonText',
),
cancelButtonText: this.$locale.baseText('executionsList.confirmMessage.cancelButtonText'),
},
'warning',
this.$locale.baseText('executionsList.confirmMessage.confirmButtonText'),
this.$locale.baseText('executionsList.confirmMessage.cancelButtonText'),
);
if (deleteExecutions !== MODAL_CONFIRM) {
if (!deleteExecutions) {
return;
}
@ -483,7 +473,7 @@ export default mixins(externalHooks, genericHelpers, executionHelpers).extend({
await this.workflowsStore.deleteExecutions(sendData);
} catch (error) {
this.isDataLoading = false;
this.showError(
this.$showError(
error,
this.$locale.baseText('executionsList.showError.handleDeleteSelected.title'),
);
@ -492,7 +482,7 @@ export default mixins(externalHooks, genericHelpers, executionHelpers).extend({
}
this.isDataLoading = false;
this.showMessage({
this.$showMessage({
title: this.$locale.baseText('executionsList.showMessage.handleDeleteSelected.title'),
type: 'success',
});
@ -683,7 +673,7 @@ export default mixins(externalHooks, genericHelpers, executionHelpers).extend({
);
} catch (error) {
this.isDataLoading = false;
this.showError(error, this.$locale.baseText('executionsList.showError.loadMore.title'));
this.$showError(error, this.$locale.baseText('executionsList.showError.loadMore.title'));
return;
}
@ -723,7 +713,7 @@ export default mixins(externalHooks, genericHelpers, executionHelpers).extend({
Vue.set(this, 'workflows', workflows);
} catch (error) {
this.showError(
this.$showError(
error,
this.$locale.baseText('executionsList.showError.loadWorkflows.title'),
);
@ -739,12 +729,12 @@ export default mixins(externalHooks, genericHelpers, executionHelpers).extend({
);
if (retrySuccessful) {
this.showMessage({
this.$showMessage({
title: this.$locale.baseText('executionsList.showMessage.retrySuccessfulTrue.title'),
type: 'success',
});
} else {
this.showMessage({
this.$showMessage({
title: this.$locale.baseText('executionsList.showMessage.retrySuccessfulFalse.title'),
type: 'error',
});
@ -752,7 +742,7 @@ export default mixins(externalHooks, genericHelpers, executionHelpers).extend({
this.isDataLoading = false;
} catch (error) {
this.showError(
this.$showError(
error,
this.$locale.baseText('executionsList.showError.retryExecution.title'),
);
@ -766,7 +756,7 @@ export default mixins(externalHooks, genericHelpers, executionHelpers).extend({
try {
await Promise.all([this.loadActiveExecutions(), this.loadFinishedExecutions()]);
} catch (error) {
this.showError(error, this.$locale.baseText('executionsList.showError.refreshData.title'));
this.$showError(error, this.$locale.baseText('executionsList.showError.refreshData.title'));
}
this.isDataLoading = false;
@ -866,7 +856,7 @@ export default mixins(externalHooks, genericHelpers, executionHelpers).extend({
const index = this.stoppingExecutions.indexOf(activeExecutionId);
this.stoppingExecutions.splice(index, 1);
this.showMessage({
this.$showMessage({
title: this.$locale.baseText('executionsList.showMessage.stopExecution.title'),
message: this.$locale.baseText('executionsList.showMessage.stopExecution.message', {
interpolate: { activeExecutionId },
@ -876,7 +866,7 @@ export default mixins(externalHooks, genericHelpers, executionHelpers).extend({
this.refreshData();
} catch (error) {
this.showError(
this.$showError(
error,
this.$locale.baseText('executionsList.showError.stopExecution.title'),
);
@ -902,7 +892,7 @@ export default mixins(externalHooks, genericHelpers, executionHelpers).extend({
this.selectAllVisibleExecutions();
}
} catch (error) {
this.showError(
this.$showError(
error,
this.$locale.baseText('executionsList.showError.handleDeleteSelected.title'),
);

View file

@ -86,9 +86,10 @@ import mixins from 'vue-typed-mixins';
import type { IExecutionUIData } from '@/mixins/executionsHelpers';
import { executionHelpers } from '@/mixins/executionsHelpers';
import { VIEWS } from '@/constants';
import { showMessage } from '@/mixins/showMessage';
import ExecutionTime from '@/components/ExecutionTime.vue';
export default mixins(executionHelpers).extend({
export default mixins(executionHelpers, showMessage).extend({
name: 'execution-card',
components: {
ExecutionTime,

View file

@ -127,18 +127,18 @@
<script lang="ts">
import mixins from 'vue-typed-mixins';
import { useMessage } from '@/composables';
import { showMessage } from '@/mixins/showMessage';
import WorkflowPreview from '@/components/WorkflowPreview.vue';
import type { IExecutionUIData } from '@/mixins/executionsHelpers';
import { executionHelpers } from '@/mixins/executionsHelpers';
import { MODAL_CONFIRM, VIEWS } from '@/constants';
import { VIEWS } from '@/constants';
import { mapStores } from 'pinia';
import { useUIStore } from '@/stores/ui.store';
import { Dropdown as ElDropdown } from 'element-ui';
type RetryDropdownRef = InstanceType<typeof ElDropdown> & { hide: () => void };
export default mixins(executionHelpers).extend({
export default mixins(showMessage, executionHelpers).extend({
name: 'execution-preview',
components: {
ElDropdown,
@ -149,11 +149,6 @@ export default mixins(executionHelpers).extend({
VIEWS,
};
},
setup() {
return {
...useMessage(),
};
},
computed: {
...mapStores(useUIStore),
executionUIDetails(): IExecutionUIData | null {
@ -168,18 +163,14 @@ export default mixins(executionHelpers).extend({
},
methods: {
async onDeleteExecution(): Promise<void> {
const deleteConfirmed = await this.confirm(
const deleteConfirmed = await this.confirmMessage(
this.$locale.baseText('executionDetails.confirmMessage.message'),
this.$locale.baseText('executionDetails.confirmMessage.headline'),
{
type: 'warning',
confirmButtonText: this.$locale.baseText(
'executionDetails.confirmMessage.confirmButtonText',
),
cancelButtonText: '',
},
'warning',
this.$locale.baseText('executionDetails.confirmMessage.confirmButtonText'),
'',
);
if (deleteConfirmed !== MODAL_CONFIRM) {
if (!deleteConfirmed) {
return;
}
this.$emit('deleteCurrentExecution');

View file

@ -27,7 +27,7 @@ import ExecutionsSidebar from '@/components/ExecutionsView/ExecutionsSidebar.vue
import {
MAIN_HEADER_TABS,
MODAL_CANCEL,
MODAL_CONFIRM,
MODAL_CONFIRMED,
PLACEHOLDER_EMPTY_WORKFLOW_ID,
VIEWS,
WEBHOOK_NODE_TYPE,
@ -49,7 +49,7 @@ import type {
} from 'n8n-workflow';
import { NodeHelpers } from 'n8n-workflow';
import mixins from 'vue-typed-mixins';
import { useToast, useMessage } from '@/composables';
import { showMessage } from '@/mixins/showMessage';
import { v4 as uuid } from 'uuid';
import type { Route } from 'vue-router';
import { executionHelpers } from '@/mixins/executionsHelpers';
@ -70,7 +70,7 @@ const MAX_LOADING_ATTEMPTS = 5;
// Number of executions fetched on each page
const LOAD_MORE_PAGE_SIZE = 100;
export default mixins(executionHelpers, debounceHelper, workflowHelpers).extend({
export default mixins(showMessage, executionHelpers, debounceHelper, workflowHelpers).extend({
name: 'executions-list',
components: {
ExecutionsSidebar,
@ -83,12 +83,6 @@ export default mixins(executionHelpers, debounceHelper, workflowHelpers).extend(
temporaryExecution: null as IExecutionsSummary | null,
};
},
setup() {
return {
...useToast(),
...useMessage(),
};
},
computed: {
...mapStores(useTagsStore, useNodeTypesStore, useSettingsStore, useUIStore, useWorkflowsStore),
hidePreview(): boolean {
@ -138,22 +132,16 @@ export default mixins(executionHelpers, debounceHelper, workflowHelpers).extend(
return;
}
if (this.uiStore.stateIsDirty) {
const confirmModal = await this.confirm(
const confirmModal = await this.confirmModal(
this.$locale.baseText('generic.unsavedWork.confirmMessage.message'),
{
title: this.$locale.baseText('generic.unsavedWork.confirmMessage.headline'),
type: 'warning',
confirmButtonText: this.$locale.baseText(
'generic.unsavedWork.confirmMessage.confirmButtonText',
),
cancelButtonText: this.$locale.baseText(
'generic.unsavedWork.confirmMessage.cancelButtonText',
),
showClose: true,
},
this.$locale.baseText('generic.unsavedWork.confirmMessage.headline'),
'warning',
this.$locale.baseText('generic.unsavedWork.confirmMessage.confirmButtonText'),
this.$locale.baseText('generic.unsavedWork.confirmMessage.cancelButtonText'),
true,
);
if (confirmModal === MODAL_CONFIRM) {
if (confirmModal === MODAL_CONFIRMED) {
const saved = await this.saveCurrentWorkflow({}, false);
if (saved) {
await this.settingsStore.fetchPromptsData();
@ -233,7 +221,7 @@ export default mixins(executionHelpers, debounceHelper, workflowHelpers).extend(
data = await this.workflowsStore.getPastExecutions(this.requestFilter, limit, lastId);
} catch (error) {
this.loadingMore = false;
this.showError(error, this.$locale.baseText('executionsList.showError.loadMore.title'));
this.$showError(error, this.$locale.baseText('executionsList.showError.loadMore.title'));
return;
}
@ -288,7 +276,7 @@ export default mixins(executionHelpers, debounceHelper, workflowHelpers).extend(
await this.setExecutions();
} catch (error) {
this.loading = false;
this.showError(
this.$showError(
error,
this.$locale.baseText('executionsList.showError.handleDeleteSelected.title'),
);
@ -296,7 +284,7 @@ export default mixins(executionHelpers, debounceHelper, workflowHelpers).extend(
}
this.loading = false;
this.showMessage({
this.$showMessage({
title: this.$locale.baseText('executionsList.showMessage.handleDeleteSelected.title'),
type: 'success',
});
@ -307,7 +295,7 @@ export default mixins(executionHelpers, debounceHelper, workflowHelpers).extend(
try {
await this.workflowsStore.stopCurrentExecution(activeExecutionId);
this.showMessage({
this.$showMessage({
title: this.$locale.baseText('executionsList.showMessage.stopExecution.title'),
message: this.$locale.baseText('executionsList.showMessage.stopExecution.message', {
interpolate: { activeExecutionId },
@ -317,7 +305,7 @@ export default mixins(executionHelpers, debounceHelper, workflowHelpers).extend(
await this.loadAutoRefresh();
} catch (error) {
this.showError(
this.$showError(
error,
this.$locale.baseText('executionsList.showError.stopExecution.title'),
);
@ -411,7 +399,7 @@ export default mixins(executionHelpers, debounceHelper, workflowHelpers).extend(
return await this.workflowsStore.loadCurrentWorkflowExecutions(this.requestFilter);
} catch (error) {
if (error.errorCode === NO_NETWORK_ERROR_CODE) {
this.showMessage(
this.$showMessage(
{
title: this.$locale.baseText('executionsList.showError.refreshData.title'),
message: error.message,
@ -421,7 +409,7 @@ export default mixins(executionHelpers, debounceHelper, workflowHelpers).extend(
false,
);
} else {
this.showError(
this.$showError(
error,
this.$locale.baseText('executionsList.showError.refreshData.title'),
);
@ -461,7 +449,7 @@ export default mixins(executionHelpers, debounceHelper, workflowHelpers).extend(
const existingExecution = await this.workflowsStore.fetchExecutionDataById(executionId);
if (!existingExecution) {
this.workflowsStore.activeWorkflowExecution = null;
this.showError(
this.$showError(
new Error(
this.$locale.baseText('executionView.notFound.message', {
interpolate: { executionId },
@ -505,7 +493,7 @@ export default mixins(executionHelpers, debounceHelper, workflowHelpers).extend(
try {
data = await this.workflowsStore.fetchWorkflow(workflowId);
} catch (error) {
this.showError(error, this.$locale.baseText('nodeView.showError.openWorkflow.title'));
this.$showError(error, this.$locale.baseText('nodeView.showError.openWorkflow.title'));
return;
}
if (data === undefined) {
@ -654,7 +642,7 @@ export default mixins(executionHelpers, debounceHelper, workflowHelpers).extend(
async onRetryExecution(payload: { execution: IExecutionsSummary; command: string }) {
const loadWorkflow = payload.command === 'current-workflow';
this.showMessage({
this.$showMessage({
title: this.$locale.baseText('executionDetails.runningMessage'),
type: 'info',
duration: 2000,
@ -676,18 +664,18 @@ export default mixins(executionHelpers, debounceHelper, workflowHelpers).extend(
);
if (retrySuccessful === true) {
this.showMessage({
this.$showMessage({
title: this.$locale.baseText('executionsList.showMessage.retrySuccessfulTrue.title'),
type: 'success',
});
} else {
this.showMessage({
this.$showMessage({
title: this.$locale.baseText('executionsList.showMessage.retrySuccessfulFalse.title'),
type: 'error',
});
}
} catch (error) {
this.showError(
this.$showError(
error,
this.$locale.baseText('executionsList.showError.retryExecution.title'),
);

View file

@ -40,30 +40,25 @@
</template>
<script lang="ts">
import Modal from '@/components/Modal.vue';
import Modal from './Modal.vue';
import {
IMPORT_CURL_MODAL_KEY,
CURL_IMPORT_NOT_SUPPORTED_PROTOCOLS,
CURL_IMPORT_NODES_PROTOCOLS,
} from '@/constants';
import { useToast } from '@/composables';
import { defineComponent } from 'vue';
} from '../constants';
import { showMessage } from '@/mixins/showMessage';
import mixins from 'vue-typed-mixins';
import type { INodeUi } from '@/Interface';
import { mapStores } from 'pinia';
import { useUIStore } from '@/stores/ui.store';
import { useNDVStore } from '@/stores/ndv.store';
import { createEventBus } from '@/event-bus';
export default defineComponent({
export default mixins(showMessage).extend({
name: 'ImportCurlModal',
components: {
Modal,
},
setup() {
return {
...useToast(),
};
},
data() {
return {
IMPORT_CURL_MODAL_KEY,
@ -127,7 +122,7 @@ export default defineComponent({
}
},
showProtocolErrorWithSupportedNode(protocol: string, node: string): void {
this.showToast({
this.$showToast({
title: this.$locale.baseText('importParameter.showError.invalidProtocol1.title', {
interpolate: {
node,
@ -143,7 +138,7 @@ export default defineComponent({
});
},
showProtocolError(protocol: string): void {
this.showToast({
this.$showToast({
title: this.$locale.baseText('importParameter.showError.invalidProtocol2.title'),
message: this.$locale.baseText('importParameter.showError.invalidProtocol.message', {
interpolate: {
@ -155,7 +150,7 @@ export default defineComponent({
});
},
showInvalidcURLCommandError(): void {
this.showToast({
this.$showToast({
title: this.$locale.baseText('importParameter.showError.invalidCurlCommand.title'),
message: this.$locale.baseText('importParameter.showError.invalidCurlCommand.message'),
type: 'error',

View file

@ -11,12 +11,13 @@
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import { IMPORT_CURL_MODAL_KEY } from '@/constants';
import { useUIStore } from '@/stores/ui.store';
import { mapStores } from 'pinia';
import mixins from 'vue-typed-mixins';
import { showMessage } from '@/mixins/showMessage';
export default defineComponent({
export default mixins(showMessage).extend({
name: 'import-parameter',
props: {
isReadOnly: {

View file

@ -32,10 +32,10 @@
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import { useToast } from '@/composables';
import mixins from 'vue-typed-mixins';
import { showMessage } from '@/mixins/showMessage';
export default defineComponent({
export default mixins(showMessage).extend({
name: 'InlineNameEdit',
props: {
name: {
@ -52,11 +52,6 @@ export default defineComponent({
default: false,
},
},
setup() {
return {
...useToast(),
};
},
data() {
return {
isNameEdit: false,
@ -80,7 +75,7 @@ export default defineComponent({
if (!this.name) {
this.$emit('input', `Untitled ${this.type}`);
this.showToast({
this.$showToast({
title: 'Error',
message: `${this.type} name cannot be empty`,
type: 'warning',

View file

@ -66,7 +66,7 @@
<script lang="ts">
import mixins from 'vue-typed-mixins';
import { useToast } from '@/composables';
import { showMessage } from '@/mixins/showMessage';
import { copyPaste } from '@/mixins/copyPaste';
import Modal from './Modal.vue';
import type { IFormInputs, IInviteResponse, IUser } from '@/Interface';
@ -90,7 +90,7 @@ function getEmail(email: string): string {
return parsed;
}
export default mixins(copyPaste).extend({
export default mixins(showMessage, copyPaste).extend({
components: { Modal },
name: 'InviteUsersModal',
props: {
@ -98,11 +98,6 @@ export default mixins(copyPaste).extend({
type: String,
},
},
setup() {
return {
...useToast(),
};
},
data() {
return {
config: null as IFormInputs | null,
@ -229,7 +224,7 @@ export default mixins(copyPaste).extend({
);
if (successfulEmailInvites.length) {
this.showMessage({
this.$showMessage({
type: 'success',
title: this.$locale.baseText(
successfulEmailInvites.length > 1
@ -249,7 +244,7 @@ export default mixins(copyPaste).extend({
this.copyToClipboard(successfulUrlInvites[0].user.inviteAcceptUrl);
}
this.showMessage({
this.$showMessage({
type: 'success',
title: this.$locale.baseText(
successfulUrlInvites.length > 1
@ -271,7 +266,7 @@ export default mixins(copyPaste).extend({
if (erroredInvites.length) {
setTimeout(() => {
this.showMessage({
this.$showMessage({
type: 'error',
title: this.$locale.baseText('settings.users.usersEmailedError'),
message: this.$locale.baseText('settings.users.emailInvitesSentError', {
@ -287,12 +282,12 @@ export default mixins(copyPaste).extend({
this.modalBus.emit('close');
}
} catch (error) {
this.showError(error, this.$locale.baseText('settings.users.usersInvitedError'));
this.$showError(error, this.$locale.baseText('settings.users.usersInvitedError'));
}
this.loading = false;
},
showCopyInviteLinkToast(successfulUrlInvites: IInviteResponse[]) {
this.showMessage({
this.$showMessage({
type: 'success',
title: this.$locale.baseText(
successfulUrlInvites.length > 1

View file

@ -128,7 +128,6 @@ import {
DUPLICATE_MODAL_KEY,
EnterpriseEditionFeature,
MAX_WORKFLOW_NAME_LENGTH,
MODAL_CONFIRM,
PLACEHOLDER_EMPTY_WORKFLOW_ID,
VIEWS,
WORKFLOW_MENU_ACTIONS,
@ -148,7 +147,7 @@ import BreakpointsObserver from '@/components/BreakpointsObserver.vue';
import type { IUser, IWorkflowDataUpdate, IWorkflowDb, IWorkflowToShare } from '@/Interface';
import { saveAs } from 'file-saver';
import { useTitleChange, useToast, useMessage } from '@/composables';
import { useTitleChange } from '@/composables/useTitleChange';
import type { MessageBoxInputData } from 'element-ui/types/message-box';
import { mapStores } from 'pinia';
import { useUIStore } from '@/stores/ui.store';
@ -186,8 +185,6 @@ export default mixins(workflowHelpers).extend({
setup() {
return {
...useTitleChange(),
...useToast(),
...useMessage(),
};
},
data() {
@ -384,7 +381,7 @@ export default mixins(workflowHelpers).extend({
async onNameSubmit(name: string, cb: (saved: boolean) => void) {
const newName = name.trim();
if (!newName) {
this.showMessage({
this.$showMessage({
title: this.$locale.baseText('workflowDetails.showMessage.title'),
message: this.$locale.baseText('workflowDetails.showMessage.message'),
type: 'error',
@ -416,7 +413,7 @@ export default mixins(workflowHelpers).extend({
try {
workflowData = JSON.parse(data as string);
} catch (error) {
this.showMessage({
this.$showMessage({
title: this.$locale.baseText('mainSidebar.showMessage.handleFileImport.title'),
message: this.$locale.baseText('mainSidebar.showMessage.handleFileImport.message'),
type: 'error',
@ -473,7 +470,7 @@ export default mixins(workflowHelpers).extend({
}
case WORKFLOW_MENU_ACTIONS.IMPORT_FROM_URL: {
try {
const promptResponse = (await this.prompt(
const promptResponse = (await this.$prompt(
this.$locale.baseText('mainSidebar.prompt.workflowUrl') + ':',
this.$locale.baseText('mainSidebar.prompt.importWorkflowFromUrl') + ':',
{
@ -497,36 +494,30 @@ export default mixins(workflowHelpers).extend({
break;
}
case WORKFLOW_MENU_ACTIONS.DELETE: {
const deleteConfirmed = await this.confirm(
const deleteConfirmed = await this.confirmMessage(
this.$locale.baseText('mainSidebar.confirmMessage.workflowDelete.message', {
interpolate: { workflowName: this.workflowName },
}),
this.$locale.baseText('mainSidebar.confirmMessage.workflowDelete.headline'),
{
type: 'warning',
confirmButtonText: this.$locale.baseText(
'mainSidebar.confirmMessage.workflowDelete.confirmButtonText',
),
cancelButtonText: this.$locale.baseText(
'mainSidebar.confirmMessage.workflowDelete.cancelButtonText',
),
},
'warning',
this.$locale.baseText('mainSidebar.confirmMessage.workflowDelete.confirmButtonText'),
this.$locale.baseText('mainSidebar.confirmMessage.workflowDelete.cancelButtonText'),
);
if (deleteConfirmed !== MODAL_CONFIRM) {
if (deleteConfirmed === false) {
return;
}
try {
await this.workflowsStore.deleteWorkflow(this.currentWorkflowId);
} catch (error) {
this.showError(error, this.$locale.baseText('generic.deleteWorkflowError'));
this.$showError(error, this.$locale.baseText('generic.deleteWorkflowError'));
return;
}
this.uiStore.stateIsDirty = false;
// Reset tab title since workflow is deleted.
this.titleReset();
this.showMessage({
this.$showMessage({
title: this.$locale.baseText('mainSidebar.showMessage.handleSelect1.title'),
type: 'success',
});

View file

@ -110,13 +110,13 @@
</template>
<script lang="ts">
import type { IExecutionResponse, IMenuItem, IVersion } from '@/Interface';
import type { MessageBoxInputData } from 'element-ui/types/message-box';
import type { IExecutionResponse, IMenuItem, IVersion } from '../Interface';
import GiftNotificationIcon from './GiftNotificationIcon.vue';
import WorkflowSettings from '@/components/WorkflowSettings.vue';
import { genericHelpers } from '@/mixins/genericHelpers';
import { useMessage } from '@/composables';
import { showMessage } from '@/mixins/showMessage';
import { workflowHelpers } from '@/mixins/workflowHelpers';
import { workflowRun } from '@/mixins/workflowRun';
@ -137,6 +137,7 @@ import { useVersionControlStore } from '@/stores/versionControl.store';
export default mixins(
genericHelpers,
showMessage,
workflowHelpers,
workflowRun,
userHelpers,
@ -147,11 +148,6 @@ export default mixins(
GiftNotificationIcon,
WorkflowSettings,
},
setup() {
return {
...useMessage(),
};
},
data() {
return {
// @ts-ignore
@ -487,7 +483,7 @@ export default mixins(
}
},
async sync() {
const prompt = (await this.prompt(
const prompt = await this.$prompt(
this.$locale.baseText('settings.versionControl.sync.prompt.description', {
interpolate: { branch: this.versionControlStore.state.currentBranch },
}),
@ -503,7 +499,7 @@ export default mixins(
inputPattern: /^.+$/,
inputErrorMessage: this.$locale.baseText('settings.versionControl.sync.prompt.error'),
},
)) as MessageBoxInputData;
);
if (prompt.value) {
await this.versionControlStore.sync({ commitMessage: prompt.value });

View file

@ -115,7 +115,7 @@ import type {
import { genericHelpers } from '@/mixins/genericHelpers';
import { nodeHelpers } from '@/mixins/nodeHelpers';
import { useToast } from '@/composables';
import { showMessage } from '@/mixins/showMessage';
import TitledList from '@/components/TitledList.vue';
@ -141,7 +141,7 @@ interface CredentialDropdownOption extends ICredentialsResponse {
typeDisplayName: string;
}
export default mixins(genericHelpers, nodeHelpers).extend({
export default mixins(genericHelpers, nodeHelpers, showMessage).extend({
name: 'NodeCredentials',
props: {
readonly: {
@ -167,11 +167,6 @@ export default mixins(genericHelpers, nodeHelpers).extend({
components: {
TitledList,
},
setup() {
return {
...useToast(),
};
},
data() {
return {
NEW_CREDENTIALS_TEXT: `- ${this.$locale.baseText('nodeCredentials.createNew')} -`,
@ -457,7 +452,7 @@ export default mixins(genericHelpers, nodeHelpers).extend({
type: selectedCredentialsType,
});
this.updateNodesCredentialsIssues();
this.showMessage({
this.$showMessage({
title: this.$locale.baseText('nodeCredentials.showMessage.title'),
message: this.$locale.baseText('nodeCredentials.showMessage.message', {
interpolate: {

View file

@ -150,7 +150,6 @@ import {
BASE_NODE_SURVEY_URL,
EnterpriseEditionFeature,
EXECUTABLE_TRIGGER_NODE_TYPES,
MODAL_CONFIRM,
START_NODE_TYPE,
STICKY_NODE_TYPE,
} from '@/constants';
@ -164,7 +163,6 @@ import { useNodeTypesStore } from '@/stores/nodeTypes.store';
import { useUIStore } from '@/stores/ui.store';
import { useSettingsStore } from '@/stores/settings.store';
import useDeviceSupport from '@/composables/useDeviceSupport';
import { useMessage } from '@/composables';
export default mixins(
externalHooks,
@ -196,7 +194,6 @@ export default mixins(
setup() {
return {
...useDeviceSupport(),
...useMessage(),
};
},
data() {
@ -611,16 +608,15 @@ export default mixins(
}
if (this.outputPanelEditMode.enabled) {
const shouldPinDataBeforeClosing = await this.confirm(
const shouldPinDataBeforeClosing = await this.confirmMessage(
'',
this.$locale.baseText('ndv.pinData.beforeClosing.title'),
{
confirmButtonText: this.$locale.baseText('ndv.pinData.beforeClosing.confirm'),
cancelButtonText: this.$locale.baseText('ndv.pinData.beforeClosing.cancel'),
},
null,
this.$locale.baseText('ndv.pinData.beforeClosing.confirm'),
this.$locale.baseText('ndv.pinData.beforeClosing.cancel'),
);
if (shouldPinDataBeforeClosing === MODAL_CONFIRM) {
if (shouldPinDataBeforeClosing) {
const { value } = this.outputPanelEditMode;
if (!this.isValidPinDataSize(value)) {

View file

@ -18,7 +18,7 @@
</template>
<script lang="ts">
import { WEBHOOK_NODE_TYPE, MANUAL_TRIGGER_NODE_TYPE, MODAL_CONFIRM } from '@/constants';
import { WEBHOOK_NODE_TYPE, MANUAL_TRIGGER_NODE_TYPE } from '@/constants';
import type { INodeUi } from '@/Interface';
import type { INodeTypeDescription } from 'n8n-workflow';
import mixins from 'vue-typed-mixins';
@ -29,7 +29,6 @@ import { mapStores } from 'pinia';
import { useWorkflowsStore } from '@/stores/workflows.store';
import { useNDVStore } from '@/stores/ndv.store';
import { useNodeTypesStore } from '@/stores/nodeTypes.store';
import { useToast, useMessage } from '@/composables';
export default mixins(workflowRun, pinData).extend({
props: {
@ -57,12 +56,6 @@ export default mixins(workflowRun, pinData).extend({
type: String,
},
},
setup() {
return {
...useToast(),
...useMessage(),
};
},
computed: {
...mapStores(useNodeTypesStore, useNDVStore, useWorkflowsStore),
node(): INodeUi | null {
@ -180,7 +173,7 @@ export default mixins(workflowRun, pinData).extend({
try {
await this.workflowsStore.removeTestWebhook(this.workflowsStore.workflowId);
} catch (error) {
this.showError(error, this.$locale.baseText('ndv.execute.stopWaitingForWebhook.error'));
this.$showError(error, this.$locale.baseText('ndv.execute.stopWaitingForWebhook.error'));
return;
}
},
@ -193,15 +186,13 @@ export default mixins(workflowRun, pinData).extend({
} else {
let shouldUnpinAndExecute = false;
if (this.hasPinData) {
const confirmResult = await this.confirm(
shouldUnpinAndExecute = await this.confirmMessage(
this.$locale.baseText('ndv.pinData.unpinAndExecute.description'),
this.$locale.baseText('ndv.pinData.unpinAndExecute.title'),
{
confirmButtonText: this.$locale.baseText('ndv.pinData.unpinAndExecute.confirm'),
cancelButtonText: this.$locale.baseText('ndv.pinData.unpinAndExecute.cancel'),
},
null,
this.$locale.baseText('ndv.pinData.unpinAndExecute.confirm'),
this.$locale.baseText('ndv.pinData.unpinAndExecute.cancel'),
);
shouldUnpinAndExecute = confirmResult === MODAL_CONFIRM;
if (shouldUnpinAndExecute) {
dataPinningEventBus.emit('data-unpinning', { source: 'unpin-and-execute-modal' });

View file

@ -62,22 +62,17 @@ import type { INodeTypeDescription, IWebhookDescription } from 'n8n-workflow';
import { WEBHOOK_NODE_TYPE } from '@/constants';
import { copyPaste } from '@/mixins/copyPaste';
import { useToast } from '@/composables';
import { showMessage } from '@/mixins/showMessage';
import { workflowHelpers } from '@/mixins/workflowHelpers';
import mixins from 'vue-typed-mixins';
export default mixins(copyPaste, workflowHelpers).extend({
export default mixins(copyPaste, showMessage, workflowHelpers).extend({
name: 'NodeWebhooks',
props: [
'node', // NodeUi
'nodeType', // INodeTypeDescription
],
setup() {
return {
...useToast(),
};
},
data() {
return {
isMinimized: this.nodeType && this.nodeType.name !== WEBHOOK_NODE_TYPE,
@ -100,7 +95,7 @@ export default mixins(copyPaste, workflowHelpers).extend({
const webhookUrl = this.getWebhookUrlDisplay(webhookData);
this.copyToClipboard(webhookUrl);
this.showMessage({
this.$showMessage({
title: this.$locale.baseText('nodeWebhooks.showMessage.title'),
type: 'success',
});

View file

@ -51,23 +51,18 @@
import { ONBOARDING_CALL_SIGNUP_MODAL_KEY, VALID_EMAIL_REGEX } from '@/constants';
import Modal from './Modal.vue';
import { defineComponent } from 'vue';
import { useToast } from '@/composables';
import mixins from 'vue-typed-mixins';
import { showMessage } from '@/mixins/showMessage';
import { mapStores } from 'pinia';
import { useUIStore } from '@/stores/ui.store';
import { createEventBus } from '@/event-bus';
export default defineComponent({
export default mixins(showMessage).extend({
components: {
Modal,
},
name: 'OnboardingCallSignupModal',
props: ['modalName'],
setup() {
return {
...useToast(),
};
},
data() {
return {
email: '',
@ -96,7 +91,7 @@ export default defineComponent({
try {
await this.uiStore.applyForOnboardingCall(this.email);
this.showMessage({
this.$showMessage({
type: 'success',
title: this.$locale.baseText('onboardingCallSignupSucess.title'),
message: this.$locale.baseText('onboardingCallSignupSucess.message'),
@ -104,7 +99,7 @@ export default defineComponent({
this.okToClose = true;
this.modalBus.emit('close');
} catch (e) {
this.showError(
this.$showError(
e,
this.$locale.baseText('onboardingCallSignupFailed.title'),
this.$locale.baseText('onboardingCallSignupFailed.message'),

View file

@ -3,12 +3,13 @@
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import type { ElNotificationComponent } from 'element-ui/types/notification';
import { sanitizeHtml } from '@/utils';
import { useToast } from '@/composables';
import mixins from 'vue-typed-mixins';
export default defineComponent({
import { showMessage } from '@/mixins/showMessage';
import type { ElMessageComponent } from 'element-ui/types/message';
import { sanitizeHtml } from '@/utils';
export default mixins(showMessage).extend({
name: 'PageAlert',
props: {
message: {
@ -19,24 +20,19 @@ export default defineComponent({
type: String,
},
},
setup() {
return {
...useToast(),
};
},
data() {
return {
alert: null as null | ElNotificationComponent,
alert: null as null | ElMessageComponent,
};
},
mounted() {
this.alert = this.showAlert({
title: '',
this.alert = this.$showAlert({
message: sanitizeHtml(this.message),
type: 'warning',
duration: 0,
showClose: true,
dangerouslyUseHTMLString: true,
// @ts-ignore
customClass: this.popupClass || '',
});
},

View file

@ -379,6 +379,7 @@ import HtmlEditor from '@/components/HtmlEditor/HtmlEditor.vue';
import SqlEditor from '@/components/SqlEditor/SqlEditor.vue';
import { externalHooks } from '@/mixins/externalHooks';
import { nodeHelpers } from '@/mixins/nodeHelpers';
import { showMessage } from '@/mixins/showMessage';
import { workflowHelpers } from '@/mixins/workflowHelpers';
import { hasExpressionMapping, isValueExpression, isResourceLocatorValue } from '@/utils';
@ -396,7 +397,13 @@ import Vue from 'vue';
type ResourceLocatorRef = InstanceType<typeof ResourceLocator>;
export default mixins(externalHooks, nodeHelpers, workflowHelpers, debounceHelper).extend({
export default mixins(
externalHooks,
nodeHelpers,
showMessage,
workflowHelpers,
debounceHelper,
).extend({
name: 'parameter-input',
components: {
CodeNodeEditor,

View file

@ -76,7 +76,7 @@ import type { IN8nButton, INodeUi, IRunDataDisplayMode, IUpdateInformation } fro
import ParameterOptions from '@/components/ParameterOptions.vue';
import DraggableTarget from '@/components/DraggableTarget.vue';
import mixins from 'vue-typed-mixins';
import { useToast } from '@/composables';
import { showMessage } from '@/mixins/showMessage';
import {
hasExpressionMapping,
isResourceLocatorValue,
@ -95,24 +95,19 @@ import { mapStores } from 'pinia';
import { useNDVStore } from '@/stores/ndv.store';
import { useSegment } from '@/stores/segment.store';
import { externalHooks } from '@/mixins/externalHooks';
import { getMappedResult } from '@/utils/mappingUtils';
import { getMappedResult } from '../utils/mappingUtils';
type ParamterInputWrapperRef = InstanceType<typeof ParameterInputWrapper>;
const DISPLAY_MODES_WITH_DATA_MAPPING = ['table', 'json', 'schema'];
export default mixins(externalHooks).extend({
export default mixins(showMessage, externalHooks).extend({
name: 'parameter-input-full',
components: {
ParameterOptions,
DraggableTarget,
ParameterInputWrapper,
},
setup() {
return {
...useToast(),
};
},
data() {
return {
focused: false,
@ -297,7 +292,7 @@ export default mixins(externalHooks).extend({
this.$emit('valueChanged', parameterData);
if (!this.ndvStore.isMappingOnboarded) {
this.showMessage({
this.$showMessage({
title: this.$locale.baseText('dataMapping.success.title'),
message: this.$locale.baseText('dataMapping.success.moreInfo'),
type: 'success',

View file

@ -45,8 +45,9 @@
import type { PropType } from 'vue';
import ParameterInput from '@/components/ParameterInput.vue';
import InputHint from '@/components/ParameterInputHint.vue';
import InputHint from './ParameterInputHint.vue';
import mixins from 'vue-typed-mixins';
import { showMessage } from '@/mixins/showMessage';
import type {
INodeProperties,
INodePropertyMode,
@ -62,7 +63,7 @@ import { useNDVStore } from '@/stores/ndv.store';
type ParamRef = InstanceType<typeof ParameterInput>;
export default mixins(workflowHelpers).extend({
export default mixins(showMessage, workflowHelpers).extend({
name: 'parameter-input-wrapper',
components: {
ParameterInput,

View file

@ -125,8 +125,8 @@ import {
VIEWS,
} from '@/constants';
import { workflowHelpers } from '@/mixins/workflowHelpers';
import { useToast } from '@/composables';
import Modal from '@/components/Modal.vue';
import { showMessage } from '@/mixins/showMessage';
import Modal from './Modal.vue';
import type { IFormInputs, IPersonalizationLatestVersion, IUser } from '@/Interface';
import { getAccountAge } from '@/utils';
import type { GenericValue } from 'n8n-workflow';
@ -137,7 +137,7 @@ import { useRootStore } from '@/stores/n8nRoot.store';
import { useUsersStore } from '@/stores/users.store';
import { createEventBus } from '@/event-bus';
export default mixins(workflowHelpers).extend({
export default mixins(showMessage, workflowHelpers).extend({
components: { Modal },
name: 'PersonalizationModal',
data() {
@ -151,11 +151,6 @@ export default mixins(workflowHelpers).extend({
formBus: createEventBus(),
};
},
setup() {
return {
...useToast(),
};
},
computed: {
...mapStores(useRootStore, useSettingsStore, useUIStore, useUsersStore),
survey() {
@ -642,7 +637,7 @@ export default mixins(workflowHelpers).extend({
await this.fetchOnboardingPrompt();
} catch (e) {
this.showError(e, 'Error while submitting results');
this.$showError(e, 'Error while submitting results');
}
this.$data.isSaving = false;
@ -659,7 +654,7 @@ export default mixins(workflowHelpers).extend({
if (onboardingResponse.title && onboardingResponse.description) {
setTimeout(async () => {
this.showToast({
this.$showToast({
type: 'info',
title: onboardingResponse.title,
message: onboardingResponse.description,

View file

@ -508,12 +508,12 @@ import { nodeHelpers } from '@/mixins/nodeHelpers';
import { pinData } from '@/mixins/pinData';
import CodeNodeEditor from '@/components/CodeNodeEditor/CodeNodeEditor.vue';
import { dataPinningEventBus } from '@/event-bus';
import { clearJsonKey, executionDataToJson, stringSizeInBytes, isEmpty } from '@/utils';
import { clearJsonKey, executionDataToJson, stringSizeInBytes } from '@/utils';
import { isEmpty } from '@/utils';
import { useWorkflowsStore } from '@/stores/workflows.store';
import { mapStores } from 'pinia';
import { useNDVStore } from '@/stores/ndv.store';
import { useNodeTypesStore } from '@/stores/nodeTypes.store';
import { useToast } from '@/composables';
const RunDataTable = async () => import('@/components/RunDataTable.vue');
const RunDataJson = async () => import('@/components/RunDataJson.vue');
@ -585,11 +585,6 @@ export default mixins(externalHooks, genericHelpers, nodeHelpers, pinData).exten
default: false,
},
},
setup() {
return {
...useToast(),
};
},
data() {
return {
binaryDataPreviewActive: false,
@ -1077,7 +1072,7 @@ export default mixins(externalHooks, genericHelpers, nodeHelpers, pinData).exten
this.workflowsStore.pinData({ node: this.node, data: this.inputData });
if (this.maxRunIndex > 0) {
this.showToast({
this.$showToast({
title: this.$locale.baseText('ndv.pinData.pin.multipleRuns.title', {
interpolate: {
index: `${this.runIndex}`,

View file

@ -48,7 +48,6 @@ import { clearJsonKey, convertPath, executionDataToJson } from '@/utils';
import { mapStores } from 'pinia';
import { useWorkflowsStore } from '@/stores/workflows.store';
import { useNDVStore } from '@/stores/ndv.store';
import { useToast } from '@/composables';
type JsonPathData = {
path: string;
@ -91,11 +90,6 @@ export default mixins(genericHelpers, nodeHelpers, pinData, copyPaste).extend({
required: true,
},
},
setup() {
return {
...useToast(),
};
},
computed: {
...mapStores(useNDVStore, useWorkflowsStore),
activeNode(): INodeUi | null {
@ -158,7 +152,7 @@ export default mixins(genericHelpers, nodeHelpers, pinData, copyPaste).extend({
if (commandData.command === 'value') {
value = this.getJsonValue();
this.showToast({
this.$showToast({
title: this.$locale.baseText('runData.copyValue.toast'),
message: '',
type: 'success',
@ -172,7 +166,7 @@ export default mixins(genericHelpers, nodeHelpers, pinData, copyPaste).extend({
startPath = jsonItemPath.startPath;
path = jsonItemPath.path;
this.showToast({
this.$showToast({
title: this.$locale.baseText('runData.copyItemPath.toast'),
message: '',
type: 'success',
@ -183,7 +177,7 @@ export default mixins(genericHelpers, nodeHelpers, pinData, copyPaste).extend({
startPath = jsonParameterPath.startPath;
path = jsonParameterPath.path;
this.showToast({
this.$showToast({
title: this.$locale.baseText('runData.copyParameterPath.toast'),
message: '',
type: 'success',

View file

@ -47,9 +47,9 @@
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import { EnterpriseEditionFeature, MODAL_CONFIRM } from '@/constants';
import { useMessage } from '@/composables';
import mixins from 'vue-typed-mixins';
import { EnterpriseEditionFeature } from '@/constants';
import { showMessage } from '@/mixins/showMessage';
import { useLogStreamingStore } from '@/stores/logStreaming.store';
import type { PropType } from 'vue';
import { mapStores } from 'pinia';
@ -63,18 +63,13 @@ export const DESTINATION_LIST_ITEM_ACTIONS = {
DELETE: 'delete',
};
export default defineComponent({
export default mixins(showMessage).extend({
data() {
return {
EnterpriseEditionFeature,
nodeParameters: {} as MessageEventBusDestinationOptions,
};
},
setup() {
return {
...useMessage(),
};
},
components: {},
props: {
eventBus: {
@ -153,23 +148,17 @@ export default defineComponent({
if (action === DESTINATION_LIST_ITEM_ACTIONS.OPEN) {
this.$emit('edit', this.destination.id);
} else if (action === DESTINATION_LIST_ITEM_ACTIONS.DELETE) {
const deleteConfirmed = await this.confirm(
const deleteConfirmed = await this.confirmMessage(
this.$locale.baseText('settings.log-streaming.destinationDelete.message', {
interpolate: { destinationName: this.destination.label },
}),
this.$locale.baseText('settings.log-streaming.destinationDelete.headline'),
{
type: 'warning',
confirmButtonText: this.$locale.baseText(
'settings.log-streaming.destinationDelete.confirmButtonText',
),
cancelButtonText: this.$locale.baseText(
'settings.log-streaming.destinationDelete.cancelButtonText',
),
},
'warning',
this.$locale.baseText('settings.log-streaming.destinationDelete.confirmButtonText'),
this.$locale.baseText('settings.log-streaming.destinationDelete.cancelButtonText'),
);
if (deleteConfirmed !== MODAL_CONFIRM) {
if (deleteConfirmed === false) {
return;
}

View file

@ -174,11 +174,13 @@
<script lang="ts">
import { get, set, unset } from 'lodash-es';
import { mapStores } from 'pinia';
import mixins from 'vue-typed-mixins';
import { useLogStreamingStore } from '@/stores/logStreaming.store';
import { useNDVStore } from '@/stores/ndv.store';
import { useWorkflowsStore } from '@/stores/workflows.store';
import ParameterInputList from '@/components/ParameterInputList.vue';
import type { IMenuItem, INodeUi, IUpdateInformation } from '@/Interface';
import NodeCredentials from '@/components/NodeCredentials.vue';
import type { IMenuItem, INodeUi, ITab, IUpdateInformation } from '@/Interface';
import type {
IDataObject,
INodeCredentials,
@ -194,26 +196,27 @@ import {
defaultMessageEventBusDestinationSentryOptions,
} from 'n8n-workflow';
import type { PropType } from 'vue';
import Vue, { defineComponent } from 'vue';
import { LOG_STREAM_MODAL_KEY, MODAL_CONFIRM } from '@/constants';
import Vue from 'vue';
import { LOG_STREAM_MODAL_KEY } from '@/constants';
import Modal from '@/components/Modal.vue';
import { useMessage } from '@/composables';
import { showMessage } from '@/mixins/showMessage';
import { useUIStore } from '@/stores/ui.store';
import { useUsersStore } from '@/stores/users.store';
import { destinationToFakeINodeUi } from '@/components/SettingsLogStreaming/Helpers.ee';
import { destinationToFakeINodeUi } from './Helpers.ee';
import {
webhookModalDescription,
sentryModalDescription,
syslogModalDescription,
} from './descriptions.ee';
import type { BaseTextKey } from '@/plugins/i18n';
import InlineNameEdit from '@/components/InlineNameEdit.vue';
import SaveButton from '@/components/SaveButton.vue';
import InlineNameEdit from '../InlineNameEdit.vue';
import SaveButton from '../SaveButton.vue';
import EventSelection from '@/components/SettingsLogStreaming/EventSelection.ee.vue';
import { Checkbox } from 'element-ui';
import type { EventBus } from '@/event-bus';
import { createEventBus } from '@/event-bus';
export default defineComponent({
export default mixins(showMessage).extend({
name: 'event-destination-settings-modal',
props: {
modalName: String,
@ -229,14 +232,11 @@ export default defineComponent({
components: {
Modal,
ParameterInputList,
NodeCredentials,
InlineNameEdit,
SaveButton,
EventSelection,
},
setup() {
return {
...useMessage(),
};
Checkbox,
},
data() {
return {
@ -311,6 +311,18 @@ export default defineComponent({
}
return items;
},
tabItems(): ITab[] {
return [
{
label: this.$locale.baseText('settings.log-streaming.tab.settings'),
value: 'settings',
},
{
label: this.$locale.baseText('settings.log-streaming.tab.events'),
value: 'events',
},
];
},
},
mounted() {
this.isInstanceOwner = this.usersStore.currentUser?.globalRole?.name === 'owner';
@ -430,23 +442,17 @@ export default defineComponent({
this.testMessageSent = true;
},
async removeThis() {
const deleteConfirmed = await this.confirm(
const deleteConfirmed = await this.confirmMessage(
this.$locale.baseText('settings.log-streaming.destinationDelete.message', {
interpolate: { destinationName: this.destination.label },
}),
this.$locale.baseText('settings.log-streaming.destinationDelete.headline'),
{
type: 'warning',
confirmButtonText: this.$locale.baseText(
'settings.log-streaming.destinationDelete.confirmButtonText',
),
cancelButtonText: this.$locale.baseText(
'settings.log-streaming.destinationDelete.cancelButtonText',
),
},
'warning',
this.$locale.baseText('settings.log-streaming.destinationDelete.confirmButtonText'),
this.$locale.baseText('settings.log-streaming.destinationDelete.cancelButtonText'),
);
if (deleteConfirmed !== MODAL_CONFIRM) {
if (deleteConfirmed === false) {
return;
} else {
this.eventBus.emit('remove', this.destination.id);

View file

@ -55,12 +55,12 @@
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import mixins from 'vue-typed-mixins';
import type { ITag } from '@/Interface';
import { MAX_TAG_NAME_LENGTH, TAGS_MANAGER_MODAL_KEY } from '@/constants';
import { useToast } from '@/composables';
import { showMessage } from '@/mixins/showMessage';
import { mapStores } from 'pinia';
import { useUIStore } from '@/stores/ui.store';
import { useTagsStore } from '@/stores/tags.store';
@ -75,7 +75,7 @@ type CreateRef = InstanceType<typeof N8nOption>;
const MANAGE_KEY = '__manage';
const CREATE_KEY = '__create';
export default defineComponent({
export default mixins(showMessage).extend({
name: 'TagsDropdown',
props: {
placeholder: {},
@ -88,11 +88,6 @@ export default defineComponent({
type: Object as PropType<EventBus>,
},
},
setup() {
return {
...useToast(),
};
},
data() {
return {
filter: '',
@ -168,7 +163,7 @@ export default defineComponent({
this.$data.filter = '';
} catch (error) {
this.showError(
this.$showError(
error,
this.$locale.baseText('tagsDropdown.showError.title'),
this.$locale.baseText('tagsDropdown.showError.message', { interpolate: { name } }),

View file

@ -28,11 +28,11 @@
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import mixins from 'vue-typed-mixins';
import type { ITag } from '@/Interface';
import { useToast } from '@/composables';
import { showMessage } from '@/mixins/showMessage';
import TagsView from '@/components/TagsManager/TagsView/TagsView.vue';
import NoTagsView from '@/components/TagsManager/NoTagsView.vue';
import Modal from '@/components/Modal.vue';
@ -41,13 +41,8 @@ import { mapStores } from 'pinia';
import { useTagsStore } from '@/stores/tags.store';
import { createEventBus } from '@/event-bus';
export default defineComponent({
export default mixins(showMessage).extend({
name: 'TagsManager',
setup() {
return {
...useToast(),
};
},
created() {
void this.tagsStore.fetchAll({ force: true, withUsageCount: true });
},
@ -99,7 +94,7 @@ export default defineComponent({
cb(newTag);
} catch (error) {
const escapedName = escape(name);
this.showError(
this.$showError(
error,
this.$locale.baseText('tagsManager.showError.onCreate.title'),
this.$locale.baseText('tagsManager.showError.onCreate.message', {
@ -127,13 +122,13 @@ export default defineComponent({
const updatedTag = await this.tagsStore.rename({ id, name });
cb(!!updatedTag);
this.showMessage({
this.$showMessage({
title: this.$locale.baseText('tagsManager.showMessage.onUpdate.title'),
type: 'success',
});
} catch (error) {
const escapedName = escape(oldName);
this.showError(
this.$showError(
error,
this.$locale.baseText('tagsManager.showError.onUpdate.title'),
this.$locale.baseText('tagsManager.showError.onUpdate.message', {
@ -158,13 +153,13 @@ export default defineComponent({
cb(deleted);
this.showMessage({
this.$showMessage({
title: this.$locale.baseText('tagsManager.showMessage.onDelete.title'),
type: 'success',
});
} catch (error) {
const escapedName = escape(name);
this.showError(
this.$showError(
error,
this.$locale.baseText('tagsManager.showError.onDelete.title'),
this.$locale.baseText('tagsManager.showError.onDelete.message', {

View file

@ -106,12 +106,13 @@ import { EXECUTIONS_MODAL_KEY, WEBHOOK_NODE_TYPE, WORKFLOW_SETTINGS_MODAL_KEY }
import type { INodeUi } from '@/Interface';
import type { INodeTypeDescription } from 'n8n-workflow';
import { getTriggerNodeServiceName } from '@/utils';
import NodeExecuteButton from '@/components/NodeExecuteButton.vue';
import NodeExecuteButton from './NodeExecuteButton.vue';
import { workflowHelpers } from '@/mixins/workflowHelpers';
import mixins from 'vue-typed-mixins';
import CopyInput from '@/components/CopyInput.vue';
import NodeIcon from '@/components/NodeIcon.vue';
import CopyInput from './CopyInput.vue';
import NodeIcon from './NodeIcon.vue';
import { copyPaste } from '@/mixins/copyPaste';
import { showMessage } from '@/mixins/showMessage';
import { mapStores } from 'pinia';
import { useUIStore } from '@/stores/ui.store';
import { useWorkflowsStore } from '@/stores/workflows.store';
@ -121,7 +122,7 @@ import type { N8nInfoAccordion } from 'n8n-design-system';
type HelpRef = InstanceType<typeof N8nInfoAccordion>;
export default mixins(workflowHelpers, copyPaste).extend({
export default mixins(workflowHelpers, copyPaste, showMessage).extend({
name: 'TriggerPanel',
components: {
NodeExecuteButton,
@ -189,6 +190,18 @@ export default mixins(workflowHelpers, copyPaste).extend({
return this.getWebhookUrl(this.nodeType.webhooks[0], this.node, 'test');
},
webhookProdUrl(): string | undefined {
if (
!this.node ||
!this.nodeType ||
!this.nodeType.webhooks ||
!this.nodeType.webhooks.length
) {
return undefined;
}
return this.getWebhookUrl(this.nodeType.webhooks[0], this.node, 'prod');
},
isWebhookBasedNode(): boolean {
return Boolean(this.nodeType && this.nodeType.webhooks && this.nodeType.webhooks.length);
},

View file

@ -59,7 +59,7 @@
import { VALID_EMAIL_REGEX, VALUE_SURVEY_MODAL_KEY } from '@/constants';
import type { IN8nPromptResponse } from '@/Interface';
import ModalDrawer from '@/components/ModalDrawer.vue';
import ModalDrawer from './ModalDrawer.vue';
import mixins from 'vue-typed-mixins';
import { workflowHelpers } from '@/mixins/workflowHelpers';
@ -67,7 +67,6 @@ import { mapStores } from 'pinia';
import { useSettingsStore } from '@/stores/settings.store';
import { useRootStore } from '@/stores/n8nRoot.store';
import { createEventBus } from '@/event-bus';
import { useToast } from '@/composables';
const DEFAULT_TITLE = 'How likely are you to recommend n8n to a friend or colleague?';
const GREAT_FEEDBACK_TITLE =
@ -81,11 +80,6 @@ export default mixins(workflowHelpers).extend({
components: {
ModalDrawer,
},
setup() {
return {
...useToast(),
};
},
watch: {
isActive(isActive) {
if (isActive) {
@ -170,7 +164,7 @@ export default mixins(workflowHelpers).extend({
instance_id: this.rootStore.instanceId,
email: this.form.email,
});
this.showMessage({
this.$showMessage({
title: 'Thanks for your feedback',
message:
'If youd like to help even more, leave us a <a target="_blank" href="https://www.g2.com/products/n8n/reviews/start">review on G2</a>.',

View file

@ -50,7 +50,7 @@
</template>
<script lang="ts">
import { useToast } from '@/composables';
import { showMessage } from '@/mixins/showMessage';
import { workflowActivate } from '@/mixins/workflowActivate';
import { useUIStore } from '@/stores/ui.store';
import { useWorkflowsStore } from '@/stores/workflows.store';
@ -58,16 +58,14 @@ import { mapStores } from 'pinia';
import mixins from 'vue-typed-mixins';
import { getActivatableTriggerNodes } from '@/utils';
export default mixins(workflowActivate).extend({
export default mixins(showMessage, workflowActivate).extend({
name: 'WorkflowActivator',
props: ['workflowActive', 'workflowId'],
setup() {
return {
...useToast(),
};
},
computed: {
...mapStores(useUIStore, useWorkflowsStore),
getStateIsDirty(): boolean {
return this.uiStore.stateIsDirty;
},
nodesIssuesExist(): boolean {
return this.workflowsStore.nodesIssuesExist;
},
@ -125,7 +123,7 @@ export default mixins(workflowActivate).extend({
);
}
this.showMessage({
this.$showMessage({
title: this.$locale.baseText('workflowActivator.showMessage.displayActivationError.title'),
message: errorMessage,
type: 'warning',

View file

@ -62,16 +62,15 @@
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import mixins from 'vue-typed-mixins';
import type { IWorkflowDb, IUser, ITag } from '@/Interface';
import {
DUPLICATE_MODAL_KEY,
EnterpriseEditionFeature,
MODAL_CONFIRM,
VIEWS,
WORKFLOW_SHARE_MODAL_KEY,
} from '@/constants';
import { useToast, useMessage } from '@/composables';
import { showMessage } from '@/mixins/showMessage';
import type { IPermissions } from '@/permissions';
import { getWorkflowPermissions } from '@/permissions';
import dateformat from 'dateformat';
@ -91,18 +90,12 @@ export const WORKFLOW_LIST_ITEM_ACTIONS = {
DELETE: 'delete',
};
export default defineComponent({
export default mixins(showMessage).extend({
data() {
return {
EnterpriseEditionFeature,
};
},
setup() {
return {
...useToast(),
...useMessage(),
};
},
components: {
WorkflowActivator,
},
@ -225,35 +218,29 @@ export default defineComponent({
sub_view: this.$route.name === VIEWS.WORKFLOWS ? 'Workflows listing' : 'Workflow editor',
});
} else if (action === WORKFLOW_LIST_ITEM_ACTIONS.DELETE) {
const deleteConfirmed = await this.confirm(
const deleteConfirmed = await this.confirmMessage(
this.$locale.baseText('mainSidebar.confirmMessage.workflowDelete.message', {
interpolate: { workflowName: this.data.name },
}),
this.$locale.baseText('mainSidebar.confirmMessage.workflowDelete.headline'),
{
type: 'warning',
confirmButtonText: this.$locale.baseText(
'mainSidebar.confirmMessage.workflowDelete.confirmButtonText',
),
cancelButtonText: this.$locale.baseText(
'mainSidebar.confirmMessage.workflowDelete.cancelButtonText',
),
},
'warning',
this.$locale.baseText('mainSidebar.confirmMessage.workflowDelete.confirmButtonText'),
this.$locale.baseText('mainSidebar.confirmMessage.workflowDelete.cancelButtonText'),
);
if (deleteConfirmed !== MODAL_CONFIRM) {
if (deleteConfirmed === false) {
return;
}
try {
await this.workflowsStore.deleteWorkflow(this.data.id);
} catch (error) {
this.showError(error, this.$locale.baseText('generic.deleteWorkflowError'));
this.$showError(error, this.$locale.baseText('generic.deleteWorkflowError'));
return;
}
// Reset tab title since workflow is deleted.
this.showMessage({
this.$showMessage({
title: this.$locale.baseText('mainSidebar.showMessage.handleSelect1.title'),
type: 'success',
});

View file

@ -22,13 +22,13 @@
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import { useToast } from '@/composables';
import type { IWorkflowDb } from '@/Interface';
import mixins from 'vue-typed-mixins';
import { showMessage } from '@/mixins/showMessage';
import type { IWorkflowDb } from '../Interface';
import { mapStores } from 'pinia';
import { useRootStore } from '@/stores/n8nRoot.store';
export default defineComponent({
export default mixins(showMessage).extend({
name: 'WorkflowPreview',
props: {
loading: {
@ -58,11 +58,6 @@ export default defineComponent({
validator: (value: string): boolean => ['image', 'spinner'].includes(value),
},
},
setup() {
return {
...useToast(),
};
},
data() {
return {
nodeViewDetailsOpened: false,
@ -112,7 +107,7 @@ export default defineComponent({
);
}
} catch (error) {
this.showError(
this.$showError(
error,
this.$locale.baseText('workflowPreview.showError.previewError.title'),
this.$locale.baseText('workflowPreview.showError.previewError.message'),
@ -136,7 +131,7 @@ export default defineComponent({
);
}
} catch (error) {
this.showError(
this.$showError(
error,
this.$locale.baseText('workflowPreview.showError.previewError.title'),
this.$locale.baseText('workflowPreview.executionMode.showError.previewError.message'),

View file

@ -328,7 +328,7 @@ import Vue from 'vue';
import { externalHooks } from '@/mixins/externalHooks';
import { genericHelpers } from '@/mixins/genericHelpers';
import { useToast } from '@/composables';
import { showMessage } from '@/mixins/showMessage';
import type {
ITimeoutHMS,
IUser,
@ -337,12 +337,12 @@ import type {
IWorkflowSettings,
IWorkflowShortResponse,
} from '@/Interface';
import Modal from '@/components/Modal.vue';
import Modal from './Modal.vue';
import {
EnterpriseEditionFeature,
PLACEHOLDER_EMPTY_WORKFLOW_ID,
WORKFLOW_SETTINGS_MODAL_KEY,
} from '@/constants';
} from '../constants';
import mixins from 'vue-typed-mixins';
@ -356,16 +356,11 @@ import useWorkflowsEEStore from '@/stores/workflows.ee.store';
import { useUsersStore } from '@/stores/users.store';
import { createEventBus } from '@/event-bus';
export default mixins(externalHooks, genericHelpers).extend({
export default mixins(externalHooks, genericHelpers, showMessage).extend({
name: 'WorkflowSettings',
components: {
Modal,
},
setup() {
return {
...useToast(),
};
},
data() {
return {
isLoading: true,
@ -453,7 +448,7 @@ export default mixins(externalHooks, genericHelpers).extend({
this.maxExecutionTimeout = this.rootStore.maxExecutionTimeout;
if (!this.workflowId || this.workflowId === PLACEHOLDER_EMPTY_WORKFLOW_ID) {
this.showMessage({
this.$showMessage({
title: 'No workflow active',
message: 'No workflow active to display settings of.',
type: 'error',
@ -482,7 +477,7 @@ export default mixins(externalHooks, genericHelpers).extend({
try {
await Promise.all(promises);
} catch (error) {
this.showError(
this.$showError(
error,
'Problem loading settings',
'The following error occurred loading the data:',
@ -759,7 +754,7 @@ export default mixins(externalHooks, genericHelpers).extend({
data.settings!.executionTimeout !== -1 ? hours * 3600 + minutes * 60 + seconds : -1;
if (data.settings!.executionTimeout === 0) {
this.showError(
this.$showError(
new Error(this.$locale.baseText('workflowSettings.showError.saveSettings1.errorMessage')),
this.$locale.baseText('workflowSettings.showError.saveSettings1.title'),
this.$locale.baseText('workflowSettings.showError.saveSettings1.message') + ':',
@ -772,7 +767,7 @@ export default mixins(externalHooks, genericHelpers).extend({
const { hours, minutes, seconds } = this.convertToHMS(
this.workflowSettings.maxExecutionTimeout as number,
);
this.showError(
this.$showError(
new Error(
this.$locale.baseText('workflowSettings.showError.saveSettings2.errorMessage', {
interpolate: {
@ -796,7 +791,7 @@ export default mixins(externalHooks, genericHelpers).extend({
const workflow = await this.workflowsStore.updateWorkflow(this.$route.params.name, data);
this.workflowsStore.setWorkflowVersionId(workflow.versionId);
} catch (error) {
this.showError(
this.$showError(
error,
this.$locale.baseText('workflowSettings.showError.saveSettings3.title'),
);
@ -818,7 +813,7 @@ export default mixins(externalHooks, genericHelpers).extend({
this.isLoading = false;
this.showMessage({
this.$showMessage({
title: this.$locale.baseText('workflowSettings.showMessage.saveSettings.title'),
type: 'success',
});

View file

@ -126,16 +126,15 @@
import Modal from './Modal.vue';
import {
EnterpriseEditionFeature,
MODAL_CONFIRM,
PLACEHOLDER_EMPTY_WORKFLOW_ID,
VIEWS,
WORKFLOW_SHARE_MODAL_KEY,
} from '@/constants';
} from '../constants';
import type { IUser, IWorkflowDb } from '@/Interface';
import type { IPermissions } from '@/permissions';
import { getWorkflowPermissions } from '@/permissions';
import { defineComponent } from 'vue';
import { useToast, useMessage } from '@/composables';
import mixins from 'vue-typed-mixins';
import { showMessage } from '@/mixins/showMessage';
import { createEventBus, nodeViewEventBus } from '@/event-bus';
import { mapStores } from 'pinia';
import { useSettingsStore } from '@/stores/settings.store';
@ -148,7 +147,7 @@ import { useUsageStore } from '@/stores/usage.store';
import type { BaseTextKey } from '@/plugins/i18n';
import { isNavigationFailure } from 'vue-router';
export default defineComponent({
export default mixins(showMessage).extend({
name: 'workflow-share-modal',
components: {
Modal,
@ -159,12 +158,6 @@ export default defineComponent({
default: () => ({}),
},
},
setup() {
return {
...useToast(),
...useMessage(),
};
},
data() {
const workflowsStore = useWorkflowsStore();
const workflow =
@ -195,6 +188,11 @@ export default defineComponent({
isSharingEnabled(): boolean {
return this.settingsStore.isEnterpriseFeatureEnabled(EnterpriseEditionFeature.Sharing);
},
fallbackLinkUrl(): string {
return `${this.$locale.baseText(
this.uiStore.contextBasedTranslationKeys.upgradeLinkUrl as BaseTextKey,
)}${true ? '&utm_campaign=upgrade-workflow-sharing' : ''}`;
},
modalTitle(): string {
return this.$locale.baseText(
this.isSharingEnabled
@ -294,12 +292,12 @@ export default defineComponent({
sharees_removed: shareesRemoved.length,
});
this.showMessage({
this.$showMessage({
title: this.$locale.baseText('workflows.shareModal.onSave.success.title'),
type: 'success',
});
} catch (error) {
this.showError(error, this.$locale.baseText('workflows.shareModal.onSave.error.title'));
this.$showError(error, this.$locale.baseText('workflows.shareModal.onSave.error.title'));
} finally {
this.modalBus.emit('close');
this.loading = false;
@ -372,7 +370,7 @@ export default defineComponent({
let confirm = true;
if (!isNewSharee && isLastUserWithAccessToCredentials) {
const confirmAction = await this.confirm(
confirm = await this.confirmMessage(
this.$locale.baseText(
'workflows.shareModal.list.delete.confirm.lastUserWithAccessToCredentials.message',
{
@ -382,17 +380,10 @@ export default defineComponent({
this.$locale.baseText('workflows.shareModal.list.delete.confirm.title', {
interpolate: { name: user.fullName as string },
}),
{
confirmButtonText: this.$locale.baseText(
'workflows.shareModal.list.delete.confirm.confirmButtonText',
),
cancelButtonText: this.$locale.baseText(
'workflows.shareModal.list.delete.confirm.cancelButtonText',
),
},
null,
this.$locale.baseText('workflows.shareModal.list.delete.confirm.confirmButtonText'),
this.$locale.baseText('workflows.shareModal.list.delete.confirm.cancelButtonText'),
);
confirm = confirmAction === MODAL_CONFIRM;
}
if (confirm) {
@ -413,21 +404,15 @@ export default defineComponent({
},
async onCloseModal() {
if (this.isDirty) {
const shouldSave = await this.confirm(
const shouldSave = await this.confirmMessage(
this.$locale.baseText('workflows.shareModal.saveBeforeClose.message'),
this.$locale.baseText('workflows.shareModal.saveBeforeClose.title'),
{
type: 'warning',
confirmButtonText: this.$locale.baseText(
'workflows.shareModal.saveBeforeClose.confirmButtonText',
),
cancelButtonText: this.$locale.baseText(
'workflows.shareModal.saveBeforeClose.cancelButtonText',
),
},
'warning',
this.$locale.baseText('workflows.shareModal.saveBeforeClose.confirmButtonText'),
this.$locale.baseText('workflows.shareModal.saveBeforeClose.cancelButtonText'),
);
if (shouldSave === MODAL_CONFIRM) {
if (shouldSave) {
return this.onSave();
}
}

View file

@ -10,6 +10,7 @@ import ExecutionsList from '@/components/ExecutionsList.vue';
import { externalHooks } from '@/mixins/externalHooks';
import { genericHelpers } from '@/mixins/genericHelpers';
import { executionHelpers } from '@/mixins/executionsHelpers';
import { showMessage } from '@/mixins/showMessage';
import { i18nInstance } from '@/plugins/i18n';
import type { IWorkflowDb } from '@/Interface';
import type { IExecutionsSummary } from 'n8n-workflow';
@ -72,7 +73,7 @@ const renderOptions = {
}),
i18n: i18nInstance,
stubs: ['font-awesome-icon'],
mixins: [externalHooks, genericHelpers, executionHelpers],
mixins: [externalHooks, genericHelpers, executionHelpers, showMessage],
};
function TelemetryPlugin(vue: typeof Vue): void {

View file

@ -195,6 +195,7 @@
</template>
<script lang="ts">
import { showMessage } from '@/mixins/showMessage';
import type { IUser } from '@/Interface';
import mixins from 'vue-typed-mixins';
@ -236,7 +237,9 @@ interface IFilters {
type IResourceKeyType = 'credentials' | 'workflows';
type SearchRef = InstanceType<typeof N8nInput>;
export default mixins(debounceHelper).extend({
const filterKeys = ['ownedBy', 'sharedWith'];
export default mixins(showMessage, debounceHelper).extend({
name: 'resources-list-layout',
components: {
TemplateCard,

View file

@ -1,13 +1,8 @@
export { default as useCanvasMouseSelect } from './useCanvasMouseSelect';
export * from './useCopyToClipboard';
export * from './useDebounce';
export { default as useDeviceSupport } from './useDeviceSupport';
export * from './useExternalHooks';
export { default as useGlobalLinkActions } from './useGlobalLinkActions';
export * from './useHistoryHelper';
export * from './useGlobalLinkActions';
export * from './useI18n';
export * from './useMessage';
export * from './useTelemetry';
export * from './useTitleChange';
export * from './useToast';
export * from './useUpgradeLink';

View file

@ -3,7 +3,7 @@ import type { ElNotificationComponent, ElNotificationOptions } from 'element-ui/
import type { MessageType } from 'element-ui/types/message';
import { sanitizeHtml } from '@/utils';
import { useTelemetry } from '@/composables/useTelemetry';
import { useWorkflowsStore } from '@/stores/workflows.store';
import { useWorkflowsStore } from '@/stores';
import { useI18n } from './useI18n';
import { useExternalHooks } from './useExternalHooks';
@ -39,7 +39,6 @@ export function useToast() {
telemetry.track('Instance FE emitted error', {
error_title: messageData.title,
error_message: messageData.message,
caused_by_credential: causedByCredential(messageData.message),
workflow_id: workflowsStore.workflowId,
});
}
@ -131,36 +130,13 @@ export function useToast() {
error_title: title,
error_description: message,
error_message: error.message,
caused_by_credential: causedByCredential(error.message),
workflow_id: workflowsStore.workflowId,
});
}
function showAlert(config: ElNotificationOptions): ElNotificationComponent {
return Notification(config);
}
function causedByCredential(message: string | undefined) {
if (!message) return false;
return message.includes('Credentials for') && message.includes('are not set');
}
function clearAllStickyNotifications() {
stickyNotificationQueue.forEach((notification) => {
if (notification) {
notification.close();
}
});
stickyNotificationQueue.length = 0;
}
return {
showMessage,
showToast,
showError,
showAlert,
clearAllStickyNotifications,
};
}

View file

@ -304,7 +304,7 @@ export const ROLE_OTHER = 'other';
export const MODAL_CANCEL = 'cancel';
export const MODAL_CLOSE = 'close';
export const MODAL_CONFIRM = 'confirm';
export const MODAL_CONFIRMED = 'confirmed';
export const VALID_EMAIL_REGEX =
/^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;

View file

@ -1,15 +1,10 @@
import { defineComponent } from 'vue';
import mixins from 'vue-typed-mixins';
import dateformat from 'dateformat';
import { VIEWS } from '@/constants';
import { useToast } from '@/composables';
import { showMessage } from '@/mixins/showMessage';
export const genericHelpers = defineComponent({
setup() {
return {
...useToast(),
};
},
export const genericHelpers = mixins(showMessage).extend({
data() {
return {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
@ -51,7 +46,7 @@ export const genericHelpers = defineComponent({
},
editAllowedCheck(): boolean {
if (this.isReadOnly) {
this.showMessage({
this.$showMessage({
// title: 'Workflow can not be changed!',
title: this.$locale.baseText('genericHelpers.showMessage.title'),
message: this.$locale.baseText('genericHelpers.showMessage.message'),

View file

@ -1,16 +1,11 @@
import { defineComponent } from 'vue';
import { useToast } from '@/composables';
import mixins from 'vue-typed-mixins';
import { showMessage } from './showMessage';
import { VERSIONS_MODAL_KEY } from '@/constants';
import { mapStores } from 'pinia';
import { useUIStore } from '@/stores/ui.store';
import { useVersionsStore } from '@/stores/versions.store';
export const newVersions = defineComponent({
setup() {
return {
...useToast(),
};
},
export const newVersions = mixins(showMessage).extend({
computed: {
...mapStores(useUIStore, useVersionsStore),
},
@ -33,7 +28,7 @@ export const newVersions = defineComponent({
}
message = `${message} <a class="primary-color">More info</a>`;
this.showToast({
this.$showToast({
title: 'Critical update available',
message,
onClick: () => {

View file

@ -5,7 +5,6 @@ import { stringSizeInBytes } from '@/utils';
import { MAX_WORKFLOW_PINNED_DATA_SIZE, PIN_DATA_NODE_TYPES_DENYLIST } from '@/constants';
import { mapStores } from 'pinia';
import { useWorkflowsStore } from '@/stores/workflows.store';
import { useToast } from '@/composables';
export interface IPinDataContext {
node: INodeUi;
@ -14,11 +13,6 @@ export interface IPinDataContext {
}
export const pinData = (Vue as Vue.VueConstructor<Vue & IPinDataContext>).extend({
setup() {
return {
...useToast(),
};
},
computed: {
...mapStores(useWorkflowsStore),
pinData(): IPinData[string] | undefined {
@ -78,7 +72,7 @@ export const pinData = (Vue as Vue.VueConstructor<Vue & IPinDataContext>).extend
})} ${error.message}`;
}
this.showError(error, title);
this.$showError(error, title);
return false;
}
@ -90,7 +84,7 @@ export const pinData = (Vue as Vue.VueConstructor<Vue & IPinDataContext>).extend
this.workflowsStore.pinDataSize + stringSizeInBytes(data) >
MAX_WORKFLOW_PINNED_DATA_SIZE
) {
this.showError(
this.$showError(
new Error(this.$locale.baseText('ndv.pinData.error.tooLarge.description')),
this.$locale.baseText('ndv.pinData.error.tooLarge.title'),
);

View file

@ -7,7 +7,8 @@ import type {
import { externalHooks } from '@/mixins/externalHooks';
import { nodeHelpers } from '@/mixins/nodeHelpers';
import { useTitleChange, useToast } from '@/composables';
import { showMessage } from '@/mixins/showMessage';
import { useTitleChange } from '@/composables/useTitleChange';
import { workflowHelpers } from '@/mixins/workflowHelpers';
import type {
@ -18,7 +19,6 @@ import type {
IRunExecutionData,
IWorkflowBase,
SubworkflowOperationError,
IExecuteContextData,
} from 'n8n-workflow';
import { TelemetryHelpers } from 'n8n-workflow';
@ -35,11 +35,15 @@ import { useSettingsStore } from '@/stores/settings.store';
import { parse } from 'flatted';
import { useSegment } from '@/stores/segment.store';
export const pushConnection = mixins(externalHooks, nodeHelpers, workflowHelpers).extend({
export const pushConnection = mixins(
externalHooks,
nodeHelpers,
showMessage,
workflowHelpers,
).extend({
setup() {
return {
...useTitleChange(),
...useToast(),
};
},
data() {
@ -320,7 +324,7 @@ export const pushConnection = mixins(externalHooks, nodeHelpers, workflowHelpers
const runDataExecuted = pushData.data;
let runDataExecutedErrorMessage = this.getExecutionError(runDataExecuted.data);
let runDataExecutedErrorMessage = this.$getExecutionError(runDataExecuted.data);
if (pushData.data.status === 'crashed') {
runDataExecutedErrorMessage = this.$locale.baseText(
@ -363,7 +367,7 @@ export const pushConnection = mixins(externalHooks, nodeHelpers, workflowHelpers
// Workflow did start but had been put to wait
this.titleSet(workflow.name as string, 'IDLE');
this.showToast({
this.$showToast({
title: 'Workflow started waiting',
message: `${action} <a href="https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.wait/" target="_blank">More info</a>`,
type: 'success',
@ -418,7 +422,7 @@ export const pushConnection = mixins(externalHooks, nodeHelpers, workflowHelpers
this.workflowsStore.subWorkflowExecutionError = error;
this.showMessage({
this.$showMessage({
title: error.message,
message: error.description,
type: 'error',
@ -432,7 +436,7 @@ export const pushConnection = mixins(externalHooks, nodeHelpers, workflowHelpers
title = 'Problem executing workflow';
}
this.showMessage({
this.$showMessage({
title,
message: runDataExecutedErrorMessage,
type: 'error',
@ -455,7 +459,7 @@ export const pushConnection = mixins(externalHooks, nodeHelpers, workflowHelpers
execution.data.resultData.runData &&
execution.data.resultData.runData[execution.executedNode];
if (nodeType && nodeType.polling && !nodeOutput) {
this.showMessage({
this.$showMessage({
title: this.$locale.baseText('pushConnection.pollingNode.dataNotFound', {
interpolate: {
service: getTriggerNodeServiceName(nodeType),
@ -469,13 +473,13 @@ export const pushConnection = mixins(externalHooks, nodeHelpers, workflowHelpers
type: 'success',
});
} else {
this.showMessage({
this.$showMessage({
title: this.$locale.baseText('pushConnection.nodeExecutedSuccessfully'),
type: 'success',
});
}
} else {
this.showMessage({
this.$showMessage({
title: this.$locale.baseText('pushConnection.workflowExecutedSuccessfully'),
type: 'success',
});
@ -578,38 +582,5 @@ export const pushConnection = mixins(externalHooks, nodeHelpers, workflowHelpers
}
return true;
},
getExecutionError(data: IRunExecutionData | IExecuteContextData) {
const error = data.resultData.error;
let errorMessage: string;
if (data.resultData.lastNodeExecuted && error) {
errorMessage = error.message || error.description;
} else {
errorMessage = this.$locale.baseText('pushConnection.executionError', {
interpolate: { error: '!' },
});
if (error && error.message) {
let nodeName: string | undefined;
if ('node' in error) {
nodeName = typeof error.node === 'string' ? error.node : error.node!.name;
}
const receivedError = nodeName ? `${nodeName}: ${error.message}` : error.message;
errorMessage = this.$locale.baseText('pushConnection.executionError', {
interpolate: {
error: `.${this.$locale.baseText('pushConnection.executionError.details', {
interpolate: {
details: receivedError,
},
})}`,
},
});
}
}
return errorMessage;
},
},
});

View file

@ -0,0 +1,235 @@
// @ts-ignore
import type { ElNotificationComponent, ElNotificationOptions } from 'element-ui/types/notification';
import mixins from 'vue-typed-mixins';
import { externalHooks } from '@/mixins/externalHooks';
import type { IExecuteContextData, IRunExecutionData } from 'n8n-workflow';
import type { ElMessageBoxOptions } from 'element-ui/types/message-box';
import type { ElMessageComponent, ElMessageOptions, MessageType } from 'element-ui/types/message';
import { sanitizeHtml } from '@/utils';
import { mapStores } from 'pinia';
import { useWorkflowsStore } from '@/stores/workflows.store';
let stickyNotificationQueue: ElNotificationComponent[] = [];
export const showMessage = mixins(externalHooks).extend({
computed: {
...mapStores(useWorkflowsStore),
},
methods: {
$showMessage(
messageData: Omit<ElNotificationOptions, 'message'> & { message?: string },
track = true,
) {
messageData.dangerouslyUseHTMLString = true;
messageData.message = messageData.message
? sanitizeHtml(messageData.message)
: messageData.message;
if (messageData.position === undefined) {
messageData.position = 'bottom-right';
}
const notification = this.$notify(messageData as ElNotificationOptions);
if (messageData.duration === 0) {
stickyNotificationQueue.push(notification);
}
if (messageData.type === 'error' && track) {
this.$telemetry.track('Instance FE emitted error', {
error_title: messageData.title,
error_message: messageData.message,
caused_by_credential: this.causedByCredential(messageData.message),
workflow_id: this.workflowsStore.workflowId,
});
}
return notification;
},
$showToast(config: {
title: string;
message: string;
onClick?: () => void;
onClose?: () => void;
duration?: number;
customClass?: string;
closeOnClick?: boolean;
type?: MessageType;
}) {
// eslint-disable-next-line prefer-const
let notification: ElNotificationComponent;
if (config.closeOnClick) {
const cb = config.onClick;
config.onClick = () => {
if (notification) {
notification.close();
}
if (cb) {
cb();
}
};
}
notification = this.$showMessage({
title: config.title,
message: config.message,
onClick: config.onClick,
onClose: config.onClose,
duration: config.duration,
customClass: config.customClass,
type: config.type,
});
return notification;
},
$showAlert(config: ElMessageOptions): ElMessageComponent {
return this.$message(config);
},
$getExecutionError(data: IRunExecutionData | IExecuteContextData) {
const error = data.resultData.error;
let errorMessage: string;
if (data.resultData.lastNodeExecuted && error) {
errorMessage = error.message || error.description;
} else {
errorMessage = 'There was a problem executing the workflow!';
if (error && error.message) {
let nodeName: string | undefined;
if ('node' in error) {
nodeName = typeof error.node === 'string' ? error.node : error.node!.name;
}
const receivedError = nodeName ? `${nodeName}: ${error.message}` : error.message;
errorMessage = `There was a problem executing the workflow:<br /><strong>"${receivedError}"</strong>`;
}
}
return errorMessage;
},
$showError(e: Error | unknown, title: string, message?: string) {
const error = e as Error;
const messageLine = message ? `${message}<br/>` : '';
this.$showMessage(
{
title,
message: `
${messageLine}
<i>${error.message}</i>
${this.collapsableDetails(error)}`,
type: 'error',
duration: 0,
},
false,
);
void this.$externalHooks().run('showMessage.showError', {
title,
message,
errorMessage: error.message,
});
this.$telemetry.track('Instance FE emitted error', {
error_title: title,
error_description: message,
error_message: error.message,
caused_by_credential: this.causedByCredential(error.message),
workflow_id: this.workflowsStore.workflowId,
});
},
async confirmMessage(
message: string,
headline: string,
type: MessageType | null = 'warning',
confirmButtonText?: string,
cancelButtonText?: string,
): Promise<boolean> {
try {
const options: ElMessageBoxOptions = {
confirmButtonText: confirmButtonText || this.$locale.baseText('showMessage.ok'),
cancelButtonText: cancelButtonText || this.$locale.baseText('showMessage.cancel'),
dangerouslyUseHTMLString: true,
...(type && { type }),
};
const sanitizedMessage = sanitizeHtml(message);
await this.$confirm(sanitizedMessage, headline, options);
return true;
} catch (e) {
return false;
}
},
async confirmModal(
message: string,
headline: string,
type: MessageType | null = 'warning',
confirmButtonText?: string,
cancelButtonText?: string,
showClose = false,
): Promise<string> {
try {
const options: ElMessageBoxOptions = {
confirmButtonText: confirmButtonText || this.$locale.baseText('showMessage.ok'),
cancelButtonText: cancelButtonText || this.$locale.baseText('showMessage.cancel'),
dangerouslyUseHTMLString: true,
showClose,
...(type && { type }),
};
const sanitizedMessage = sanitizeHtml(message);
await this.$confirm(sanitizedMessage, headline, options);
return 'confirmed';
} catch (e) {
return e as string;
}
},
clearAllStickyNotifications() {
stickyNotificationQueue.map((notification: ElNotificationComponent) => {
if (notification) {
notification.close();
}
});
stickyNotificationQueue = [];
},
// @ts-ignore
collapsableDetails({ description, node }: Error) {
if (!description) return '';
const errorDescription =
description.length > 500 ? `${description.slice(0, 500)}...` : description;
return `
<br>
<br>
<details>
<summary
style="color: #ff6d5a; font-weight: bold; cursor: pointer;"
>
${this.$locale.baseText('showMessage.showDetails')}
</summary>
<p>${node.name}: ${errorDescription}</p>
</details>
`;
},
/**
* Whether a workflow execution error was caused by a credential issue, as reflected by the error message.
*/
causedByCredential(message: string | undefined) {
if (!message) return false;
return message.includes('Credentials for') && message.includes('are not set');
},
},
});

View file

@ -1,6 +1,6 @@
import { externalHooks } from '@/mixins/externalHooks';
import { workflowHelpers } from '@/mixins/workflowHelpers';
import { useToast } from '@/composables';
import { showMessage } from '@/mixins/showMessage';
import mixins from 'vue-typed-mixins';
import {
@ -13,12 +13,7 @@ import { useUIStore } from '@/stores/ui.store';
import { useSettingsStore } from '@/stores/settings.store';
import { useWorkflowsStore } from '@/stores/workflows.store';
export const workflowActivate = mixins(externalHooks, workflowHelpers).extend({
setup() {
return {
...useToast(),
};
},
export const workflowActivate = mixins(externalHooks, workflowHelpers, showMessage).extend({
data() {
return {
updatingWorkflowActivation: false,
@ -65,7 +60,7 @@ export const workflowActivate = mixins(externalHooks, workflowHelpers).extend({
try {
if (isWorkflowActive && newActiveState) {
this.showMessage({
this.$showMessage({
title: this.$locale.baseText('workflowActivator.workflowIsActive'),
type: 'success',
});
@ -75,7 +70,7 @@ export const workflowActivate = mixins(externalHooks, workflowHelpers).extend({
}
if (isCurrentWorkflow && nodesIssuesExist && newActiveState === true) {
this.showMessage({
this.$showMessage({
title: this.$locale.baseText(
'workflowActivator.showMessage.activeChangedNodesIssuesExistTrue.title',
),
@ -92,7 +87,7 @@ export const workflowActivate = mixins(externalHooks, workflowHelpers).extend({
await this.updateWorkflow({ workflowId: currWorkflowId, active: newActiveState });
} catch (error) {
const newStateName = newActiveState === true ? 'activated' : 'deactivated';
this.showError(
this.$showError(
error,
this.$locale.baseText('workflowActivator.showError.title', {
interpolate: { newStateName },

View file

@ -4,7 +4,6 @@ import {
WEBHOOK_NODE_TYPE,
VIEWS,
EnterpriseEditionFeature,
MODAL_CONFIRM,
} from '@/constants';
import type {
@ -41,7 +40,7 @@ import type {
import { externalHooks } from '@/mixins/externalHooks';
import { nodeHelpers } from '@/mixins/nodeHelpers';
import { useToast, useMessage } from '@/composables';
import { showMessage } from '@/mixins/showMessage';
import { isEqual } from 'lodash-es';
@ -321,13 +320,7 @@ function executeData(
return executeData;
}
export const workflowHelpers = mixins(externalHooks, nodeHelpers).extend({
setup() {
return {
...useToast(),
...useMessage(),
};
},
export const workflowHelpers = mixins(externalHooks, nodeHelpers, showMessage).extend({
computed: {
...mapStores(
useNodeTypesStore,
@ -748,31 +741,26 @@ export const workflowHelpers = mixins(externalHooks, nodeHelpers).extend({
params: { name: currentWorkflow },
}).href;
const overwrite = await this.confirm(
const overwrite = await this.confirmMessage(
this.$locale.baseText('workflows.concurrentChanges.confirmMessage.message', {
interpolate: {
url,
},
}),
this.$locale.baseText('workflows.concurrentChanges.confirmMessage.title'),
{
confirmButtonText: this.$locale.baseText(
'workflows.concurrentChanges.confirmMessage.confirmButtonText',
),
cancelButtonText: this.$locale.baseText(
'workflows.concurrentChanges.confirmMessage.cancelButtonText',
),
},
null,
this.$locale.baseText('workflows.concurrentChanges.confirmMessage.confirmButtonText'),
this.$locale.baseText('workflows.concurrentChanges.confirmMessage.cancelButtonText'),
);
if (overwrite === MODAL_CONFIRM) {
if (overwrite) {
return this.saveCurrentWorkflow({ id, name, tags }, redirect, true);
}
return false;
}
this.showMessage({
this.$showMessage({
title: this.$locale.baseText('workflowHelpers.showMessage.title'),
message: error.message,
type: 'error',
@ -902,7 +890,7 @@ export const workflowHelpers = mixins(externalHooks, nodeHelpers).extend({
} catch (e) {
this.uiStore.removeActiveAction('workflowSaving');
this.showMessage({
this.$showMessage({
title: this.$locale.baseText('workflowHelpers.showMessage.title'),
message: (e as Error).message,
type: 'error',

View file

@ -5,7 +5,7 @@ import { NodeHelpers, TelemetryHelpers } from 'n8n-workflow';
import { externalHooks } from '@/mixins/externalHooks';
import { workflowHelpers } from '@/mixins/workflowHelpers';
import { useToast } from '@/composables';
import { showMessage } from '@/mixins/showMessage';
import mixins from 'vue-typed-mixins';
import { useTitleChange } from '@/composables/useTitleChange';
@ -14,11 +14,10 @@ import { useUIStore } from '@/stores/ui.store';
import { useWorkflowsStore } from '@/stores/workflows.store';
import { useRootStore } from '@/stores/n8nRoot.store';
export const workflowRun = mixins(externalHooks, workflowHelpers).extend({
export const workflowRun = mixins(externalHooks, workflowHelpers, showMessage).extend({
setup() {
return {
...useTitleChange(),
...useToast(),
};
},
computed: {
@ -107,7 +106,7 @@ export const workflowRun = mixins(externalHooks, workflowHelpers).extend({
trackNodeIssues.push(trackNodeIssue);
}
this.showMessage({
this.$showMessage({
title: this.$locale.baseText('workflowRun.showMessage.title'),
message: errorMessages.join('<br />'),
type: 'error',
@ -240,7 +239,7 @@ export const workflowRun = mixins(externalHooks, workflowHelpers).extend({
return runWorkflowApiResponse;
} catch (error) {
this.titleSet(workflow.name as string, 'ERROR');
this.showError(error, this.$locale.baseText('workflowRun.showError.title'));
this.$showError(error, this.$locale.baseText('workflowRun.showError.title'));
return undefined;
}
},

View file

@ -1821,7 +1821,5 @@
"userActivationSurveyModal.sharedFeedback.success": "Thanks for your feedback",
"userActivationSurveyModal.sharedFeedback.error": "Problem sharing feedback, try again",
"sso.login.divider": "or",
"sso.login.button": "Continue with SSO",
"pushConnection.executionError": "There was a problem executing the workflow{error}",
"pushConnection.executionError.details": "<br /><strong>{details}</strong>"
"sso.login.button": "Continue with SSO"
}

View file

@ -9,25 +9,20 @@
</template>
<script lang="ts">
import AuthView from '@/views/AuthView.vue';
import { useToast } from '@/composables';
import AuthView from './AuthView.vue';
import { showMessage } from '@/mixins/showMessage';
import { defineComponent } from 'vue';
import mixins from 'vue-typed-mixins';
import type { IFormBoxConfig } from '@/Interface';
import { VIEWS } from '@/constants';
import { mapStores } from 'pinia';
import { useUsersStore } from '@/stores/users.store';
export default defineComponent({
export default mixins(showMessage).extend({
name: 'ChangePasswordView',
components: {
AuthView,
},
setup() {
return {
...useToast(),
};
},
data() {
return {
password: '',
@ -93,7 +88,7 @@ export default defineComponent({
await this.usersStore.validatePasswordToken({ token, userId });
} catch (e) {
this.showMessage({
this.$showMessage({
title: this.$locale.baseText('auth.changePassword.tokenValidationError'),
type: 'error',
});
@ -133,7 +128,7 @@ export default defineComponent({
if (token && userId) {
await this.usersStore.changePassword({ token, userId, password: this.password });
this.showMessage({
this.$showMessage({
type: 'success',
title: this.$locale.baseText('auth.changePassword.passwordUpdated'),
message: this.$locale.baseText('auth.changePassword.passwordUpdatedMessage'),
@ -141,13 +136,13 @@ export default defineComponent({
await this.$router.push({ name: VIEWS.SIGNIN });
} else {
this.showError(
this.$showError(
new Error(this.$locale.baseText('auth.validation.missingParameters')),
this.$locale.baseText('auth.changePassword.error'),
);
}
} catch (error) {
this.showError(error, this.$locale.baseText('auth.changePassword.error'));
this.$showError(error, this.$locale.baseText('auth.changePassword.error'));
}
this.loading = false;
},

View file

@ -44,12 +44,20 @@
</template>
<script lang="ts">
import { showMessage } from '@/mixins/showMessage';
import type { ICredentialsResponse, ICredentialTypeMap } from '@/Interface';
import { defineComponent } from 'vue';
import mixins from 'vue-typed-mixins';
import SettingsView from './SettingsView.vue';
import ResourcesListLayout from '@/components/layouts/ResourcesListLayout.vue';
import PageViewLayout from '@/components/layouts/PageViewLayout.vue';
import PageViewLayoutList from '@/components/layouts/PageViewLayoutList.vue';
import CredentialCard from '@/components/CredentialCard.vue';
import type { ICredentialType } from 'n8n-workflow';
import TemplateCard from '@/components/TemplateCard.vue';
import { debounceHelper } from '@/mixins/debounce';
import ResourceOwnershipSelect from '@/components/forms/ResourceOwnershipSelect.ee.vue';
import ResourceFiltersDropdown from '@/components/forms/ResourceFiltersDropdown.vue';
import { CREDENTIAL_SELECT_MODAL_KEY } from '@/constants';
import type Vue from 'vue';
import { mapStores } from 'pinia';
@ -60,11 +68,17 @@ import { useCredentialsStore } from '@/stores/credentials.store';
type IResourcesListLayoutInstance = Vue & { sendFiltersTelemetry: (source: string) => void };
export default defineComponent({
export default mixins(showMessage, debounceHelper).extend({
name: 'SettingsPersonalView',
components: {
ResourcesListLayout,
TemplateCard,
PageViewLayout,
PageViewLayoutList,
SettingsView,
CredentialCard,
ResourceOwnershipSelect,
ResourceFiltersDropdown,
},
data() {
return {

View file

@ -4,24 +4,19 @@
<script lang="ts">
import AuthView from './AuthView.vue';
import { useToast } from '@/composables';
import { showMessage } from '@/mixins/showMessage';
import { defineComponent } from 'vue';
import mixins from 'vue-typed-mixins';
import type { IFormBoxConfig } from '@/Interface';
import { mapStores } from 'pinia';
import { useSettingsStore } from '@/stores/settings.store';
import { useUsersStore } from '@/stores/users.store';
export default defineComponent({
export default mixins(showMessage).extend({
name: 'ForgotMyPasswordView',
components: {
AuthView,
},
setup() {
return {
...useToast(),
};
},
data() {
return {
loading: false,
@ -79,7 +74,7 @@ export default defineComponent({
this.loading = true;
await this.usersStore.sendForgotPasswordEmail(values);
this.showMessage({
this.$showMessage({
type: 'success',
title: this.$locale.baseText('forgotPassword.recoveryEmailSent'),
message: this.$locale.baseText('forgotPassword.emailSentIfExists', {
@ -91,7 +86,7 @@ export default defineComponent({
if (error.httpStatusCode === 422) {
message = this.$locale.baseText(error.message);
}
this.showMessage({
this.$showMessage({
type: 'error',
title: this.$locale.baseText('forgotPassword.sendingEmailError'),
message,

View file

@ -186,7 +186,7 @@ import {
MAIN_HEADER_TABS,
MODAL_CANCEL,
MODAL_CLOSE,
MODAL_CONFIRM,
MODAL_CONFIRMED,
NODE_OUTPUT_DEFAULT_KEY,
ONBOARDING_CALL_SIGNUP_MODAL_KEY,
ONBOARDING_PROMPT_TIMEBOX,
@ -206,15 +206,13 @@ import { copyPaste } from '@/mixins/copyPaste';
import { externalHooks } from '@/mixins/externalHooks';
import { genericHelpers } from '@/mixins/genericHelpers';
import { moveNodeWorkflow } from '@/mixins/moveNodeWorkflow';
import {
useGlobalLinkActions,
useCanvasMouseSelect,
useMessage,
useToast,
useTitleChange,
} from '@/composables';
import useGlobalLinkActions from '@/composables/useGlobalLinkActions';
import useCanvasMouseSelect from '@/composables/useCanvasMouseSelect';
import { showMessage } from '@/mixins/showMessage';
import { useTitleChange } from '@/composables/useTitleChange';
import { useUniqueNodeName } from '@/composables/useUniqueNodeName';
import { useI18n } from '@/composables/useI18n';
import { workflowHelpers } from '@/mixins/workflowHelpers';
import { workflowRun } from '@/mixins/workflowRun';
@ -324,6 +322,7 @@ export default mixins(
externalHooks,
genericHelpers,
moveNodeWorkflow,
showMessage,
workflowHelpers,
workflowRun,
debounceHelper,
@ -344,8 +343,6 @@ export default mixins(
...useCanvasMouseSelect(),
...useGlobalLinkActions(),
...useTitleChange(),
...useToast(),
...useMessage(),
...useUniqueNodeName(),
...useI18n(),
};
@ -418,21 +415,15 @@ export default mixins(
return;
}
if (this.uiStore.stateIsDirty) {
const confirmModal = await this.confirm(
const confirmModal = await this.confirmModal(
this.$locale.baseText('generic.unsavedWork.confirmMessage.message'),
{
title: this.$locale.baseText('generic.unsavedWork.confirmMessage.headline'),
type: 'warning',
confirmButtonText: this.$locale.baseText(
'generic.unsavedWork.confirmMessage.confirmButtonText',
),
cancelButtonText: this.$locale.baseText(
'generic.unsavedWork.confirmMessage.cancelButtonText',
),
showClose: true,
},
this.$locale.baseText('generic.unsavedWork.confirmMessage.headline'),
'warning',
this.$locale.baseText('generic.unsavedWork.confirmMessage.confirmButtonText'),
this.$locale.baseText('generic.unsavedWork.confirmMessage.cancelButtonText'),
true,
);
if (confirmModal === MODAL_CONFIRM) {
if (confirmModal === MODAL_CONFIRMED) {
// Make sure workflow id is empty when leaving the editor
this.workflowsStore.setWorkflowId(PLACEHOLDER_EMPTY_WORKFLOW_ID);
const saved = await this.saveCurrentWorkflow({}, false);
@ -669,7 +660,7 @@ export default mixins(
this.registerCustomAction('showNodeCreator', () =>
this.showTriggerCreator(NODE_CREATOR_OPEN_SOURCES.NO_TRIGGER_EXECUTION_TOOLTIP),
);
const notice = this.showMessage({
const notice = this.$showMessage({
type: 'info',
title: this.$locale.baseText('nodeView.cantExecuteNoTrigger'),
message,
@ -697,7 +688,7 @@ export default mixins(
saved = true;
}
if (saved) {
this.showMessage({
this.$showMessage({
title: this.$locale.baseText('generic.workflowSaved'),
type: 'success',
});
@ -717,7 +708,7 @@ export default mixins(
try {
data = await this.workflowsStore.getExecution(executionId);
} catch (error) {
this.showError(error, this.$locale.baseText('nodeView.showError.openExecution.title'));
this.$showError(error, this.$locale.baseText('nodeView.showError.openExecution.title'));
return;
}
if (data === undefined) {
@ -775,7 +766,7 @@ export default mixins(
}
}
if ((data as IExecutionsSummary).waitTill) {
this.showMessage({
this.$showMessage({
title: this.$locale.baseText('nodeView.thisExecutionHasntFinishedYet'),
message: `<a data-action="reload">${this.$locale.baseText(
'nodeView.refresh',
@ -828,7 +819,7 @@ export default mixins(
);
}
} catch (error) {
this.showError(error, this.$locale.baseText('nodeView.couldntImportWorkflow'));
this.$showError(error, this.$locale.baseText('nodeView.couldntImportWorkflow'));
void this.$router.replace({ name: VIEWS.NEW_WORKFLOW });
return;
}
@ -1039,7 +1030,7 @@ export default mixins(
void this.$router.push({ name: VIEWS.NEW_WORKFLOW });
}
this.showMessage({
this.$showMessage({
title: this.$locale.baseText('nodeView.showMessage.keyDown.title'),
type: 'success',
});
@ -1314,7 +1305,7 @@ export default mixins(
this.copyToClipboard(nodeData);
if (data.nodes.length > 0) {
if (!isCut) {
this.showMessage({
this.$showMessage({
title: 'Copied!',
message: '',
type: 'success',
@ -1336,7 +1327,7 @@ export default mixins(
try {
this.stopExecutionInProgress = true;
await this.workflowsStore.stopCurrentExecution(executionId);
this.showMessage({
this.$showMessage({
title: this.$locale.baseText('nodeView.showMessage.stopExecutionTry.title'),
type: 'success',
});
@ -1355,7 +1346,7 @@ export default mixins(
this.uiStore.removeActiveAction('workflowRunning');
this.titleSet(this.workflowsStore.workflowName, 'IDLE');
this.showMessage({
this.$showMessage({
title: this.$locale.baseText('nodeView.showMessage.stopExecutionCatch.unsaved.title'),
message: this.$locale.baseText(
'nodeView.showMessage.stopExecutionCatch.unsaved.message',
@ -1382,13 +1373,13 @@ export default mixins(
this.workflowsStore.executingNode = null;
this.workflowsStore.setWorkflowExecutionData(executedData as IExecutionResponse);
this.uiStore.removeActiveAction('workflowRunning');
this.showMessage({
this.$showMessage({
title: this.$locale.baseText('nodeView.showMessage.stopExecutionCatch.title'),
message: this.$locale.baseText('nodeView.showMessage.stopExecutionCatch.message'),
type: 'success',
});
} else {
this.showError(error, this.$locale.baseText('nodeView.showError.stopExecution.title'));
this.$showError(error, this.$locale.baseText('nodeView.showError.stopExecution.title'));
}
}
this.stopExecutionInProgress = false;
@ -1410,7 +1401,7 @@ export default mixins(
try {
await this.workflowsStore.removeTestWebhook(this.workflowsStore.workflowId);
} catch (error) {
this.showError(
this.$showError(
error,
this.$locale.baseText('nodeView.showError.stopWaitingForWebhook.title'),
);
@ -1435,23 +1426,19 @@ export default mixins(
return;
}
const importConfirm = await this.confirm(
const importConfirm = await this.confirmMessage(
this.$locale.baseText('nodeView.confirmMessage.receivedCopyPasteData.message', {
interpolate: { plainTextData },
}),
this.$locale.baseText('nodeView.confirmMessage.receivedCopyPasteData.headline'),
{
type: 'warning',
confirmButtonText: this.$locale.baseText(
'nodeView.confirmMessage.receivedCopyPasteData.confirmButtonText',
),
cancelButtonText: this.$locale.baseText(
'nodeView.confirmMessage.receivedCopyPasteData.cancelButtonText',
),
},
'warning',
this.$locale.baseText(
'nodeView.confirmMessage.receivedCopyPasteData.confirmButtonText',
),
this.$locale.baseText('nodeView.confirmMessage.receivedCopyPasteData.cancelButtonText'),
);
if (importConfirm !== MODAL_CONFIRM) {
if (!importConfirm) {
return;
}
@ -1488,7 +1475,7 @@ export default mixins(
workflowData = await this.workflowsStore.getWorkflowFromUrl(url);
} catch (error) {
this.stopLoading();
this.showError(
this.$showError(
error,
this.$locale.baseText('nodeView.showError.getWorkflowDataFromUrl.title'),
);
@ -1606,7 +1593,10 @@ export default mixins(
this.workflowsStore.addWorkflowTagIds(tagIds);
}
} catch (error) {
this.showError(error, this.$locale.baseText('nodeView.showError.importWorkflowData.title'));
this.$showError(
error,
this.$locale.baseText('nodeView.showError.importWorkflowData.title'),
);
}
},
onDragOver(event: DragEvent) {
@ -1670,7 +1660,7 @@ export default mixins(
},
showMaxNodeTypeError(nodeTypeData: INodeTypeDescription) {
const maxNodes = nodeTypeData.maxNodes;
this.showMessage({
this.$showMessage({
title: this.$locale.baseText('nodeView.showMessage.showMaxNodeTypeError.title'),
message: this.$locale.baseText('nodeView.showMessage.showMaxNodeTypeError.message', {
adjustToNumber: maxNodes,
@ -1780,7 +1770,7 @@ export default mixins(
this.nodeTypesStore.getNodeType(nodeTypeName);
if (nodeTypeData === null) {
this.showMessage({
this.$showMessage({
title: this.$locale.baseText('nodeView.showMessage.addNodeButton.title'),
message: this.$locale.baseText('nodeView.showMessage.addNodeButton.message', {
interpolate: { nodeTypeName },
@ -2500,21 +2490,15 @@ export default mixins(
} else {
const result = this.uiStore.stateIsDirty;
if (result) {
const confirmModal = await this.confirm(
const confirmModal = await this.confirmModal(
this.$locale.baseText('generic.unsavedWork.confirmMessage.message'),
{
title: this.$locale.baseText('generic.unsavedWork.confirmMessage.headline'),
type: 'warning',
confirmButtonText: this.$locale.baseText(
'generic.unsavedWork.confirmMessage.confirmButtonText',
),
cancelButtonText: this.$locale.baseText(
'generic.unsavedWork.confirmMessage.cancelButtonText',
),
showClose: true,
},
this.$locale.baseText('generic.unsavedWork.confirmMessage.headline'),
'warning',
this.$locale.baseText('generic.unsavedWork.confirmMessage.confirmButtonText'),
this.$locale.baseText('generic.unsavedWork.confirmMessage.cancelButtonText'),
true,
);
if (confirmModal === MODAL_CONFIRM) {
if (confirmModal === MODAL_CONFIRMED) {
const saved = await this.saveCurrentWorkflow();
if (saved) await this.settingsStore.fetchPromptsData();
} else if (confirmModal === MODAL_CLOSE) {
@ -2531,7 +2515,7 @@ export default mixins(
try {
workflow = await this.workflowsStore.fetchWorkflow(workflowId);
} catch (error) {
this.showError(error, this.$locale.baseText('openWorkflow.workflowNotFoundError'));
this.$showError(error, this.$locale.baseText('openWorkflow.workflowNotFoundError'));
void this.$router.push({
name: VIEWS.NEW_WORKFLOW,
@ -3015,7 +2999,7 @@ export default mixins(
},
async renameNodePrompt(currentName: string) {
try {
const promptResponsePromise = this.prompt(
const promptResponsePromise = this.$prompt(
this.$locale.baseText('nodeView.prompt.newName') + ':',
this.$locale.baseText('nodeView.prompt.renameNode') + `: ${currentName}`,
{
@ -3573,7 +3557,7 @@ export default mixins(
'*',
);
}
this.showMessage({
this.$showMessage({
title: this.$locale.baseText('openWorkflow.workflowImportError'),
message: (e as Error).message,
type: 'error',
@ -3597,7 +3581,7 @@ export default mixins(
'*',
);
}
this.showMessage({
this.$showMessage({
title: this.$locale.baseText('nodeView.showError.openExecution.title'),
message: (e as Error).message,
type: 'error',
@ -3796,7 +3780,7 @@ export default mixins(
try {
await Promise.all(loadPromises);
} catch (error) {
this.showError(
this.$showError(
error,
this.$locale.baseText('nodeView.showError.mounted1.title'),
this.$locale.baseText('nodeView.showError.mounted1.message') + ':',
@ -3816,7 +3800,7 @@ export default mixins(
);
}
} catch (error) {
this.showError(
this.$showError(
error,
this.$locale.baseText('nodeView.showError.mounted2.title'),
this.$locale.baseText('nodeView.showError.mounted2.message') + ':',
@ -3847,7 +3831,7 @@ export default mixins(
if (onboardingResponse.title && onboardingResponse.description) {
setTimeout(async () => {
this.showToast({
this.$showToast({
type: 'info',
title: onboardingResponse.title,
message: onboardingResponse.description,

View file

@ -75,28 +75,22 @@
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import { showMessage } from '@/mixins/showMessage';
import type { IUser } from '@/Interface';
import { useToast, useMessage } from '@/composables';
import mixins from 'vue-typed-mixins';
import CopyInput from '@/components/CopyInput.vue';
import { mapStores } from 'pinia';
import { useSettingsStore } from '@/stores/settings.store';
import { useRootStore } from '@/stores/n8nRoot.store';
import { useUsersStore } from '@/stores/users.store';
import { DOCS_DOMAIN, MODAL_CONFIRM } from '@/constants';
import { DOCS_DOMAIN } from '@/constants';
export default defineComponent({
export default mixins(showMessage).extend({
name: 'SettingsApiView',
components: {
CopyInput,
},
setup() {
return {
...useToast(),
...useMessage(),
};
},
data() {
return {
loading: false,
@ -124,15 +118,14 @@ export default defineComponent({
},
methods: {
async showDeleteModal() {
const confirmed = await this.confirm(
const confirmed = await this.confirmMessage(
this.$locale.baseText('settings.api.delete.description'),
this.$locale.baseText('settings.api.delete.title'),
{
confirmButtonText: this.$locale.baseText('settings.api.delete.button'),
cancelButtonText: this.$locale.baseText('generic.cancel'),
},
null,
this.$locale.baseText('settings.api.delete.button'),
this.$locale.baseText('generic.cancel'),
);
if (confirmed === MODAL_CONFIRM) {
if (confirmed) {
await this.deleteApiKey();
}
},
@ -140,7 +133,7 @@ export default defineComponent({
try {
this.apiKey = (await this.settingsStore.getApiKey()) || '';
} catch (error) {
this.showError(error, this.$locale.baseText('settings.api.view.error'));
this.$showError(error, this.$locale.baseText('settings.api.view.error'));
} finally {
this.mounted = true;
}
@ -151,7 +144,7 @@ export default defineComponent({
try {
this.apiKey = (await this.settingsStore.createApiKey()) || '';
} catch (error) {
this.showError(error, this.$locale.baseText('settings.api.create.error'));
this.$showError(error, this.$locale.baseText('settings.api.create.error'));
} finally {
this.loading = false;
this.$telemetry.track('User clicked create API key button');
@ -160,13 +153,13 @@ export default defineComponent({
async deleteApiKey() {
try {
await this.settingsStore.deleteApiKey();
this.showMessage({
this.$showMessage({
title: this.$locale.baseText('settings.api.delete.toast'),
type: 'success',
});
this.apiKey = '';
} catch (error) {
this.showError(error, this.$locale.baseText('settings.api.delete.error'));
this.$showError(error, this.$locale.baseText('settings.api.delete.error'));
} finally {
this.$telemetry.track('User clicked delete API key button');
}

View file

@ -58,7 +58,7 @@ import {
COMMUNITY_NODES_NPM_INSTALLATION_URL,
} from '@/constants';
import CommunityPackageCard from '@/components/CommunityPackageCard.vue';
import { useToast } from '@/composables';
import { showMessage } from '@/mixins/showMessage';
import { pushConnection } from '@/mixins/pushConnection';
import mixins from 'vue-typed-mixins';
import type { PublicInstalledPackage } from 'n8n-workflow';
@ -70,16 +70,11 @@ import { useSettingsStore } from '@/stores/settings.store';
const PACKAGE_COUNT_THRESHOLD = 31;
export default mixins(pushConnection).extend({
export default mixins(showMessage, pushConnection).extend({
name: 'SettingsCommunityNodesView',
components: {
CommunityPackageCard,
},
setup() {
return {
...useToast(),
};
},
data() {
return {
loading: false,
@ -118,7 +113,7 @@ export default mixins(pushConnection).extend({
number_of_updates_available: packagesToUpdate.length,
});
} catch (error) {
this.showError(
this.$showError(
error,
this.$locale.baseText('settings.communityNodes.fetchError.title'),
this.$locale.baseText('settings.communityNodes.fetchError.message'),

View file

@ -143,9 +143,8 @@
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import { convertToDisplayDate } from '@/utils';
import { useToast, useMessage } from '@/composables';
import { showMessage } from '@/mixins/showMessage';
import type {
ILdapConfig,
ILdapSyncData,
@ -154,7 +153,7 @@ import type {
IFormInputs,
IUser,
} from '@/Interface';
import { MODAL_CONFIRM } from '@/constants';
import mixins from 'vue-typed-mixins';
import humanizeDuration from 'humanize-duration';
import type { rowCallbackParams, cellCallbackParams } from 'element-ui/types/table';
@ -181,17 +180,11 @@ type rowType = rowCallbackParams & tableRow;
type cellType = cellCallbackParams & { property: keyof tableRow };
export default defineComponent({
export default mixins(showMessage).extend({
name: 'SettingsLdapView',
components: {
InfiniteLoading,
},
setup() {
return {
...useToast(),
...useMessage(),
};
},
data() {
return {
dataTable: [] as ILdapSyncTable[],
@ -308,20 +301,13 @@ export default defineComponent({
try {
if (this.adConfig.loginEnabled === true && newConfiguration.loginEnabled === false) {
const confirmAction = await this.confirm(
saveForm = await this.confirmMessage(
this.$locale.baseText('settings.ldap.confirmMessage.beforeSaveForm.message'),
this.$locale.baseText('settings.ldap.confirmMessage.beforeSaveForm.headline'),
{
cancelButtonText: this.$locale.baseText(
'settings.ldap.confirmMessage.beforeSaveForm.cancelButtonText',
),
confirmButtonText: this.$locale.baseText(
'settings.ldap.confirmMessage.beforeSaveForm.confirmButtonText',
),
},
null,
this.$locale.baseText('settings.ldap.confirmMessage.beforeSaveForm.cancelButtonText'),
this.$locale.baseText('settings.ldap.confirmMessage.beforeSaveForm.confirmButtonText'),
);
saveForm = confirmAction === MODAL_CONFIRM;
}
if (!saveForm) {
@ -329,13 +315,13 @@ export default defineComponent({
}
this.adConfig = await this.settingsStore.updateLdapConfig(newConfiguration);
this.showToast({
this.$showToast({
title: this.$locale.baseText('settings.ldap.updateConfiguration'),
message: '',
type: 'success',
});
} catch (error) {
this.showError(error, this.$locale.baseText('settings.ldap.configurationError'));
this.$showError(error, this.$locale.baseText('settings.ldap.configurationError'));
} finally {
if (saveForm) {
this.hasAnyChanges = false;
@ -349,13 +335,13 @@ export default defineComponent({
this.loadingTestConnection = true;
try {
await this.settingsStore.testLdapConnection();
this.showToast({
this.$showToast({
title: this.$locale.baseText('settings.ldap.connectionTest'),
message: this.$locale.baseText('settings.ldap.toast.connection.success'),
type: 'success',
});
} catch (error) {
this.showToast({
this.$showToast({
title: this.$locale.baseText('settings.ldap.connectionTestError'),
message: error.message,
type: 'error',
@ -368,13 +354,13 @@ export default defineComponent({
this.loadingDryRun = true;
try {
await this.settingsStore.runLdapSync({ type: 'dry' });
this.showToast({
this.$showToast({
title: this.$locale.baseText('settings.ldap.runSync.title'),
message: this.$locale.baseText('settings.ldap.toast.sync.success'),
type: 'success',
});
} catch (error) {
this.showError(error, this.$locale.baseText('settings.ldap.synchronizationError'));
this.$showError(error, this.$locale.baseText('settings.ldap.synchronizationError'));
} finally {
this.loadingDryRun = false;
await this.reloadLdapSynchronizations();
@ -384,13 +370,13 @@ export default defineComponent({
this.loadingLiveRun = true;
try {
await this.settingsStore.runLdapSync({ type: 'live' });
this.showToast({
this.$showToast({
title: this.$locale.baseText('settings.ldap.runSync.title'),
message: this.$locale.baseText('settings.ldap.toast.sync.success'),
type: 'success',
});
} catch (error) {
this.showError(error, this.$locale.baseText('settings.ldap.synchronizationError'));
this.$showError(error, this.$locale.baseText('settings.ldap.synchronizationError'));
} finally {
this.loadingLiveRun = false;
await this.reloadLdapSynchronizations();
@ -683,7 +669,7 @@ export default defineComponent({
},
];
} catch (error) {
this.showError(error, this.$locale.baseText('settings.ldap.configurationError'));
this.$showError(error, this.$locale.baseText('settings.ldap.configurationError'));
}
},
async getLdapSynchronizations(state: any) {
@ -702,7 +688,7 @@ export default defineComponent({
}
this.loadingTable = false;
} catch (error) {
this.showError(error, this.$locale.baseText('settings.ldap.synchronizationError'));
this.$showError(error, this.$locale.baseText('settings.ldap.synchronizationError'));
}
},
async reloadLdapSynchronizations() {
@ -711,7 +697,7 @@ export default defineComponent({
this.tableKey += 1;
this.dataTable = [];
} catch (error) {
this.showError(error, this.$locale.baseText('settings.ldap.synchronizationError'));
this.$showError(error, this.$locale.baseText('settings.ldap.synchronizationError'));
}
},
},

View file

@ -58,23 +58,18 @@
</template>
<script lang="ts">
import { useToast } from '@/composables';
import { showMessage } from '@/mixins/showMessage';
import { CHANGE_PASSWORD_MODAL_KEY } from '@/constants';
import type { IFormInputs, IUser } from '@/Interface';
import { useUIStore } from '@/stores/ui.store';
import { useUsersStore } from '@/stores/users.store';
import { useSettingsStore } from '@/stores/settings.store';
import { mapStores } from 'pinia';
import { defineComponent } from 'vue';
import mixins from 'vue-typed-mixins';
import { createEventBus } from '@/event-bus';
export default defineComponent({
export default mixins(showMessage).extend({
name: 'SettingsPersonalView',
setup() {
return {
...useToast(),
};
},
data() {
return {
hasAnyChanges: false,
@ -159,14 +154,14 @@ export default defineComponent({
lastName: form.lastName,
email: form.email,
});
this.showToast({
this.$showToast({
title: this.$locale.baseText('settings.personal.personalSettingsUpdated'),
message: '',
type: 'success',
});
this.hasAnyChanges = false;
} catch (e) {
this.showError(e, this.$locale.baseText('settings.personal.personalSettingsUpdatedError'));
this.$showError(e, this.$locale.baseText('settings.personal.personalSettingsUpdatedError'));
}
},
onSaveClick() {

View file

@ -61,10 +61,10 @@
<script lang="ts">
import { EnterpriseEditionFeature, INVITE_USER_MODAL_KEY, VIEWS } from '@/constants';
import PageAlert from '@/components/PageAlert.vue';
import PageAlert from '../components/PageAlert.vue';
import type { IUser, IUserListAction } from '@/Interface';
import mixins from 'vue-typed-mixins';
import { useToast } from '@/composables';
import { showMessage } from '@/mixins/showMessage';
import { copyPaste } from '@/mixins/copyPaste';
import { mapStores } from 'pinia';
import { useUIStore } from '@/stores/ui.store';
@ -73,16 +73,11 @@ import { useUsersStore } from '@/stores/users.store';
import { useUsageStore } from '@/stores/usage.store';
import { useSSOStore } from '@/stores/sso.store';
export default mixins(copyPaste).extend({
export default mixins(showMessage, copyPaste).extend({
name: 'SettingsUsersView',
components: {
PageAlert,
},
setup() {
return {
...useToast(),
};
},
async mounted() {
if (!this.usersStore.showUMSetupWarning) {
await this.usersStore.fetchUsers();
@ -131,7 +126,7 @@ export default mixins(copyPaste).extend({
try {
await this.usersStore.reinviteUser({ id: user.id });
this.showToast({
this.$showToast({
type: 'success',
title: this.$locale.baseText('settings.users.inviteResent'),
message: this.$locale.baseText('settings.users.emailSentTo', {
@ -139,7 +134,7 @@ export default mixins(copyPaste).extend({
}),
});
} catch (e) {
this.showError(e, this.$locale.baseText('settings.users.userReinviteError'));
this.$showError(e, this.$locale.baseText('settings.users.userReinviteError'));
}
}
},
@ -148,7 +143,7 @@ export default mixins(copyPaste).extend({
if (user?.inviteAcceptUrl) {
this.copyToClipboard(user.inviteAcceptUrl);
this.showToast({
this.$showToast({
type: 'success',
title: this.$locale.baseText('settings.users.inviteUrlCreated'),
message: this.$locale.baseText('settings.users.inviteUrlCreated.message'),

View file

@ -10,28 +10,22 @@
<script lang="ts">
import AuthView from './AuthView.vue';
import { defineComponent } from 'vue';
import { showMessage } from '@/mixins/showMessage';
import { useToast, useMessage } from '@/composables';
import mixins from 'vue-typed-mixins';
import type { IFormBoxConfig } from '@/Interface';
import { MODAL_CONFIRM, VIEWS } from '@/constants';
import { VIEWS } from '@/constants';
import { mapStores } from 'pinia';
import { useUIStore } from '@/stores/ui.store';
import { useSettingsStore } from '@/stores/settings.store';
import { useUsersStore } from '@/stores/users.store';
import { useCredentialsStore } from '@/stores/credentials.store';
export default defineComponent({
export default mixins(showMessage).extend({
name: 'SetupView',
components: {
AuthView,
},
setup() {
return {
...useToast(),
...useMessage(),
};
},
async mounted() {
const { credentials, workflows } = await this.usersStore.preOwnerSetup();
this.credentialsCount = credentials;
@ -132,20 +126,17 @@ export default defineComponent({
interpolate: { workflows, credentials },
})
: workflows || credentials;
const confirm = await this.confirm(
return this.confirmMessage(
this.$locale.baseText('auth.setup.confirmOwnerSetupMessage', {
interpolate: {
entities,
},
}),
this.$locale.baseText('auth.setup.confirmOwnerSetup'),
{
confirmButtonText: this.$locale.baseText('auth.setup.createAccount'),
cancelButtonText: this.$locale.baseText('auth.setup.goBack'),
},
null,
this.$locale.baseText('auth.setup.createAccount'),
this.$locale.baseText('auth.setup.goBack'),
);
return confirm === MODAL_CONFIRM;
},
async onSubmit(values: { [key: string]: string | boolean }) {
try {
@ -172,20 +163,19 @@ export default defineComponent({
await this.$router.push({ name: VIEWS.USERS_SETTINGS });
}
} catch (error) {
this.showError(error, this.$locale.baseText('auth.setup.settingUpOwnerError'));
this.$showError(error, this.$locale.baseText('auth.setup.settingUpOwnerError'));
}
this.loading = false;
},
async showSkipConfirmation() {
const skip = await this.confirm(
const skip = await this.confirmMessage(
this.$locale.baseText('auth.setup.ownerAccountBenefits'),
this.$locale.baseText('auth.setup.skipOwnerSetupQuestion'),
{
confirmButtonText: this.$locale.baseText('auth.setup.skipSetup'),
cancelButtonText: this.$locale.baseText('auth.setup.goBack'),
},
null,
this.$locale.baseText('auth.setup.skipSetup'),
this.$locale.baseText('auth.setup.goBack'),
);
if (skip === MODAL_CONFIRM) {
if (skip) {
this.onSkip();
}
},

View file

@ -9,26 +9,21 @@
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import AuthView from './AuthView.vue';
import { useToast } from '@/composables';
import { showMessage } from '@/mixins/showMessage';
import mixins from 'vue-typed-mixins';
import type { IFormBoxConfig } from '@/Interface';
import { VIEWS } from '@/constants';
import { mapStores } from 'pinia';
import { useUsersStore } from '@/stores/users.store';
import { useSettingsStore } from '@/stores/settings.store';
export default defineComponent({
export default mixins(showMessage).extend({
name: 'SigninView',
components: {
AuthView,
},
setup() {
return {
...useToast(),
};
},
data() {
return {
FORM_CONFIG: {} as IFormBoxConfig,
@ -102,7 +97,7 @@ export default defineComponent({
await this.$router.push({ name: VIEWS.HOMEPAGE });
} catch (error) {
this.showError(error, this.$locale.baseText('auth.signin.error'));
this.$showError(error, this.$locale.baseText('auth.signin.error'));
this.loading = false;
}
},

View file

@ -2,16 +2,11 @@
import { VIEWS } from '@/constants';
import { mapStores } from 'pinia';
import { useUsersStore } from '@/stores/users.store';
import { defineComponent } from 'vue';
import { useToast } from '@/composables';
import mixins from 'vue-typed-mixins';
import { showMessage } from '@/mixins/showMessage';
export default defineComponent({
export default mixins(showMessage).extend({
name: 'SignoutView',
setup() {
return {
...useToast(),
};
},
computed: {
...mapStores(useUsersStore),
},
@ -21,7 +16,7 @@ export default defineComponent({
await this.usersStore.logout();
void this.$router.replace({ name: VIEWS.SIGNIN });
} catch (e) {
this.showError(e, this.$locale.baseText('auth.signout.error'));
this.$showError(e, this.$locale.baseText('auth.signout.error'));
}
},
},

View file

@ -8,26 +8,21 @@
</template>
<script lang="ts">
import AuthView from '@/views/AuthView.vue';
import { useToast } from '@/composables';
import AuthView from './AuthView.vue';
import { showMessage } from '@/mixins/showMessage';
import { defineComponent } from 'vue';
import mixins from 'vue-typed-mixins';
import type { IFormBoxConfig } from '@/Interface';
import { VIEWS } from '@/constants';
import { mapStores } from 'pinia';
import { useUIStore } from '@/stores/ui.store';
import { useUsersStore } from '@/stores/users.store';
export default defineComponent({
export default mixins(showMessage).extend({
name: 'SignupView',
components: {
AuthView,
},
setup() {
return {
...useToast(),
};
},
data() {
const FORM_CONFIG: IFormBoxConfig = {
title: this.$locale.baseText('auth.signup.setupYourAccount'),
@ -101,7 +96,7 @@ export default defineComponent({
const invite = await this.usersStore.validateSignupToken({ inviteeId, inviterId });
this.inviter = invite.inviter as { firstName: string; lastName: string };
} catch (e) {
this.showError(e, this.$locale.baseText('auth.signup.tokenValidationError'));
this.$showError(e, this.$locale.baseText('auth.signup.tokenValidationError'));
void this.$router.replace({ name: VIEWS.SIGNIN });
}
},
@ -120,7 +115,7 @@ export default defineComponent({
methods: {
async onSubmit(values: { [key: string]: string | boolean }) {
if (!this.inviterId || !this.inviteeId) {
this.showError(
this.$showError(
new Error(this.$locale.baseText('auth.changePassword.tokenValidationError')),
this.$locale.baseText('auth.signup.setupYourAccountError'),
);
@ -149,7 +144,7 @@ export default defineComponent({
await this.$router.push({ name: VIEWS.NEW_WORKFLOW });
} catch (error) {
this.showError(error, this.$locale.baseText('auth.signup.setupYourAccountError'));
this.$showError(error, this.$locale.baseText('auth.signup.setupYourAccountError'));
}
this.loading = false;
},

View file

@ -78,7 +78,7 @@
import CollectionsCarousel from '@/components/CollectionsCarousel.vue';
import TemplateFilters from '@/components/TemplateFilters.vue';
import TemplateList from '@/components/TemplateList.vue';
import TemplatesView from '@/views/TemplatesView.vue';
import TemplatesView from './TemplatesView.vue';
import { genericHelpers } from '@/mixins/genericHelpers';
import type {
@ -97,7 +97,6 @@ import { useSettingsStore } from '@/stores/settings.store';
import { useUsersStore } from '@/stores/users.store';
import { useTemplatesStore } from '@/stores/templates.store';
import { useUIStore } from '@/stores/ui.store';
import { useToast } from '@/composables';
interface ISearchEvent {
search_string: string;
@ -115,11 +114,6 @@ export default mixins(genericHelpers, debounceHelper).extend({
TemplateList,
TemplatesView,
},
setup() {
return {
...useToast(),
};
},
data() {
return {
areCategoriesPrepopulated: false,
@ -293,7 +287,7 @@ export default mixins(genericHelpers, debounceHelper).extend({
search: this.search,
});
} catch (e) {
this.showMessage({
this.$showMessage({
title: 'Error',
message: 'Could not load more workflows',
type: 'error',

View file

@ -89,10 +89,17 @@
</template>
<script lang="ts">
import { defineComponent } from 'vue';
import { showMessage } from '@/mixins/showMessage';
import mixins from 'vue-typed-mixins';
import SettingsView from './SettingsView.vue';
import ResourcesListLayout from '@/components/layouts/ResourcesListLayout.vue';
import PageViewLayout from '@/components/layouts/PageViewLayout.vue';
import PageViewLayoutList from '@/components/layouts/PageViewLayoutList.vue';
import WorkflowCard from '@/components/WorkflowCard.vue';
import TemplateCard from '@/components/TemplateCard.vue';
import { EnterpriseEditionFeature, VIEWS } from '@/constants';
import { debounceHelper } from '@/mixins/debounce';
import type Vue from 'vue';
import type { ITag, IUser, IWorkflowDb } from '@/Interface';
import TagsDropdown from '@/components/TagsDropdown.vue';
@ -111,10 +118,14 @@ const StatusFilter = {
ALL: '',
};
const WorkflowsView = defineComponent({
const WorkflowsView = mixins(showMessage, debounceHelper).extend({
name: 'WorkflowsView',
components: {
ResourcesListLayout,
TemplateCard,
PageViewLayout,
PageViewLayoutList,
SettingsView,
WorkflowCard,
TagsDropdown,
},
@ -146,6 +157,9 @@ const WorkflowsView = defineComponent({
isShareable(): boolean {
return this.settingsStore.isEnterpriseFeatureEnabled(EnterpriseEditionFeature.Sharing);
},
hasActiveWorkflows(): boolean {
return !!this.workflowsStore.activeWorkflows.length;
},
statusFilterOptions(): Array<{ label: string; value: string | boolean }> {
return [
{