refactor: Workflow sharing bug bash fixes (#4888)

* fix: Prevent workflows with only manual trigger from being activated

* fix: Fix workflow id when sharing from workflows list

* fix: Update sharing modal translations

* fix: Allow sharees to disable workflows and fix issue with unique key when removing a user

* refactor: Improve error messages and change logging level to be less verbose

* fix: Broken user removal transfer issue

* feat: Implement workflow sharing BE telemetry

* chore: temporarily add sharing env vars

* feat: Implement BE telemetry for workflow sharing

* fix: Prevent issues with possibly missing workflow id

* feat: Replace WorkflowSharing flag references (no-changelog) (#4918)

* ci: Block all external network calls in tests (no-changelog) (#4930)

* setup nock to prevent tests from making any external requests

* mock all calls to posthog sdk

* feat: Replace WorkflowSharing flag references (no-changelog)

Co-authored-by: कारतोफ्फेलस्क्रिप्ट™ <netroy@users.noreply.github.com>

* refactor: Remove temporary feature flag for workflow sharing

* refactor: add sharing_role to both manual and node executions

* refactor: Allow changing name, position and disabled of read only nodes

* feat: Overhaul dynamic translations for local and cloud (#4943)

* feat: Overhaul dynamic translations for local and cloud

* fix: remove type casting

* chore: remove unused translations

* fix: fix workflow sharing translation

* test: Fix broken test

* refactor: remove unnecessary import

* refactor: Minor code improvements

* refactor: rename dynamicTranslations to contextBasedTranslationKeys

* fix: fix type imports

* refactor: Consolidate sharing feature check

* feat: update cred sharing unavailable translations

* feat: update upgrade message when user management not available

* fix: rename plan names to Pro and Power

* feat: update translations to no longer contain plan names

* wip: subworkflow permissions

* feat: add workflowsFromSameOwner caller policy

* feat: Fix subworkflow permissions

* shared entites should check for role when deleting users

* refactor: remove circular dependency

* role filter shouldn't be an array

* fixed role issue

* fix: Corrected behavior when removing users

* feat: show instance owner credential sharing message only if isnt sharee

* feat: update workflow caller policy caller ids labels

* feat: update upgrade plan links to contain instance ids

* fix: show check errors below creds message only to owner

* fix(editor): Hide usage page on cloud

* fix: update credential validation error message for sharee

* fix(core): Remove duplicate import

* fix(editor): Extending deployment types

* feat: Overhaul contextual translations (#4992)

feat: update how contextual translations work

* refactor: improve messageing for subworkflow permissions

* test: Fix issue with user deletion and transfer

* fix: Explicitly throw error message so it can be displayed in UI

Co-authored-by: Alex Grozav <alex@grozav.com>
Co-authored-by: कारतोफ्फेलस्क्रिप्ट™ <netroy@users.noreply.github.com>
Co-authored-by: freyamade <freya@n8n.io>
Co-authored-by: Csaba Tuncsik <csaba@n8n.io>
This commit is contained in:
Omar Ajoue
2022-12-21 16:42:07 +01:00
committed by GitHub
parent e225c3190e
commit 25e9f0817a
43 changed files with 597 additions and 344 deletions

View File

@@ -1,18 +1,23 @@
<template>
<Modal
width="460px"
:title="
$locale.baseText(dynamicTranslations.workflows.shareModal.title, {
interpolate: { name: workflow.name },
})
"
:title="modalTitle"
:eventBus="modalBus"
:name="WORKFLOW_SHARE_MODAL_KEY"
:center="true"
:beforeClose="onCloseModal"
>
<template #content>
<div v-if="isDefaultUser" :class="$style.container">
<div v-if="!isSharingEnabled" :class="$style.container">
<n8n-text>
{{
$locale.baseText(
contextBasedTranslationKeys.workflows.sharing.unavailable.description.modal,
)
}}
</n8n-text>
</div>
<div v-else-if="isDefaultUser" :class="$style.container">
<n8n-text>
{{ $locale.baseText('workflows.shareModal.isDefaultUser.description') }}
</n8n-text>
@@ -25,7 +30,7 @@
})
}}
</n8n-info-tip>
<enterprise-edition :features="[EnterpriseEditionFeature.WorkflowSharing]">
<enterprise-edition :features="[EnterpriseEditionFeature.Sharing]">
<n8n-user-select
v-if="workflowPermissions.updateSharing"
class="mb-s"
@@ -66,7 +71,7 @@
<template #fallback>
<n8n-text>
<i18n
:path="dynamicTranslations.workflows.sharing.unavailable.description"
:path="contextBasedTranslationKeys.workflows.sharing.unavailable.description"
tag="span"
>
<template #action />
@@ -78,14 +83,19 @@
</template>
<template #footer>
<div v-if="isDefaultUser" :class="$style.actionButtons">
<div v-if="!isSharingEnabled" :class="$style.actionButtons">
<n8n-button @click="goToUpgrade">
{{ $locale.baseText(contextBasedTranslationKeys.workflows.sharing.unavailable.button) }}
</n8n-button>
</div>
<div v-else-if="isDefaultUser" :class="$style.actionButtons">
<n8n-button @click="goToUsersSettings">
{{ $locale.baseText('workflows.shareModal.isDefaultUser.button') }}
</n8n-button>
</div>
<enterprise-edition
v-else
:features="[EnterpriseEditionFeature.WorkflowSharing]"
:features="[EnterpriseEditionFeature.Sharing]"
:class="$style.actionButtons"
>
<n8n-text v-show="isDirty" color="text-light" size="small" class="mr-xs">
@@ -102,9 +112,11 @@
</n8n-button>
<template #fallback>
<n8n-link :to="dynamicTranslations.workflows.sharing.unavailable.linkURL">
<n8n-link :to="contextBasedTranslationKeys.workflows.sharing.unavailable.linkUrl">
<n8n-button :loading="loading" size="medium">
{{ $locale.baseText(dynamicTranslations.workflows.sharing.unavailable.button) }}
{{
$locale.baseText(contextBasedTranslationKeys.workflows.sharing.unavailable.button)
}}
</n8n-button>
</n8n-link>
</template>
@@ -122,7 +134,7 @@ import {
VIEWS,
WORKFLOW_SHARE_MODAL_KEY,
} from '../constants';
import { IUser, IWorkflowDb, NestedRecord } from '@/Interface';
import { IUser, IWorkflowDb, UIState } from '@/Interface';
import { getWorkflowPermissions, IPermissions } from '@/permissions';
import mixins from 'vue-typed-mixins';
import { showMessage } from '@/mixins/showMessage';
@@ -134,6 +146,7 @@ import { useUsersStore } from '@/stores/users';
import { useWorkflowsStore } from '@/stores/workflows';
import { useWorkflowsEEStore } from '@/stores/workflows.ee';
import { ITelemetryTrackProperties } from 'n8n-workflow';
import { useUsageStore } from '@/stores/usage';
export default mixins(showMessage).extend({
name: 'workflow-share-modal',
@@ -166,12 +179,26 @@ export default mixins(showMessage).extend({
useSettingsStore,
useUIStore,
useUsersStore,
useUsageStore,
useWorkflowsStore,
useWorkflowsEEStore,
),
isDefaultUser(): boolean {
return this.usersStore.isDefaultUser;
},
isSharingEnabled(): boolean {
return this.settingsStore.isEnterpriseFeatureEnabled(EnterpriseEditionFeature.Sharing);
},
modalTitle(): string {
return this.$locale.baseText(
this.isSharingEnabled
? this.contextBasedTranslationKeys.workflows.sharing.title
: this.contextBasedTranslationKeys.workflows.sharing.unavailable.title,
{
interpolate: { name: this.workflow.name },
},
);
},
usersList(): IUser[] {
return this.usersStore.allUsers.filter((user: IUser) => {
const isCurrentUser = user.id === this.usersStore.currentUser?.id;
@@ -208,14 +235,8 @@ export default mixins(showMessage).extend({
workflowOwnerName(): string {
return this.workflowsEEStore.getWorkflowOwnerName(`${this.workflow.id}`);
},
isSharingAvailable(): boolean {
return (
this.settingsStore.isEnterpriseFeatureEnabled(EnterpriseEditionFeature.WorkflowSharing) ===
true
);
},
dynamicTranslations(): NestedRecord<string> {
return this.uiStore.dynamicTranslations;
contextBasedTranslationKeys(): UIState['contextBasedTranslationKeys'] {
return this.uiStore.contextBasedTranslationKeys;
},
isDirty(): boolean {
const previousSharedWith = this.workflow.sharedWith || [];
@@ -240,10 +261,10 @@ export default mixins(showMessage).extend({
return new Promise<string>((resolve) => {
if (this.workflow.id === PLACEHOLDER_EMPTY_WORKFLOW_ID) {
nodeViewEventBus.$emit('saveWorkflow', () => {
resolve(this.workflowsStore.workflowId);
resolve(this.workflow.id);
});
} else {
resolve(this.workflowsStore.workflowId);
resolve(this.workflow.id);
}
});
};
@@ -411,9 +432,17 @@ export default mixins(showMessage).extend({
...data,
});
},
goToUpgrade() {
let linkUrl = this.$locale.baseText(this.contextBasedTranslationKeys.upgradeLinkUrl);
if (linkUrl.includes('subscription')) {
linkUrl = this.usageStore.viewPlansUrl;
}
window.open(linkUrl, '_blank');
},
},
mounted() {
if (this.isSharingAvailable) {
if (this.isSharingEnabled) {
this.loadUsers();
}
},