mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-17 18:12:04 +00:00
feat: Refresh workflow name in workflows selector when updated (#14705)
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
import { createTestingPinia } from '@pinia/testing';
|
||||
import WorkflowSelectorParameterInput, {
|
||||
type Props,
|
||||
} from '@/components/WorkflowSelectorParameterInput/WorkflowSelectorParameterInput.vue';
|
||||
import { createComponentRenderer } from '@/__tests__/render';
|
||||
import { cleanupAppModals, createAppModals, mockedStore } from '@/__tests__/utils';
|
||||
import { useProjectsStore } from '@/stores/projects.store';
|
||||
import { useWorkflowsStore } from '@/stores/workflows.store';
|
||||
|
||||
const { onDocumentVisible } = vi.hoisted(() => ({
|
||||
onDocumentVisible: vi.fn(),
|
||||
}));
|
||||
|
||||
const flushPromises = async () => await new Promise(setImmediate);
|
||||
|
||||
vi.mock('@/composables/useDocumentVisibility', () => ({
|
||||
useDocumentVisibility: () => ({ onDocumentVisible }),
|
||||
}));
|
||||
|
||||
const renderComponent = createComponentRenderer(WorkflowSelectorParameterInput, {
|
||||
global: {
|
||||
stubs: {
|
||||
ResourceLocatorDropdown: true,
|
||||
},
|
||||
},
|
||||
pinia: createTestingPinia({}),
|
||||
});
|
||||
|
||||
const projectsStore = mockedStore(useProjectsStore);
|
||||
projectsStore.isTeamProjectFeatureEnabled = false;
|
||||
|
||||
const workflowsStore = mockedStore(useWorkflowsStore);
|
||||
|
||||
describe('WorkflowSelectorParameterInput', () => {
|
||||
beforeEach(() => {
|
||||
createAppModals();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
cleanupAppModals();
|
||||
});
|
||||
|
||||
it('should update cached workflow when page is visible', async () => {
|
||||
const props: Props = {
|
||||
modelValue: {
|
||||
__rl: true,
|
||||
value: 'workflow-id',
|
||||
mode: 'list',
|
||||
},
|
||||
path: '',
|
||||
parameter: {
|
||||
displayName: 'display-name',
|
||||
type: 'workflowSelector',
|
||||
name: 'name',
|
||||
default: '',
|
||||
},
|
||||
};
|
||||
const { emitted } = renderComponent({ props });
|
||||
await flushPromises();
|
||||
expect(emitted()['update:modelValue']?.[0]).toEqual([props.modelValue]);
|
||||
expect(workflowsStore.fetchWorkflow).toHaveBeenCalledWith(props.modelValue.value);
|
||||
});
|
||||
|
||||
it('should update cached workflow when page is visible', async () => {
|
||||
const props: Props = {
|
||||
modelValue: {
|
||||
__rl: true,
|
||||
value: 'workflow-id',
|
||||
mode: 'list',
|
||||
},
|
||||
path: '',
|
||||
parameter: {
|
||||
displayName: 'display-name',
|
||||
type: 'workflowSelector',
|
||||
name: 'name',
|
||||
default: '',
|
||||
},
|
||||
};
|
||||
const { emitted } = renderComponent({ props });
|
||||
await flushPromises();
|
||||
|
||||
// on mount
|
||||
expect(emitted()['update:modelValue']?.[0]).toEqual([props.modelValue]);
|
||||
expect(workflowsStore.fetchWorkflow).toHaveBeenCalledWith(props.modelValue.value);
|
||||
workflowsStore.fetchWorkflow.mockReset();
|
||||
|
||||
expect(onDocumentVisible).toHaveBeenCalled();
|
||||
const onDocumentVisibleCallback = onDocumentVisible.mock.lastCall?.[0];
|
||||
await onDocumentVisibleCallback();
|
||||
|
||||
expect(emitted()['update:modelValue']?.[1]).toEqual([props.modelValue]);
|
||||
expect(workflowsStore.fetchWorkflow).toHaveBeenCalledWith(props.modelValue.value);
|
||||
});
|
||||
});
|
||||
@@ -23,8 +23,9 @@ import { useTelemetry } from '@/composables/useTelemetry';
|
||||
import { VIEWS } from '@/constants';
|
||||
import { SAMPLE_SUBWORKFLOW_WORKFLOW } from '@/constants.workflows';
|
||||
import type { IWorkflowDataCreate } from '@/Interface';
|
||||
import { useDocumentVisibility } from '@/composables/useDocumentVisibility';
|
||||
|
||||
interface Props {
|
||||
export interface Props {
|
||||
modelValue: INodeParameterResourceLocator;
|
||||
eventBus?: EventBus;
|
||||
inputSize?: 'small' | 'mini' | 'medium' | 'large' | 'xlarge';
|
||||
@@ -82,6 +83,8 @@ const { hideDropdown, isDropdownVisible, showDropdown } = useWorkflowResourceLoc
|
||||
inputRef,
|
||||
);
|
||||
|
||||
const { onDocumentVisible } = useDocumentVisibility();
|
||||
|
||||
const {
|
||||
hasMoreWorkflowsToLoad,
|
||||
isLoadingResources,
|
||||
@@ -146,14 +149,18 @@ function setWidth() {
|
||||
}
|
||||
}
|
||||
|
||||
function onInputChange(value: NodeParameterValue): void {
|
||||
if (typeof value !== 'string') return;
|
||||
function onInputChange(workflowId: NodeParameterValue): void {
|
||||
if (typeof workflowId !== 'string') return;
|
||||
|
||||
const params: INodeParameterResourceLocator = { __rl: true, value, mode: selectedMode.value };
|
||||
const params: INodeParameterResourceLocator = {
|
||||
__rl: true,
|
||||
value: workflowId,
|
||||
mode: selectedMode.value,
|
||||
};
|
||||
if (isListMode.value) {
|
||||
const resource = workflowsStore.getWorkflowById(value);
|
||||
const resource = workflowsStore.getWorkflowById(workflowId);
|
||||
if (resource?.name) {
|
||||
params.cachedResultName = getWorkflowName(value);
|
||||
params.cachedResultName = getWorkflowName(workflowId);
|
||||
}
|
||||
}
|
||||
emit('update:modelValue', params);
|
||||
@@ -191,7 +198,27 @@ function openWorkflow() {
|
||||
window.open(getWorkflowUrl(props.modelValue.value?.toString() ?? ''), '_blank');
|
||||
}
|
||||
|
||||
async function refreshCachedWorkflow() {
|
||||
if (!props.modelValue || props.modelValue.mode !== 'list' || !props.modelValue.value) {
|
||||
return;
|
||||
}
|
||||
|
||||
const workflowId = props.modelValue.value;
|
||||
if (workflowId === true) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
await workflowsStore.fetchWorkflow(`${workflowId}`);
|
||||
onInputChange(workflowId);
|
||||
} catch (e) {
|
||||
// keep old cached value
|
||||
}
|
||||
}
|
||||
|
||||
onDocumentVisible(refreshCachedWorkflow);
|
||||
|
||||
onMounted(() => {
|
||||
void refreshCachedWorkflow();
|
||||
window.addEventListener('resize', setWidth);
|
||||
setWidth();
|
||||
void setWorkflowsResources();
|
||||
|
||||
Reference in New Issue
Block a user