refactor(editor): Fix remaining FE type check errors (no-changelog) (#9607)
Co-authored-by: Alex Grozav <alex@grozav.com>
This commit is contained in:
@@ -1115,8 +1115,6 @@ export default defineComponent({
|
||||
oauthTokenData: {} as CredentialInformation,
|
||||
};
|
||||
|
||||
this.credentialsStore.enableOAuthCredential(credential);
|
||||
|
||||
// Close the window
|
||||
if (oauthPopup) {
|
||||
oauthPopup.close();
|
||||
@@ -1164,7 +1162,7 @@ export default defineComponent({
|
||||
|
||||
this.credentialData = {
|
||||
...this.credentialData,
|
||||
scopes,
|
||||
scopes: scopes as unknown as CredentialInformation,
|
||||
homeProject,
|
||||
};
|
||||
},
|
||||
|
||||
@@ -72,7 +72,7 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import type { ICredentialsResponse, IUser, IUserListAction } from '@/Interface';
|
||||
import type { ICredentialsResponse, IUserListAction } from '@/Interface';
|
||||
import { defineComponent } from 'vue';
|
||||
import type { PropType } from 'vue';
|
||||
import { useMessage } from '@/composables/useMessage';
|
||||
@@ -157,22 +157,35 @@ export default defineComponent({
|
||||
credentialOwnerName(): string {
|
||||
return this.credentialsStore.getCredentialOwnerNameById(`${this.credentialId}`);
|
||||
},
|
||||
credentialDataHomeProject(): ProjectSharingData | undefined {
|
||||
const credentialContainsProjectSharingData = (
|
||||
data: ICredentialDataDecryptedObject,
|
||||
): data is { homeProject: ProjectSharingData } => {
|
||||
return 'homeProject' in data;
|
||||
};
|
||||
|
||||
return this.credentialData && credentialContainsProjectSharingData(this.credentialData)
|
||||
? this.credentialData.homeProject
|
||||
: undefined;
|
||||
},
|
||||
isCredentialSharedWithCurrentUser(): boolean {
|
||||
return (this.credentialData.sharedWithProjects ?? []).some((sharee: IUser) => {
|
||||
return sharee.id === this.usersStore.currentUser?.id;
|
||||
if (!Array.isArray(this.credentialData.sharedWithProjects)) return false;
|
||||
|
||||
return this.credentialData.sharedWithProjects.some((sharee) => {
|
||||
return typeof sharee === 'object' && 'id' in sharee
|
||||
? sharee.id === this.usersStore.currentUser?.id
|
||||
: false;
|
||||
});
|
||||
},
|
||||
projects(): ProjectListItem[] {
|
||||
return this.projectsStore.personalProjects.filter(
|
||||
(project) =>
|
||||
project.id !== this.credential?.homeProject?.id &&
|
||||
project.id !== this.credentialData?.homeProject?.id,
|
||||
project.id !== this.credentialDataHomeProject?.id,
|
||||
);
|
||||
},
|
||||
homeProject(): ProjectSharingData | undefined {
|
||||
return (
|
||||
this.credential?.homeProject ?? (this.credentialData?.homeProject as ProjectSharingData)
|
||||
);
|
||||
return this.credential?.homeProject ?? this.credentialDataHomeProject;
|
||||
},
|
||||
isHomeTeamProject(): boolean {
|
||||
return this.homeProject?.type === ProjectTypes.Team;
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<div
|
||||
:class="$style.wrapper"
|
||||
:style="iconStyleData"
|
||||
@click="(e) => $emit('click')"
|
||||
@click="() => $emit('click')"
|
||||
@mouseover="showTooltip = true"
|
||||
@mouseleave="showTooltip = false"
|
||||
>
|
||||
@@ -126,7 +126,7 @@ export default defineComponent({
|
||||
|
||||
const restUrl = this.rootStore.getRestUrl;
|
||||
|
||||
if (nodeType.icon) {
|
||||
if (typeof nodeType.icon === 'string') {
|
||||
const [type, path] = nodeType.icon.split(':');
|
||||
const returnData: NodeIconData = {
|
||||
type,
|
||||
|
||||
@@ -207,6 +207,10 @@ const isWorkflowHistoryButtonDisabled = computed(() => {
|
||||
return isNewWorkflow.value;
|
||||
});
|
||||
|
||||
const workflowTagIds = computed(() => {
|
||||
return (props.workflow.tags ?? []).map((tag) => (typeof tag === 'string' ? tag : tag.id));
|
||||
});
|
||||
|
||||
watch(
|
||||
() => props.workflow.id,
|
||||
() => {
|
||||
@@ -601,7 +605,7 @@ function showCreateWorkflowSuccessToast(id?: string) {
|
||||
<TagsContainer
|
||||
v-else
|
||||
:key="workflow.id"
|
||||
:tag-ids="workflow.tags"
|
||||
:tag-ids="workflowTagIds"
|
||||
:clickable="true"
|
||||
:responsive="true"
|
||||
data-test-id="workflow-tags"
|
||||
|
||||
@@ -88,7 +88,9 @@ function onSelected(item: INodeCreateElement) {
|
||||
|
||||
const icon = item.properties.iconUrl
|
||||
? `${baseUrl}${item.properties.iconUrl}`
|
||||
: item.properties.icon?.split(':')[1];
|
||||
: typeof item.properties.icon === 'string'
|
||||
? item.properties.icon?.split(':')[1]
|
||||
: undefined;
|
||||
|
||||
const transformedActions = nodeActions?.map((a) =>
|
||||
transformNodeType(a, item.properties.displayName, 'action'),
|
||||
|
||||
@@ -18,7 +18,7 @@ export const mockSimplifiedNodeType = (
|
||||
): SimplifiedNodeType => ({
|
||||
displayName: 'Sample DisplayName',
|
||||
name: 'sampleName',
|
||||
icon: 'sampleIcon',
|
||||
icon: 'fa:sampleIcon',
|
||||
iconUrl: 'https://example.com/icon.png',
|
||||
group: ['group1', 'group2'],
|
||||
description: 'Sample description',
|
||||
|
||||
@@ -36,7 +36,7 @@ import { useI18n } from '@/composables/useI18n';
|
||||
import { useKeyboardNavigation } from './useKeyboardNavigation';
|
||||
|
||||
import { useNodeTypesStore } from '@/stores/nodeTypes.store';
|
||||
import type { INodeInputFilter, NodeConnectionType } from 'n8n-workflow';
|
||||
import type { INodeInputFilter, NodeConnectionType, Themed } from 'n8n-workflow';
|
||||
import { useCanvasStore } from '@/stores/canvas.store';
|
||||
|
||||
interface ViewStack {
|
||||
@@ -48,7 +48,7 @@ interface ViewStack {
|
||||
info?: string;
|
||||
nodeIcon?: {
|
||||
iconType?: string;
|
||||
icon?: string;
|
||||
icon?: Themed<string>;
|
||||
color?: string;
|
||||
};
|
||||
iconUrl?: string;
|
||||
|
||||
@@ -58,7 +58,7 @@ import {
|
||||
import { useI18n } from '@/composables/useI18n';
|
||||
import { useNodeTypesStore } from '@/stores/nodeTypes.store';
|
||||
import type { SimplifiedNodeType } from '@/Interface';
|
||||
import type { INodeTypeDescription } from 'n8n-workflow';
|
||||
import type { INodeTypeDescription, Themed } from 'n8n-workflow';
|
||||
import { NodeConnectionType } from 'n8n-workflow';
|
||||
import { useTemplatesStore } from '@/stores/templates.store';
|
||||
|
||||
@@ -74,7 +74,7 @@ export interface NodeViewItem {
|
||||
properties: {
|
||||
name?: string;
|
||||
title?: string;
|
||||
icon?: string;
|
||||
icon?: Themed<string>;
|
||||
iconProps?: {
|
||||
color?: string;
|
||||
};
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { IVersionNode } from '@/Interface';
|
||||
import type { IVersionNode, SimplifiedNodeType } from '@/Interface';
|
||||
import { useRootStore } from '@/stores/n8nRoot.store';
|
||||
import { useUIStore } from '@/stores/ui.store';
|
||||
import { getBadgeIconUrl, getNodeIcon, getNodeIconUrl } from '@/utils/nodeTypesUtils';
|
||||
@@ -30,7 +30,7 @@ interface NodeIconSource {
|
||||
}
|
||||
|
||||
type Props = {
|
||||
nodeType?: INodeTypeDescription | IVersionNode | null;
|
||||
nodeType?: INodeTypeDescription | SimplifiedNodeType | IVersionNode | null;
|
||||
size?: number;
|
||||
disabled?: boolean;
|
||||
circle?: boolean;
|
||||
|
||||
@@ -460,7 +460,6 @@ export default defineComponent({
|
||||
parameters: {},
|
||||
} as INodeParameters,
|
||||
nodeValuesInitialized: false, // Used to prevent nodeValues from being overwritten by defaults on reopening ndv
|
||||
|
||||
nodeSettings: [] as INodeProperties[],
|
||||
COMMUNITY_NODES_INSTALLATION_DOCS_URL,
|
||||
CUSTOM_NODES_DOCS_URL,
|
||||
@@ -469,7 +468,7 @@ export default defineComponent({
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
node(newNode, oldNode) {
|
||||
node() {
|
||||
this.setNodeValues();
|
||||
},
|
||||
},
|
||||
|
||||
@@ -28,7 +28,7 @@ import { isCommunityPackageName } from '@/utils/nodeTypesUtils';
|
||||
type Tab = 'settings' | 'params';
|
||||
type Props = {
|
||||
modelValue?: Tab;
|
||||
nodeType?: INodeTypeDescription;
|
||||
nodeType?: INodeTypeDescription | null;
|
||||
pushRef?: string;
|
||||
};
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { createComponentRenderer } from '@/__tests__/render';
|
||||
import ProjectTabs from '@/components/Projects/ProjectTabs.vue';
|
||||
import { useRoute, useRouter } from 'vue-router';
|
||||
import { createTestProject } from '@/__tests__/data/projects';
|
||||
import { useProjectsStore } from '@/stores/projects.store';
|
||||
|
||||
vi.mock('vue-router', () => {
|
||||
@@ -54,15 +55,14 @@ describe('ProjectTabs', () => {
|
||||
|
||||
it('should render project tabs if use has permissions', () => {
|
||||
route.params.projectId = '123';
|
||||
projectsStore.currentProject = {
|
||||
id: '123',
|
||||
type: 'team',
|
||||
name: 'Project',
|
||||
relations: [],
|
||||
scopes: ['project:update'],
|
||||
createdAt: '',
|
||||
updatedAt: '',
|
||||
};
|
||||
vi.mocked(useProjectsStore).mockImplementationOnce(
|
||||
() =>
|
||||
({
|
||||
currentProject: createTestProject({
|
||||
scopes: ['project:update'],
|
||||
}),
|
||||
}) as ReturnType<typeof useProjectsStore>,
|
||||
);
|
||||
const { getByText } = renderComponent();
|
||||
|
||||
expect(getByText('Workflows')).toBeInTheDocument();
|
||||
@@ -72,15 +72,14 @@ describe('ProjectTabs', () => {
|
||||
|
||||
it('should render project tabs', () => {
|
||||
route.params.projectId = '123';
|
||||
projectsStore.currentProject = {
|
||||
id: '123',
|
||||
type: 'team',
|
||||
name: 'Project',
|
||||
relations: [],
|
||||
scopes: ['project:read'],
|
||||
createdAt: '',
|
||||
updatedAt: '',
|
||||
};
|
||||
vi.mocked(useProjectsStore).mockImplementationOnce(
|
||||
() =>
|
||||
({
|
||||
currentProject: createTestProject({
|
||||
scopes: ['project:read'],
|
||||
}),
|
||||
}) as ReturnType<typeof useProjectsStore>,
|
||||
);
|
||||
const { queryByText, getByText } = renderComponent();
|
||||
|
||||
expect(getByText('Workflows')).toBeInTheDocument();
|
||||
|
||||
@@ -486,7 +486,7 @@ export default defineComponent({
|
||||
this.eventBus.on('refreshList', this.refreshList);
|
||||
window.addEventListener('resize', this.setWidth);
|
||||
|
||||
useNDVStore().$subscribe((mutation, state) => {
|
||||
useNDVStore().$subscribe((_mutation, _state) => {
|
||||
// Update the width when main panel dimension change
|
||||
this.setWidth();
|
||||
});
|
||||
|
||||
@@ -16,7 +16,7 @@ import MappingModeSelect from './MappingModeSelect.vue';
|
||||
import MatchingColumnsSelect from './MatchingColumnsSelect.vue';
|
||||
import MappingFields from './MappingFields.vue';
|
||||
import { fieldCannotBeDeleted, parseResourceMapperFieldName } from '@/utils/nodeTypesUtils';
|
||||
import { isResourceMapperValue } from '@/utils/typeGuards';
|
||||
import { isFullExecutionResponse, isResourceMapperValue } from '@/utils/typeGuards';
|
||||
import { i18n as locale } from '@/plugins/i18n';
|
||||
import { useNDVStore } from '@/stores/ndv.store';
|
||||
import { useWorkflowsStore } from '@/stores/workflows.store';
|
||||
@@ -78,7 +78,12 @@ watch(
|
||||
watch(
|
||||
() => workflowsStore.getWorkflowExecution,
|
||||
async (data) => {
|
||||
if (data?.status === 'success' && state.paramValue.mappingMode === 'autoMapInputData') {
|
||||
if (
|
||||
data &&
|
||||
isFullExecutionResponse(data) &&
|
||||
data.status === 'success' &&
|
||||
state.paramValue.mappingMode === 'autoMapInputData'
|
||||
) {
|
||||
await initFetching(true);
|
||||
}
|
||||
},
|
||||
|
||||
@@ -176,12 +176,14 @@ import ParameterInputList from '@/components/ParameterInputList.vue';
|
||||
import type { IMenuItem, INodeUi, IUpdateInformation } from '@/Interface';
|
||||
import type {
|
||||
IDataObject,
|
||||
INodeCredentials,
|
||||
NodeParameterValue,
|
||||
MessageEventBusDestinationOptions,
|
||||
INodeParameters,
|
||||
NodeParameterValueType,
|
||||
} from 'n8n-workflow';
|
||||
import {
|
||||
deepCopy,
|
||||
messageEventBusDestinationTypeNames,
|
||||
defaultMessageEventBusDestinationOptions,
|
||||
defaultMessageEventBusDestinationWebhookOptions,
|
||||
MessageEventBusDestinationTypeNames,
|
||||
@@ -246,7 +248,7 @@ export default defineComponent({
|
||||
showRemoveConfirm: false,
|
||||
typeSelectValue: '',
|
||||
typeSelectPlaceholder: 'Destination Type',
|
||||
nodeParameters: deepCopy(defaultMessageEventBusDestinationOptions),
|
||||
nodeParameters: deepCopy(defaultMessageEventBusDestinationOptions) as INodeParameters,
|
||||
webhookDescription: webhookModalDescription,
|
||||
sentryDescription: sentryModalDescription,
|
||||
syslogDescription: syslogModalDescription,
|
||||
@@ -261,7 +263,7 @@ export default defineComponent({
|
||||
...mapStores(useUIStore, useLogStreamingStore, useNDVStore, useWorkflowsStore),
|
||||
typeSelectOptions(): Array<{ value: string; label: BaseTextKey }> {
|
||||
const options: Array<{ value: string; label: BaseTextKey }> = [];
|
||||
for (const t of Object.values(MessageEventBusDestinationTypeNames)) {
|
||||
for (const t of messageEventBusDestinationTypeNames) {
|
||||
if (t === MessageEventBusDestinationTypeNames.abstract) {
|
||||
continue;
|
||||
}
|
||||
@@ -325,7 +327,8 @@ export default defineComponent({
|
||||
if (arg.name === this.destination.id) {
|
||||
if ('credentials' in arg.properties) {
|
||||
this.unchanged = false;
|
||||
this.nodeParameters.credentials = arg.properties.credentials as INodeCredentials;
|
||||
this.nodeParameters.credentials = arg.properties
|
||||
.credentials as NodeParameterValueType;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -350,7 +353,7 @@ export default defineComponent({
|
||||
this.workflowsStore.removeNode(this.node);
|
||||
this.ndvStore.activeNodeName = options.id ?? 'thisshouldnothappen';
|
||||
this.workflowsStore.addNode(destinationToFakeINodeUi(options));
|
||||
this.nodeParameters = options;
|
||||
this.nodeParameters = options as INodeParameters;
|
||||
this.logStreamingStore.items[this.destination.id].destination = options;
|
||||
},
|
||||
onTypeSelectInput(destinationType: MessageEventBusDestinationTypeNames) {
|
||||
@@ -448,7 +451,7 @@ export default defineComponent({
|
||||
if (deleteConfirmed !== MODAL_CONFIRM) {
|
||||
return;
|
||||
} else {
|
||||
this.eventBus.emit('remove', this.destination.id);
|
||||
this.callEventBus('remove', this.destination.id);
|
||||
this.uiStore.closeModal(LOG_STREAM_MODAL_KEY);
|
||||
this.uiStore.stateIsDirty = false;
|
||||
}
|
||||
@@ -456,10 +459,12 @@ export default defineComponent({
|
||||
onModalClose() {
|
||||
if (!this.hasOnceBeenSaved) {
|
||||
this.workflowsStore.removeNode(this.node);
|
||||
this.logStreamingStore.removeDestination(this.nodeParameters.id!);
|
||||
if (this.nodeParameters.id) {
|
||||
this.logStreamingStore.removeDestination(this.nodeParameters.id.toString());
|
||||
}
|
||||
}
|
||||
this.ndvStore.activeNodeName = null;
|
||||
this.eventBus.emit('closing', this.destination.id);
|
||||
this.callEventBus('closing', this.destination.id);
|
||||
this.uiStore.stateIsDirty = false;
|
||||
},
|
||||
async saveDestination() {
|
||||
@@ -471,10 +476,12 @@ export default defineComponent({
|
||||
this.hasOnceBeenSaved = true;
|
||||
this.testMessageSent = false;
|
||||
this.unchanged = true;
|
||||
this.eventBus.emit('destinationWasSaved', this.destination.id);
|
||||
this.callEventBus('destinationWasSaved', this.destination.id);
|
||||
this.uiStore.stateIsDirty = false;
|
||||
|
||||
const destinationType = (this.nodeParameters.__type ?? 'unknown')
|
||||
const destinationType = (
|
||||
this.nodeParameters.__type ? `${this.nodeParameters.__type}` : 'unknown'
|
||||
)
|
||||
.replace('$$MessageEventBusDestination', '')
|
||||
.toLowerCase();
|
||||
|
||||
@@ -503,6 +510,11 @@ export default defineComponent({
|
||||
});
|
||||
}
|
||||
},
|
||||
callEventBus(event: string, data: unknown) {
|
||||
if (this.eventBus) {
|
||||
this.eventBus.emit(event, data);
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -184,7 +184,7 @@ export default defineComponent({
|
||||
},
|
||||
isSelected(): boolean {
|
||||
return (
|
||||
this.uiStore.getSelectedNodes.find((node: INodeUi) => node.name === this.data.name) !==
|
||||
this.uiStore.getSelectedNodes.find((node: INodeUi) => node.name === this.data?.name) !==
|
||||
undefined
|
||||
);
|
||||
},
|
||||
|
||||
@@ -12,6 +12,8 @@ import { useUsersStore } from '@/stores/users.store';
|
||||
import { useWorkflowsStore } from '@/stores/workflows.store';
|
||||
import { testingNodeTypes, mockNodeTypesToArray } from '@/__tests__/defaults';
|
||||
import { setupServer } from '@/__tests__/server';
|
||||
import { NodeConnectionType } from 'n8n-workflow';
|
||||
import type { IConnections } from 'n8n-workflow';
|
||||
|
||||
const renderComponent = createComponentRenderer(WorkflowLMChatModal, {
|
||||
props: {
|
||||
@@ -23,25 +25,25 @@ const renderComponent = createComponentRenderer(WorkflowLMChatModal, {
|
||||
async function createPiniaWithAINodes(options = { withConnections: true, withAgentNode: true }) {
|
||||
const { withConnections, withAgentNode } = options;
|
||||
const workflowId = uuid();
|
||||
const connections: IConnections = {
|
||||
'Chat Trigger': {
|
||||
main: [
|
||||
[
|
||||
{
|
||||
node: 'Agent',
|
||||
type: NodeConnectionType.Main,
|
||||
index: 0,
|
||||
},
|
||||
],
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
const workflow = createTestWorkflow({
|
||||
id: workflowId,
|
||||
name: 'Test Workflow',
|
||||
connections: withConnections
|
||||
? {
|
||||
'Chat Trigger': {
|
||||
main: [
|
||||
[
|
||||
{
|
||||
node: 'Agent',
|
||||
type: 'main',
|
||||
index: 0,
|
||||
},
|
||||
],
|
||||
],
|
||||
},
|
||||
}
|
||||
: {},
|
||||
active: true,
|
||||
...(withConnections ? { connections } : {}),
|
||||
nodes: [
|
||||
createTestNode({
|
||||
name: 'Chat Trigger',
|
||||
|
||||
@@ -160,14 +160,14 @@ import { useRoute } from 'vue-router';
|
||||
// eslint-disable-next-line unused-imports/no-unused-imports, @typescript-eslint/no-unused-vars
|
||||
import type { BaseTextKey } from '@/plugins/i18n';
|
||||
|
||||
export interface IResource {
|
||||
export type IResource = {
|
||||
id: string;
|
||||
name: string;
|
||||
value: string;
|
||||
updatedAt?: string;
|
||||
createdAt?: string;
|
||||
homeProject?: ProjectSharingData;
|
||||
}
|
||||
};
|
||||
|
||||
interface IFilters {
|
||||
search: string;
|
||||
@@ -291,11 +291,11 @@ export default defineComponent({
|
||||
case 'lastUpdated':
|
||||
return props.sortFns.lastUpdated
|
||||
? props.sortFns.lastUpdated(a, b)
|
||||
: new Date(b.updatedAt).valueOf() - new Date(a.updatedAt).valueOf();
|
||||
: new Date(b.updatedAt ?? '').valueOf() - new Date(a.updatedAt ?? '').valueOf();
|
||||
case 'lastCreated':
|
||||
return props.sortFns.lastCreated
|
||||
? props.sortFns.lastCreated(a, b)
|
||||
: new Date(b.createdAt).valueOf() - new Date(a.createdAt).valueOf();
|
||||
: new Date(b.createdAt ?? '').valueOf() - new Date(a.createdAt ?? '').valueOf();
|
||||
case 'nameAsc':
|
||||
return props.sortFns.nameAsc
|
||||
? props.sortFns.nameAsc(a, b)
|
||||
|
||||
Reference in New Issue
Block a user