[NIFI-13029] - Download Flow (#8634)

This closes #8634
This commit is contained in:
Rob Fellows 2024-04-12 14:25:57 -04:00 committed by GitHub
parent 62a4ece55d
commit 4e4c1ed803
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 84 additions and 11 deletions

View File

@ -51,7 +51,8 @@ import {
startCurrentProcessGroup,
stopComponents,
stopCurrentProcessGroup,
stopVersionControlRequest
stopVersionControlRequest,
downloadFlow
} from '../state/flow/flow.actions';
import { ComponentType } from '../../../state/shared';
import {
@ -71,6 +72,7 @@ import {
import { promptEmptyQueueRequest, promptEmptyQueuesRequest } from '../state/queue/queue.actions';
import { getComponentStateAndOpenDialog } from '../../../state/component-state/component-state.actions';
import { navigateToComponentDocumentation } from '../../../state/documentation/documentation.actions';
import * as d3 from 'd3';
@Injectable({ providedIn: 'root' })
export class CanvasContextMenu implements ContextMenuDefinitionProvider {
@ -329,25 +331,49 @@ export class CanvasContextMenu implements ContextMenuDefinitionProvider {
id: 'download',
menuItems: [
{
condition: (selection: any) => {
// TODO - supportsDownloadFlow
return false;
condition: (selection: d3.Selection<any, any, any, any>) => {
return this.canvasUtils.supportsDownloadFlow(selection);
},
clazz: 'fa',
text: 'Without external services',
action: () => {
// TODO - downloadFlowWithoutExternalServices
action: (selection: d3.Selection<any, any, any, any>) => {
let pgId;
if (selection.empty()) {
pgId = this.canvasUtils.getProcessGroupId();
} else {
pgId = selection.datum().id;
}
this.store.dispatch(
downloadFlow({
request: {
processGroupId: pgId,
includeReferencedServices: false
}
})
);
}
},
{
condition: (selection: any) => {
// TODO - supportsDownloadFlow
return false;
condition: (selection: d3.Selection<any, any, any, any>) => {
return this.canvasUtils.supportsDownloadFlow(selection);
},
clazz: 'fa',
text: 'With external services',
action: () => {
// TODO - downloadFlowWithExternalServices
action: (selection: d3.Selection<any, any, any, any>) => {
let pgId;
if (selection.empty()) {
pgId = this.canvasUtils.getProcessGroupId();
} else {
pgId = selection.datum().id;
}
this.store.dispatch(
downloadFlow({
request: {
processGroupId: pgId,
includeReferencedServices: true
}
})
);
}
}
]

View File

@ -1694,4 +1694,21 @@ export class CanvasUtils {
return pgData.component.versionControlInformation || null;
}
}
/**
* Returns whether the process group supports downloading the current flow.
*
* @argument {d3.Selection} selection The selection
* @returns {boolean}
*/
public supportsDownloadFlow(selection: d3.Selection<any, any, any, any>): boolean {
// download is allowed when either nothing is selected or a single readable process group is selected
if (selection.empty()) {
return this.canvasPermissions.canRead;
} else if (selection.size() === 1) {
return this.isProcessGroup(selection) && this.canRead(selection);
}
return false;
}
}

View File

@ -27,6 +27,7 @@ import {
CreateProcessorRequest,
CreateRemoteProcessGroupRequest,
DeleteComponentRequest,
DownloadFlowRequest,
FlowComparisonEntity,
FlowUpdateRequestEntity,
GoToRemoteProcessGroupRequest,
@ -436,4 +437,10 @@ export class FlowService implements PropertyDescriptorRetriever {
`${FlowService.API}/process-groups/${processGroupId}/local-modifications`
) as Observable<FlowComparisonEntity>;
}
downloadFlow(downloadFlowRequest: DownloadFlowRequest): void {
window.open(
`${FlowService.API}/process-groups/${downloadFlowRequest.processGroupId}/download?includeReferencedServices=${downloadFlowRequest.includeReferencedServices}`
);
}
}

View File

@ -33,6 +33,7 @@ import {
CreateRemoteProcessGroupRequest,
DeleteComponentRequest,
DeleteComponentResponse,
DownloadFlowRequest,
EditComponentDialogRequest,
EditConnectionDialogRequest,
EditCurrentProcessGroupRequest,
@ -760,3 +761,8 @@ export const pollRevertChangesSuccess = createAction(
);
export const stopPollingRevertChanges = createAction(`${CANVAS_PREFIX} Stop Polling Revert Changes`);
export const downloadFlow = createAction(
`${CANVAS_PREFIX} Download Flow Request`,
props<{ request: DownloadFlowRequest }>()
);

View File

@ -3141,4 +3141,16 @@ export class FlowEffects {
)
)
);
downloadFlow$ = createEffect(
() =>
this.actions$.pipe(
ofType(FlowActions.downloadFlow),
map((action) => action.request),
tap((request) => {
this.flowService.downloadFlow(request);
})
),
{ dispatch: false }
);
}

View File

@ -734,3 +734,8 @@ export interface LocalChangesDialogRequest {
localModifications: FlowComparisonEntity;
mode: 'SHOW' | 'REVERT';
}
export interface DownloadFlowRequest {
processGroupId: string;
includeReferencedServices: boolean;
}