mirror of https://github.com/apache/nifi.git
NIFI-13078: Adding support to Enable and Disable through the context menu and operation control (#8680)
* NIFI-13078: - Adding support to Enable and Disable through the context menu and operation control. * NIFI-13078: - Addressing review feedback. This closes #8680
This commit is contained in:
parent
cde820673c
commit
562eece6e3
|
@ -58,13 +58,19 @@ import {
|
||||||
copy,
|
copy,
|
||||||
paste,
|
paste,
|
||||||
terminateThreads,
|
terminateThreads,
|
||||||
navigateToParameterContext
|
navigateToParameterContext,
|
||||||
|
enableCurrentProcessGroup,
|
||||||
|
enableComponents,
|
||||||
|
disableCurrentProcessGroup,
|
||||||
|
disableComponents
|
||||||
} from '../state/flow/flow.actions';
|
} from '../state/flow/flow.actions';
|
||||||
import { ComponentType } from '../../../state/shared';
|
import { ComponentType } from '../../../state/shared';
|
||||||
import {
|
import {
|
||||||
ConfirmStopVersionControlRequest,
|
ConfirmStopVersionControlRequest,
|
||||||
CopyComponentRequest,
|
CopyComponentRequest,
|
||||||
DeleteComponentRequest,
|
DeleteComponentRequest,
|
||||||
|
DisableComponentRequest,
|
||||||
|
EnableComponentRequest,
|
||||||
MoveComponentRequest,
|
MoveComponentRequest,
|
||||||
OpenChangeVersionDialogRequest,
|
OpenChangeVersionDialogRequest,
|
||||||
OpenLocalChangesDialogRequest,
|
OpenLocalChangesDialogRequest,
|
||||||
|
@ -573,8 +579,9 @@ export class CanvasContextMenu implements ContextMenuDefinitionProvider {
|
||||||
// are runnable or can start transmitting. However, if all the startable components are RGPs, we will defer
|
// are runnable or can start transmitting. However, if all the startable components are RGPs, we will defer
|
||||||
// to the Enable Transmission menu option and not show the start option.
|
// to the Enable Transmission menu option and not show the start option.
|
||||||
const allRpgs =
|
const allRpgs =
|
||||||
|
!startable.empty() &&
|
||||||
startable.filter((d: any) => d.type === ComponentType.RemoteProcessGroup).size() ===
|
startable.filter((d: any) => d.type === ComponentType.RemoteProcessGroup).size() ===
|
||||||
startable.size();
|
startable.size();
|
||||||
|
|
||||||
return this.canvasUtils.areAnyRunnable(selection) && !allRpgs;
|
return this.canvasUtils.areAnyRunnable(selection) && !allRpgs;
|
||||||
},
|
},
|
||||||
|
@ -613,8 +620,9 @@ export class CanvasContextMenu implements ContextMenuDefinitionProvider {
|
||||||
// are runnable or can stop transmitting. However, if all the stoppable components are RGPs, we will defer
|
// are runnable or can stop transmitting. However, if all the stoppable components are RGPs, we will defer
|
||||||
// to the Disable Transmission menu option and not show the start option.
|
// to the Disable Transmission menu option and not show the start option.
|
||||||
const allRpgs =
|
const allRpgs =
|
||||||
|
!stoppable.empty() &&
|
||||||
stoppable.filter((d: any) => d.type === ComponentType.RemoteProcessGroup).size() ===
|
stoppable.filter((d: any) => d.type === ComponentType.RemoteProcessGroup).size() ===
|
||||||
stoppable.size();
|
stoppable.size();
|
||||||
|
|
||||||
return this.canvasUtils.areAnyStoppable(selection) && !allRpgs;
|
return this.canvasUtils.areAnyStoppable(selection) && !allRpgs;
|
||||||
},
|
},
|
||||||
|
@ -685,25 +693,65 @@ export class CanvasContextMenu implements ContextMenuDefinitionProvider {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
condition: (selection: any) => {
|
condition: (selection: d3.Selection<any, any, any, any>) => {
|
||||||
// TODO - canEnable
|
return this.canvasUtils.canEnable(selection);
|
||||||
return false;
|
|
||||||
},
|
},
|
||||||
clazz: 'fa fa-flash',
|
clazz: 'fa fa-flash',
|
||||||
text: 'Enable',
|
text: 'Enable',
|
||||||
action: () => {
|
action: (selection: d3.Selection<any, any, any, any>) => {
|
||||||
// TODO - enable
|
if (selection.empty()) {
|
||||||
|
// attempting to enable the current process group
|
||||||
|
this.store.dispatch(enableCurrentProcessGroup());
|
||||||
|
} else {
|
||||||
|
const components: EnableComponentRequest[] = [];
|
||||||
|
const enableable = this.canvasUtils.filterEnable(selection);
|
||||||
|
enableable.each((d: any) => {
|
||||||
|
components.push({
|
||||||
|
id: d.id,
|
||||||
|
uri: d.uri,
|
||||||
|
type: d.type,
|
||||||
|
revision: this.client.getRevision(d)
|
||||||
|
});
|
||||||
|
});
|
||||||
|
this.store.dispatch(
|
||||||
|
enableComponents({
|
||||||
|
request: {
|
||||||
|
components
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
condition: (selection: any) => {
|
condition: (selection: d3.Selection<any, any, any, any>) => {
|
||||||
// TODO - canDisable
|
return this.canvasUtils.canDisable(selection);
|
||||||
return false;
|
|
||||||
},
|
},
|
||||||
clazz: 'icon icon-enable-false',
|
clazz: 'icon icon-enable-false',
|
||||||
text: 'Disable',
|
text: 'Disable',
|
||||||
action: () => {
|
action: (selection: d3.Selection<any, any, any, any>) => {
|
||||||
// TODO - disable
|
if (selection.empty()) {
|
||||||
|
// attempting to disable the current process group
|
||||||
|
this.store.dispatch(disableCurrentProcessGroup());
|
||||||
|
} else {
|
||||||
|
const components: DisableComponentRequest[] = [];
|
||||||
|
const disableable = this.canvasUtils.filterDisable(selection);
|
||||||
|
disableable.each((d: any) => {
|
||||||
|
components.push({
|
||||||
|
id: d.id,
|
||||||
|
uri: d.uri,
|
||||||
|
type: d.type,
|
||||||
|
revision: this.client.getRevision(d)
|
||||||
|
});
|
||||||
|
});
|
||||||
|
this.store.dispatch(
|
||||||
|
disableComponents({
|
||||||
|
request: {
|
||||||
|
components
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -1440,6 +1440,89 @@ export class CanvasUtils {
|
||||||
return '#ffffff';
|
return '#ffffff';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filters the specified selection for any components that supports enable.
|
||||||
|
*
|
||||||
|
* @argument {selection} selection The selection
|
||||||
|
*/
|
||||||
|
public filterEnable(selection: d3.Selection<any, any, any, any>): d3.Selection<any, any, any, any> {
|
||||||
|
return selection.filter((d, i, nodes) => {
|
||||||
|
const selected = d3.select(nodes[i]);
|
||||||
|
|
||||||
|
// enable always allowed for PGs since they will invoke the /flow endpoint for enabling all applicable components (based on permissions)
|
||||||
|
if (this.isProcessGroup(selected)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// not a PG, verify permissions to modify
|
||||||
|
if (!this.canOperate(selected)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ensure it's a processor, input port, or output port and supports modification and is disabled (can enable)
|
||||||
|
return (
|
||||||
|
(this.isProcessor(selected) || this.isInputPort(selected) || this.isOutputPort(selected)) &&
|
||||||
|
this.supportsModification(selected) &&
|
||||||
|
d.status.aggregateSnapshot.runStatus === 'Disabled'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines if the specified selection contains any components that supports enable.
|
||||||
|
*
|
||||||
|
* @argument {selection} selection The selection
|
||||||
|
*/
|
||||||
|
public canEnable(selection: d3.Selection<any, any, any, any>): boolean {
|
||||||
|
if (selection.empty()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.filterEnable(selection).size() === selection.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filters the specified selection for any components that supports disable.
|
||||||
|
*
|
||||||
|
* @argument {selection} selection The selection
|
||||||
|
*/
|
||||||
|
public filterDisable(selection: d3.Selection<any, any, any, any>): d3.Selection<any, any, any, any> {
|
||||||
|
return selection.filter((d, i, nodes) => {
|
||||||
|
const selected = d3.select(nodes[i]);
|
||||||
|
|
||||||
|
// disable always allowed for PGs since they will invoke the /flow endpoint for disabling all applicable components (based on permissions)
|
||||||
|
if (this.isProcessGroup(selected)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// not a PG, verify permissions to modify
|
||||||
|
if (!this.canOperate(selected)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ensure it's a processor, input port, or output port and supports modification and is stopped (can disable)
|
||||||
|
return (
|
||||||
|
(this.isProcessor(selected) || this.isInputPort(selected) || this.isOutputPort(selected)) &&
|
||||||
|
this.supportsModification(selected) &&
|
||||||
|
(d.status.aggregateSnapshot.runStatus === 'Stopped' ||
|
||||||
|
d.status.aggregateSnapshot.runStatus === 'Invalid')
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines if the specified selection contains any components that supports disable.
|
||||||
|
*
|
||||||
|
* @argument {selection} selection The selection
|
||||||
|
*/
|
||||||
|
public canDisable(selection: d3.Selection<any, any, any, any>): boolean {
|
||||||
|
if (selection.empty()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.filterDisable(selection).size() === selection.size();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines if the components in the specified selection are runnable.
|
* Determines if the components in the specified selection are runnable.
|
||||||
*
|
*
|
||||||
|
|
|
@ -27,7 +27,11 @@ import {
|
||||||
CreateProcessorRequest,
|
CreateProcessorRequest,
|
||||||
CreateRemoteProcessGroupRequest,
|
CreateRemoteProcessGroupRequest,
|
||||||
DeleteComponentRequest,
|
DeleteComponentRequest,
|
||||||
|
DisableComponentRequest,
|
||||||
|
DisableProcessGroupRequest,
|
||||||
DownloadFlowRequest,
|
DownloadFlowRequest,
|
||||||
|
EnableComponentRequest,
|
||||||
|
EnableProcessGroupRequest,
|
||||||
FlowComparisonEntity,
|
FlowComparisonEntity,
|
||||||
FlowUpdateRequestEntity,
|
FlowUpdateRequestEntity,
|
||||||
GoToRemoteProcessGroupRequest,
|
GoToRemoteProcessGroupRequest,
|
||||||
|
@ -270,6 +274,24 @@ export class FlowService implements PropertyDescriptorRetriever {
|
||||||
return this.httpClient.put(`${this.nifiCommon.stripProtocol(request.uri)}/run-status`, startRequest);
|
return this.httpClient.put(`${this.nifiCommon.stripProtocol(request.uri)}/run-status`, startRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enableComponent(request: EnableComponentRequest): Observable<any> {
|
||||||
|
const enableRequest: ComponentRunStatusRequest = {
|
||||||
|
revision: request.revision,
|
||||||
|
disconnectedNodeAcknowledged: this.clusterConnectionService.isDisconnectionAcknowledged(),
|
||||||
|
state: 'STOPPED'
|
||||||
|
};
|
||||||
|
return this.httpClient.put(`${this.nifiCommon.stripProtocol(request.uri)}/run-status`, enableRequest);
|
||||||
|
}
|
||||||
|
|
||||||
|
disableComponent(request: DisableComponentRequest): Observable<any> {
|
||||||
|
const disableRequest: ComponentRunStatusRequest = {
|
||||||
|
revision: request.revision,
|
||||||
|
disconnectedNodeAcknowledged: this.clusterConnectionService.isDisconnectionAcknowledged(),
|
||||||
|
state: 'DISABLED'
|
||||||
|
};
|
||||||
|
return this.httpClient.put(`${this.nifiCommon.stripProtocol(request.uri)}/run-status`, disableRequest);
|
||||||
|
}
|
||||||
|
|
||||||
startComponent(request: StartComponentRequest): Observable<any> {
|
startComponent(request: StartComponentRequest): Observable<any> {
|
||||||
const startRequest: ComponentRunStatusRequest = {
|
const startRequest: ComponentRunStatusRequest = {
|
||||||
revision: request.revision,
|
revision: request.revision,
|
||||||
|
@ -292,6 +314,24 @@ export class FlowService implements PropertyDescriptorRetriever {
|
||||||
return this.httpClient.delete(`${this.nifiCommon.stripProtocol(request.uri)}/threads`);
|
return this.httpClient.delete(`${this.nifiCommon.stripProtocol(request.uri)}/threads`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enableProcessGroup(request: EnableProcessGroupRequest): Observable<any> {
|
||||||
|
const enableRequest: ProcessGroupRunStatusRequest = {
|
||||||
|
id: request.id,
|
||||||
|
disconnectedNodeAcknowledged: this.clusterConnectionService.isDisconnectionAcknowledged(),
|
||||||
|
state: 'ENABLED'
|
||||||
|
};
|
||||||
|
return this.httpClient.put(`${FlowService.API}/flow/process-groups/${request.id}`, enableRequest);
|
||||||
|
}
|
||||||
|
|
||||||
|
disableProcessGroup(request: DisableProcessGroupRequest): Observable<any> {
|
||||||
|
const disableComponent: ProcessGroupRunStatusRequest = {
|
||||||
|
id: request.id,
|
||||||
|
disconnectedNodeAcknowledged: this.clusterConnectionService.isDisconnectionAcknowledged(),
|
||||||
|
state: 'DISABLED'
|
||||||
|
};
|
||||||
|
return this.httpClient.put(`${FlowService.API}/flow/process-groups/${request.id}`, disableComponent);
|
||||||
|
}
|
||||||
|
|
||||||
startProcessGroup(request: StartProcessGroupRequest): Observable<any> {
|
startProcessGroup(request: StartProcessGroupRequest): Observable<any> {
|
||||||
const startRequest: ProcessGroupRunStatusRequest = {
|
const startRequest: ProcessGroupRunStatusRequest = {
|
||||||
id: request.id,
|
id: request.id,
|
||||||
|
|
|
@ -34,10 +34,20 @@ import {
|
||||||
CreateRemoteProcessGroupRequest,
|
CreateRemoteProcessGroupRequest,
|
||||||
DeleteComponentRequest,
|
DeleteComponentRequest,
|
||||||
DeleteComponentResponse,
|
DeleteComponentResponse,
|
||||||
|
DisableComponentRequest,
|
||||||
|
DisableComponentResponse,
|
||||||
|
DisableComponentsRequest,
|
||||||
|
DisableProcessGroupRequest,
|
||||||
|
DisableProcessGroupResponse,
|
||||||
DownloadFlowRequest,
|
DownloadFlowRequest,
|
||||||
EditComponentDialogRequest,
|
EditComponentDialogRequest,
|
||||||
EditConnectionDialogRequest,
|
EditConnectionDialogRequest,
|
||||||
EditCurrentProcessGroupRequest,
|
EditCurrentProcessGroupRequest,
|
||||||
|
EnableComponentRequest,
|
||||||
|
EnableComponentResponse,
|
||||||
|
EnableComponentsRequest,
|
||||||
|
EnableProcessGroupRequest,
|
||||||
|
EnableProcessGroupResponse,
|
||||||
EnterProcessGroupRequest,
|
EnterProcessGroupRequest,
|
||||||
FlowUpdateRequestEntity,
|
FlowUpdateRequestEntity,
|
||||||
GoToRemoteProcessGroupRequest,
|
GoToRemoteProcessGroupRequest,
|
||||||
|
@ -588,6 +598,50 @@ export const replayLastProvenanceEvent = createAction(
|
||||||
props<{ request: ReplayLastProvenanceEventRequest }>()
|
props<{ request: ReplayLastProvenanceEventRequest }>()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
export const enableComponent = createAction(
|
||||||
|
`${CANVAS_PREFIX} Enable Component`,
|
||||||
|
props<{ request: EnableComponentRequest | EnableProcessGroupRequest }>()
|
||||||
|
);
|
||||||
|
|
||||||
|
export const enableComponents = createAction(
|
||||||
|
`${CANVAS_PREFIX} Enable Components`,
|
||||||
|
props<{ request: EnableComponentsRequest }>()
|
||||||
|
);
|
||||||
|
|
||||||
|
export const enableComponentSuccess = createAction(
|
||||||
|
`${CANVAS_PREFIX} Enable Component Success`,
|
||||||
|
props<{ response: EnableComponentResponse }>()
|
||||||
|
);
|
||||||
|
|
||||||
|
export const enableProcessGroupSuccess = createAction(
|
||||||
|
`${CANVAS_PREFIX} Enable Process Group Success`,
|
||||||
|
props<{ response: EnableProcessGroupResponse }>()
|
||||||
|
);
|
||||||
|
|
||||||
|
export const enableCurrentProcessGroup = createAction(`${CANVAS_PREFIX} Enable Current Process Group`);
|
||||||
|
|
||||||
|
export const disableComponent = createAction(
|
||||||
|
`${CANVAS_PREFIX} Disable Component`,
|
||||||
|
props<{ request: DisableComponentRequest | DisableProcessGroupRequest }>()
|
||||||
|
);
|
||||||
|
|
||||||
|
export const disableComponents = createAction(
|
||||||
|
`${CANVAS_PREFIX} Disable Components`,
|
||||||
|
props<{ request: DisableComponentsRequest }>()
|
||||||
|
);
|
||||||
|
|
||||||
|
export const disableComponentSuccess = createAction(
|
||||||
|
`${CANVAS_PREFIX} Disable Component Success`,
|
||||||
|
props<{ response: DisableComponentResponse }>()
|
||||||
|
);
|
||||||
|
|
||||||
|
export const disableProcessGroupSuccess = createAction(
|
||||||
|
`${CANVAS_PREFIX} Disable Process Group Success`,
|
||||||
|
props<{ response: DisableProcessGroupResponse }>()
|
||||||
|
);
|
||||||
|
|
||||||
|
export const disableCurrentProcessGroup = createAction(`${CANVAS_PREFIX} Disable Current Process Group`);
|
||||||
|
|
||||||
export const runOnce = createAction(`${CANVAS_PREFIX} Run Once`, props<{ request: RunOnceRequest }>());
|
export const runOnce = createAction(`${CANVAS_PREFIX} Run Once`, props<{ request: RunOnceRequest }>());
|
||||||
|
|
||||||
export const runOnceSuccess = createAction(`${CANVAS_PREFIX} Run Once Success`, props<{ response: RunOnceResponse }>());
|
export const runOnceSuccess = createAction(`${CANVAS_PREFIX} Run Once Success`, props<{ response: RunOnceResponse }>());
|
||||||
|
|
|
@ -2436,6 +2436,240 @@ export class FlowEffects {
|
||||||
{ dispatch: false }
|
{ dispatch: false }
|
||||||
);
|
);
|
||||||
|
|
||||||
|
enableCurrentProcessGroup$ = createEffect(() =>
|
||||||
|
this.actions$.pipe(
|
||||||
|
ofType(FlowActions.enableCurrentProcessGroup),
|
||||||
|
concatLatestFrom(() => this.store.select(selectCurrentProcessGroupId)),
|
||||||
|
switchMap(([, pgId]) => {
|
||||||
|
return of(
|
||||||
|
FlowActions.enableComponent({
|
||||||
|
request: {
|
||||||
|
id: pgId,
|
||||||
|
type: ComponentType.ProcessGroup
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
})
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
enableComponents$ = createEffect(() =>
|
||||||
|
this.actions$.pipe(
|
||||||
|
ofType(FlowActions.enableComponents),
|
||||||
|
map((action) => action.request),
|
||||||
|
mergeMap((request) => [
|
||||||
|
...request.components.map((component) => {
|
||||||
|
return FlowActions.enableComponent({
|
||||||
|
request: component
|
||||||
|
});
|
||||||
|
})
|
||||||
|
])
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
enableComponent$ = createEffect(() =>
|
||||||
|
this.actions$.pipe(
|
||||||
|
ofType(FlowActions.enableComponent),
|
||||||
|
map((action) => action.request),
|
||||||
|
mergeMap((request) => {
|
||||||
|
switch (request.type) {
|
||||||
|
case ComponentType.InputPort:
|
||||||
|
case ComponentType.OutputPort:
|
||||||
|
case ComponentType.Processor:
|
||||||
|
if ('uri' in request && 'revision' in request) {
|
||||||
|
return from(this.flowService.enableComponent(request)).pipe(
|
||||||
|
map((response) => {
|
||||||
|
return FlowActions.enableComponentSuccess({
|
||||||
|
response: {
|
||||||
|
type: request.type,
|
||||||
|
component: response
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}),
|
||||||
|
catchError((errorResponse: HttpErrorResponse) =>
|
||||||
|
of(FlowActions.flowSnackbarError({ error: errorResponse.error }))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return of(
|
||||||
|
FlowActions.flowSnackbarError({
|
||||||
|
error: `Enabling ${request.type} requires both uri and revision properties`
|
||||||
|
})
|
||||||
|
);
|
||||||
|
case ComponentType.ProcessGroup:
|
||||||
|
return from(this.flowService.enableProcessGroup(request)).pipe(
|
||||||
|
map((enablePgResponse) => {
|
||||||
|
return FlowActions.enableProcessGroupSuccess({
|
||||||
|
response: {
|
||||||
|
type: request.type,
|
||||||
|
component: enablePgResponse
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}),
|
||||||
|
catchError((errorResponse: HttpErrorResponse) =>
|
||||||
|
of(FlowActions.flowSnackbarError({ error: errorResponse.error }))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
default:
|
||||||
|
return of(
|
||||||
|
FlowActions.flowSnackbarError({ error: `${request.type} does not support enabling` })
|
||||||
|
);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the component enabled was the current process group, reload the flow
|
||||||
|
*/
|
||||||
|
enableCurrentProcessGroupSuccess$ = createEffect(() =>
|
||||||
|
this.actions$.pipe(
|
||||||
|
ofType(FlowActions.enableProcessGroupSuccess),
|
||||||
|
map((action) => action.response),
|
||||||
|
concatLatestFrom(() => this.store.select(selectCurrentProcessGroupId)),
|
||||||
|
filter(([response, currentPg]) => response.component.id === currentPg),
|
||||||
|
switchMap(() => of(FlowActions.reloadFlow()))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If a ProcessGroup was enabled, it should be reloaded as the response from the start operation doesn't contain all the displayed info
|
||||||
|
*/
|
||||||
|
enableProcessGroupSuccess$ = createEffect(() =>
|
||||||
|
this.actions$.pipe(
|
||||||
|
ofType(FlowActions.enableProcessGroupSuccess),
|
||||||
|
map((action) => action.response),
|
||||||
|
concatLatestFrom(() => this.store.select(selectCurrentProcessGroupId)),
|
||||||
|
filter(([response, currentPg]) => response.component.id !== currentPg),
|
||||||
|
switchMap(([response]) =>
|
||||||
|
of(
|
||||||
|
FlowActions.loadChildProcessGroup({
|
||||||
|
request: {
|
||||||
|
id: response.component.id
|
||||||
|
}
|
||||||
|
})
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
disableCurrentProcessGroup$ = createEffect(() =>
|
||||||
|
this.actions$.pipe(
|
||||||
|
ofType(FlowActions.disableCurrentProcessGroup),
|
||||||
|
concatLatestFrom(() => this.store.select(selectCurrentProcessGroupId)),
|
||||||
|
switchMap(([, pgId]) => {
|
||||||
|
return of(
|
||||||
|
FlowActions.disableComponent({
|
||||||
|
request: {
|
||||||
|
id: pgId,
|
||||||
|
type: ComponentType.ProcessGroup
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
})
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
disableComponents$ = createEffect(() =>
|
||||||
|
this.actions$.pipe(
|
||||||
|
ofType(FlowActions.disableComponents),
|
||||||
|
map((action) => action.request),
|
||||||
|
mergeMap((request) => [
|
||||||
|
...request.components.map((component) => {
|
||||||
|
return FlowActions.disableComponent({
|
||||||
|
request: component
|
||||||
|
});
|
||||||
|
})
|
||||||
|
])
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
disableComponent$ = createEffect(() =>
|
||||||
|
this.actions$.pipe(
|
||||||
|
ofType(FlowActions.disableComponent),
|
||||||
|
map((action) => action.request),
|
||||||
|
mergeMap((request) => {
|
||||||
|
switch (request.type) {
|
||||||
|
case ComponentType.InputPort:
|
||||||
|
case ComponentType.OutputPort:
|
||||||
|
case ComponentType.Processor:
|
||||||
|
if ('uri' in request && 'revision' in request) {
|
||||||
|
return from(this.flowService.disableComponent(request)).pipe(
|
||||||
|
map((response) => {
|
||||||
|
return FlowActions.disableComponentSuccess({
|
||||||
|
response: {
|
||||||
|
type: request.type,
|
||||||
|
component: response
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}),
|
||||||
|
catchError((errorResponse: HttpErrorResponse) =>
|
||||||
|
of(FlowActions.flowSnackbarError({ error: errorResponse.error }))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return of(
|
||||||
|
FlowActions.flowSnackbarError({
|
||||||
|
error: `Disabling ${request.type} requires both uri and revision properties`
|
||||||
|
})
|
||||||
|
);
|
||||||
|
case ComponentType.ProcessGroup:
|
||||||
|
return from(this.flowService.disableProcessGroup(request)).pipe(
|
||||||
|
map((enablePgResponse) => {
|
||||||
|
return FlowActions.disableProcessGroupSuccess({
|
||||||
|
response: {
|
||||||
|
type: request.type,
|
||||||
|
component: enablePgResponse
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}),
|
||||||
|
catchError((errorResponse: HttpErrorResponse) =>
|
||||||
|
of(FlowActions.flowSnackbarError({ error: errorResponse.error }))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
default:
|
||||||
|
return of(
|
||||||
|
FlowActions.flowSnackbarError({ error: `${request.type} does not support disabling` })
|
||||||
|
);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the component disabled was the current process group, reload the flow
|
||||||
|
*/
|
||||||
|
disableCurrentProcessGroupSuccess$ = createEffect(() =>
|
||||||
|
this.actions$.pipe(
|
||||||
|
ofType(FlowActions.disableProcessGroupSuccess),
|
||||||
|
map((action) => action.response),
|
||||||
|
concatLatestFrom(() => this.store.select(selectCurrentProcessGroupId)),
|
||||||
|
filter(([response, currentPg]) => response.component.id === currentPg),
|
||||||
|
switchMap(() => of(FlowActions.reloadFlow()))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If a ProcessGroup was disabled, it should be reloaded as the response from the start operation doesn't contain all the displayed info
|
||||||
|
*/
|
||||||
|
disableProcessGroupSuccess$ = createEffect(() =>
|
||||||
|
this.actions$.pipe(
|
||||||
|
ofType(FlowActions.disableProcessGroupSuccess),
|
||||||
|
map((action) => action.response),
|
||||||
|
concatLatestFrom(() => this.store.select(selectCurrentProcessGroupId)),
|
||||||
|
filter(([response, currentPg]) => response.component.id !== currentPg),
|
||||||
|
switchMap(([response]) =>
|
||||||
|
of(
|
||||||
|
FlowActions.loadChildProcessGroup({
|
||||||
|
request: {
|
||||||
|
id: response.component.id
|
||||||
|
}
|
||||||
|
})
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
startCurrentProcessGroup$ = createEffect(() =>
|
startCurrentProcessGroup$ = createEffect(() =>
|
||||||
this.actions$.pipe(
|
this.actions$.pipe(
|
||||||
ofType(FlowActions.startCurrentProcessGroup),
|
ofType(FlowActions.startCurrentProcessGroup),
|
||||||
|
@ -2449,8 +2683,7 @@ export class FlowEffects {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}),
|
})
|
||||||
catchError((error) => of(FlowActions.flowApiError({ error: error.error })))
|
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -2488,11 +2721,13 @@ export class FlowEffects {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}),
|
}),
|
||||||
catchError((error) => of(FlowActions.flowApiError({ error: error.error })))
|
catchError((errorResponse: HttpErrorResponse) =>
|
||||||
|
of(FlowActions.flowSnackbarError({ error: errorResponse.error }))
|
||||||
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return of(
|
return of(
|
||||||
FlowActions.flowApiError({
|
FlowActions.flowSnackbarError({
|
||||||
error: `Starting ${request.type} requires both uri and revision properties`
|
error: `Starting ${request.type} requires both uri and revision properties`
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
@ -2509,13 +2744,16 @@ export class FlowEffects {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}),
|
}),
|
||||||
catchError((error) => of(FlowActions.flowApiError({ error: error.error })))
|
catchError((errorResponse: HttpErrorResponse) =>
|
||||||
|
of(FlowActions.flowSnackbarError({ error: errorResponse.error }))
|
||||||
|
)
|
||||||
);
|
);
|
||||||
default:
|
default:
|
||||||
return of(FlowActions.flowApiError({ error: `${request.type} does not support starting` }));
|
return of(
|
||||||
|
FlowActions.flowSnackbarError({ error: `${request.type} does not support starting` })
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}),
|
})
|
||||||
catchError((error) => of(FlowActions.flowApiError({ error: error.error })))
|
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -2604,11 +2842,13 @@ export class FlowEffects {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}),
|
}),
|
||||||
catchError((error) => of(FlowActions.flowApiError({ error: error.error })))
|
catchError((errorResponse: HttpErrorResponse) =>
|
||||||
|
of(FlowActions.flowSnackbarError({ error: errorResponse.error }))
|
||||||
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return of(
|
return of(
|
||||||
FlowActions.flowApiError({
|
FlowActions.flowSnackbarError({
|
||||||
error: `Stopping ${request.type} requires both uri and revision properties`
|
error: `Stopping ${request.type} requires both uri and revision properties`
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
@ -2625,13 +2865,16 @@ export class FlowEffects {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}),
|
}),
|
||||||
catchError((error) => of(FlowActions.flowApiError({ error: error.error })))
|
catchError((errorResponse: HttpErrorResponse) =>
|
||||||
|
of(FlowActions.flowSnackbarError({ error: errorResponse.error }))
|
||||||
|
)
|
||||||
);
|
);
|
||||||
default:
|
default:
|
||||||
return of(FlowActions.flowApiError({ error: `${request.type} does not support stopping` }));
|
return of(
|
||||||
|
FlowActions.flowSnackbarError({ error: `${request.type} does not support stopping` })
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}),
|
})
|
||||||
catchError((error) => of(FlowActions.flowApiError({ error: error.error })))
|
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -2739,6 +2982,7 @@ export class FlowEffects {
|
||||||
//////////////////////////////////
|
//////////////////////////////////
|
||||||
// Start version control effects
|
// Start version control effects
|
||||||
//////////////////////////////////
|
//////////////////////////////////
|
||||||
|
|
||||||
openSaveVersionDialogRequest$ = createEffect(() =>
|
openSaveVersionDialogRequest$ = createEffect(() =>
|
||||||
this.actions$.pipe(
|
this.actions$.pipe(
|
||||||
ofType(FlowActions.openSaveVersionDialogRequest),
|
ofType(FlowActions.openSaveVersionDialogRequest),
|
||||||
|
|
|
@ -30,6 +30,12 @@ import {
|
||||||
createProcessGroup,
|
createProcessGroup,
|
||||||
createProcessor,
|
createProcessor,
|
||||||
deleteComponentsSuccess,
|
deleteComponentsSuccess,
|
||||||
|
disableComponent,
|
||||||
|
disableComponentSuccess,
|
||||||
|
disableProcessGroupSuccess,
|
||||||
|
enableComponent,
|
||||||
|
enableComponentSuccess,
|
||||||
|
enableProcessGroupSuccess,
|
||||||
flowApiError,
|
flowApiError,
|
||||||
flowVersionBannerError,
|
flowVersionBannerError,
|
||||||
groupComponents,
|
groupComponents,
|
||||||
|
@ -61,8 +67,11 @@ import {
|
||||||
setTransitionRequired,
|
setTransitionRequired,
|
||||||
startComponent,
|
startComponent,
|
||||||
startComponentSuccess,
|
startComponentSuccess,
|
||||||
|
startProcessGroupSuccess,
|
||||||
startRemoteProcessGroupPolling,
|
startRemoteProcessGroupPolling,
|
||||||
|
stopComponent,
|
||||||
stopComponentSuccess,
|
stopComponentSuccess,
|
||||||
|
stopProcessGroupSuccess,
|
||||||
stopRemoteProcessGroupPolling,
|
stopRemoteProcessGroupPolling,
|
||||||
stopVersionControl,
|
stopVersionControl,
|
||||||
stopVersionControlSuccess,
|
stopVersionControlSuccess,
|
||||||
|
@ -275,10 +284,30 @@ export const flowReducer = createReducer(
|
||||||
dragging: false,
|
dragging: false,
|
||||||
saving: false
|
saving: false
|
||||||
})),
|
})),
|
||||||
on(updateComponent, updateProcessor, updateConnection, startComponent, runOnce, (state) => ({
|
on(
|
||||||
...state,
|
updateComponent,
|
||||||
saving: true
|
updateProcessor,
|
||||||
})),
|
updateConnection,
|
||||||
|
enableComponent,
|
||||||
|
disableComponent,
|
||||||
|
startComponent,
|
||||||
|
stopComponent,
|
||||||
|
runOnce,
|
||||||
|
(state) => ({
|
||||||
|
...state,
|
||||||
|
saving: true
|
||||||
|
})
|
||||||
|
),
|
||||||
|
on(
|
||||||
|
enableProcessGroupSuccess,
|
||||||
|
disableProcessGroupSuccess,
|
||||||
|
startProcessGroupSuccess,
|
||||||
|
stopProcessGroupSuccess,
|
||||||
|
(state) => ({
|
||||||
|
...state,
|
||||||
|
saving: false
|
||||||
|
})
|
||||||
|
),
|
||||||
on(updateComponentSuccess, updateProcessorSuccess, updateConnectionSuccess, (state, { response }) => {
|
on(updateComponentSuccess, updateProcessorSuccess, updateConnectionSuccess, (state, { response }) => {
|
||||||
return produce(state, (draftState) => {
|
return produce(state, (draftState) => {
|
||||||
const collection: any[] | null = getComponentCollection(draftState, response.type);
|
const collection: any[] | null = getComponentCollection(draftState, response.type);
|
||||||
|
@ -400,20 +429,26 @@ export const flowReducer = createReducer(
|
||||||
...state,
|
...state,
|
||||||
operationCollapsed
|
operationCollapsed
|
||||||
})),
|
})),
|
||||||
on(startComponentSuccess, stopComponentSuccess, (state, { response }) => {
|
on(
|
||||||
return produce(state, (draftState) => {
|
startComponentSuccess,
|
||||||
const collection: any[] | null = getComponentCollection(draftState, response.type);
|
stopComponentSuccess,
|
||||||
|
enableComponentSuccess,
|
||||||
|
disableComponentSuccess,
|
||||||
|
(state, { response }) => {
|
||||||
|
return produce(state, (draftState) => {
|
||||||
|
const collection: any[] | null = getComponentCollection(draftState, response.type);
|
||||||
|
|
||||||
if (collection) {
|
if (collection) {
|
||||||
const componentIndex: number = collection.findIndex((f: any) => response.component.id === f.id);
|
const componentIndex: number = collection.findIndex((f: any) => response.component.id === f.id);
|
||||||
if (componentIndex > -1) {
|
if (componentIndex > -1) {
|
||||||
collection[componentIndex] = response.component;
|
collection[componentIndex] = response.component;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
draftState.saving = false;
|
draftState.saving = false;
|
||||||
});
|
});
|
||||||
}),
|
}
|
||||||
|
),
|
||||||
|
|
||||||
on(runOnceSuccess, (state, { response }) => {
|
on(runOnceSuccess, (state, { response }) => {
|
||||||
return produce(state, (draftState) => {
|
return produce(state, (draftState) => {
|
||||||
|
|
|
@ -655,6 +655,64 @@ export interface RunOnceResponse {
|
||||||
component: ComponentEntity;
|
component: ComponentEntity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface EnableProcessGroupRequest {
|
||||||
|
id: string;
|
||||||
|
type: ComponentType;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface EnableComponentRequest {
|
||||||
|
id: string;
|
||||||
|
uri: string;
|
||||||
|
type: ComponentType;
|
||||||
|
revision: Revision;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface EnableComponentsRequest {
|
||||||
|
components: EnableComponentRequest[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface EnableComponentResponse {
|
||||||
|
type: ComponentType;
|
||||||
|
component: ComponentEntity;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface EnableProcessGroupResponse {
|
||||||
|
type: ComponentType;
|
||||||
|
component: {
|
||||||
|
id: string;
|
||||||
|
state: string;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DisableProcessGroupRequest {
|
||||||
|
id: string;
|
||||||
|
type: ComponentType;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DisableComponentRequest {
|
||||||
|
id: string;
|
||||||
|
uri: string;
|
||||||
|
type: ComponentType;
|
||||||
|
revision: Revision;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DisableComponentsRequest {
|
||||||
|
components: DisableComponentRequest[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DisableComponentResponse {
|
||||||
|
type: ComponentType;
|
||||||
|
component: ComponentEntity;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface DisableProcessGroupResponse {
|
||||||
|
type: ComponentType;
|
||||||
|
component: {
|
||||||
|
id: string;
|
||||||
|
state: string;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
export interface StartProcessGroupRequest {
|
export interface StartProcessGroupRequest {
|
||||||
id: string;
|
id: string;
|
||||||
type: ComponentType;
|
type: ComponentType;
|
||||||
|
@ -692,10 +750,6 @@ export interface StopProcessGroupResponse {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface StartComponentsResponse {
|
|
||||||
components: StartComponentsResponse[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ComponentRunStatusRequest {
|
export interface ComponentRunStatusRequest {
|
||||||
revision: Revision;
|
revision: Revision;
|
||||||
state: string;
|
state: string;
|
||||||
|
|
|
@ -19,6 +19,10 @@ import { Component, Input } from '@angular/core';
|
||||||
import {
|
import {
|
||||||
copy,
|
copy,
|
||||||
deleteComponents,
|
deleteComponents,
|
||||||
|
disableComponents,
|
||||||
|
disableCurrentProcessGroup,
|
||||||
|
enableComponents,
|
||||||
|
enableCurrentProcessGroup,
|
||||||
getParameterContextsAndOpenGroupComponentsDialog,
|
getParameterContextsAndOpenGroupComponentsDialog,
|
||||||
navigateToEditComponent,
|
navigateToEditComponent,
|
||||||
navigateToEditCurrentProcessGroup,
|
navigateToEditCurrentProcessGroup,
|
||||||
|
@ -38,6 +42,8 @@ import { Storage } from '../../../../../../service/storage.service';
|
||||||
import {
|
import {
|
||||||
CopyComponentRequest,
|
CopyComponentRequest,
|
||||||
DeleteComponentRequest,
|
DeleteComponentRequest,
|
||||||
|
DisableComponentRequest,
|
||||||
|
EnableComponentRequest,
|
||||||
MoveComponentRequest,
|
MoveComponentRequest,
|
||||||
StartComponentRequest,
|
StartComponentRequest,
|
||||||
StopComponentRequest
|
StopComponentRequest
|
||||||
|
@ -48,6 +54,7 @@ import { ComponentType } from '../../../../../../state/shared';
|
||||||
import { MatButtonModule } from '@angular/material/button';
|
import { MatButtonModule } from '@angular/material/button';
|
||||||
import * as d3 from 'd3';
|
import * as d3 from 'd3';
|
||||||
import { CanvasView } from '../../../../service/canvas-view.service';
|
import { CanvasView } from '../../../../service/canvas-view.service';
|
||||||
|
import { Client } from '../../../../../../service/client.service';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'operation-control',
|
selector: 'operation-control',
|
||||||
|
@ -69,6 +76,7 @@ export class OperationControl {
|
||||||
private store: Store<CanvasState>,
|
private store: Store<CanvasState>,
|
||||||
public canvasUtils: CanvasUtils,
|
public canvasUtils: CanvasUtils,
|
||||||
private canvasView: CanvasView,
|
private canvasView: CanvasView,
|
||||||
|
private client: Client,
|
||||||
private storage: Storage
|
private storage: Storage
|
||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
|
@ -76,7 +84,7 @@ export class OperationControl {
|
||||||
OperationControl.CONTROL_VISIBILITY_KEY
|
OperationControl.CONTROL_VISIBILITY_KEY
|
||||||
);
|
);
|
||||||
if (item) {
|
if (item) {
|
||||||
this.operationCollapsed = item[OperationControl.OPERATION_KEY] === false;
|
this.operationCollapsed = !item[OperationControl.OPERATION_KEY];
|
||||||
this.store.dispatch(setOperationCollapsed({ operationCollapsed: this.operationCollapsed }));
|
this.store.dispatch(setOperationCollapsed({ operationCollapsed: this.operationCollapsed }));
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
@ -98,7 +106,7 @@ export class OperationControl {
|
||||||
this.storage.setItem(OperationControl.CONTROL_VISIBILITY_KEY, item);
|
this.storage.setItem(OperationControl.CONTROL_VISIBILITY_KEY, item);
|
||||||
}
|
}
|
||||||
|
|
||||||
getContextIcon(selection: any): string {
|
getContextIcon(selection: d3.Selection<any, any, any, any>): string {
|
||||||
if (selection.size() === 0) {
|
if (selection.size() === 0) {
|
||||||
if (this.breadcrumbEntity.parentBreadcrumb == null) {
|
if (this.breadcrumbEntity.parentBreadcrumb == null) {
|
||||||
return 'icon-drop';
|
return 'icon-drop';
|
||||||
|
@ -128,7 +136,7 @@ export class OperationControl {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getContextName(selection: any): string {
|
getContextName(selection: d3.Selection<any, any, any, any>): string {
|
||||||
if (selection.size() === 0) {
|
if (selection.size() === 0) {
|
||||||
if (this.breadcrumbEntity.permissions.canRead) {
|
if (this.breadcrumbEntity.permissions.canRead) {
|
||||||
return this.breadcrumbEntity.breadcrumb.name;
|
return this.breadcrumbEntity.breadcrumb.name;
|
||||||
|
@ -153,7 +161,7 @@ export class OperationControl {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getContextType(selection: any): string {
|
getContextType(selection: d3.Selection<any, any, any, any>): string {
|
||||||
if (selection.size() === 0) {
|
if (selection.size() === 0) {
|
||||||
return 'Process Group';
|
return 'Process Group';
|
||||||
} else if (selection.size() > 1) {
|
} else if (selection.size() > 1) {
|
||||||
|
@ -179,7 +187,7 @@ export class OperationControl {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getContextId(selection: any): string {
|
getContextId(selection: d3.Selection<any, any, any, any>): string {
|
||||||
if (selection.size() === 0) {
|
if (selection.size() === 0) {
|
||||||
return this.breadcrumbEntity.id;
|
return this.breadcrumbEntity.id;
|
||||||
} else if (selection.size() > 1) {
|
} else if (selection.size() > 1) {
|
||||||
|
@ -190,11 +198,11 @@ export class OperationControl {
|
||||||
return selectionData.id;
|
return selectionData.id;
|
||||||
}
|
}
|
||||||
|
|
||||||
canConfigure(selection: any): boolean {
|
canConfigure(selection: d3.Selection<any, any, any, any>): boolean {
|
||||||
return this.canvasUtils.isConfigurable(selection);
|
return this.canvasUtils.isConfigurable(selection);
|
||||||
}
|
}
|
||||||
|
|
||||||
configure(selection: any): void {
|
configure(selection: d3.Selection<any, any, any, any>): void {
|
||||||
if (selection.empty()) {
|
if (selection.empty()) {
|
||||||
this.store.dispatch(navigateToEditCurrentProcessGroup());
|
this.store.dispatch(navigateToEditCurrentProcessGroup());
|
||||||
} else {
|
} else {
|
||||||
|
@ -214,11 +222,11 @@ export class OperationControl {
|
||||||
return this.canvasUtils.supportsManagedAuthorizer();
|
return this.canvasUtils.supportsManagedAuthorizer();
|
||||||
}
|
}
|
||||||
|
|
||||||
canManageAccess(selection: any): boolean {
|
canManageAccess(selection: d3.Selection<any, any, any, any>): boolean {
|
||||||
return this.canvasUtils.canManagePolicies(selection);
|
return this.canvasUtils.canManagePolicies(selection);
|
||||||
}
|
}
|
||||||
|
|
||||||
manageAccess(selection: any): void {
|
manageAccess(selection: d3.Selection<any, any, any, any>): void {
|
||||||
if (selection.empty()) {
|
if (selection.empty()) {
|
||||||
this.store.dispatch(
|
this.store.dispatch(
|
||||||
navigateToManageComponentPolicies({
|
navigateToManageComponentPolicies({
|
||||||
|
@ -265,29 +273,69 @@ export class OperationControl {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
canEnable(selection: any): boolean {
|
canEnable(selection: d3.Selection<any, any, any, any>): boolean {
|
||||||
// TODO - canEnable
|
return this.canvasUtils.canEnable(selection);
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
enable(selection: any): void {
|
enable(selection: d3.Selection<any, any, any, any>): void {
|
||||||
// TODO - enable
|
if (selection.empty()) {
|
||||||
|
// attempting to enable the current process group
|
||||||
|
this.store.dispatch(enableCurrentProcessGroup());
|
||||||
|
} else {
|
||||||
|
const components: EnableComponentRequest[] = [];
|
||||||
|
const enableable = this.canvasUtils.filterEnable(selection);
|
||||||
|
enableable.each((d: any) => {
|
||||||
|
components.push({
|
||||||
|
id: d.id,
|
||||||
|
uri: d.uri,
|
||||||
|
type: d.type,
|
||||||
|
revision: this.client.getRevision(d)
|
||||||
|
});
|
||||||
|
});
|
||||||
|
this.store.dispatch(
|
||||||
|
enableComponents({
|
||||||
|
request: {
|
||||||
|
components
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
canDisable(selection: any): boolean {
|
canDisable(selection: d3.Selection<any, any, any, any>): boolean {
|
||||||
// TODO - canDisable
|
return this.canvasUtils.canDisable(selection);
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
disable(selection: any): void {
|
disable(selection: d3.Selection<any, any, any, any>): void {
|
||||||
// TODO - disable
|
if (selection.empty()) {
|
||||||
|
// attempting to disable the current process group
|
||||||
|
this.store.dispatch(disableCurrentProcessGroup());
|
||||||
|
} else {
|
||||||
|
const components: DisableComponentRequest[] = [];
|
||||||
|
const disableable = this.canvasUtils.filterDisable(selection);
|
||||||
|
disableable.each((d: any) => {
|
||||||
|
components.push({
|
||||||
|
id: d.id,
|
||||||
|
uri: d.uri,
|
||||||
|
type: d.type,
|
||||||
|
revision: this.client.getRevision(d)
|
||||||
|
});
|
||||||
|
});
|
||||||
|
this.store.dispatch(
|
||||||
|
disableComponents({
|
||||||
|
request: {
|
||||||
|
components
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
canStart(selection: any): boolean {
|
canStart(selection: d3.Selection<any, any, any, any>): boolean {
|
||||||
return this.canvasUtils.areAnyRunnable(selection);
|
return this.canvasUtils.areAnyRunnable(selection);
|
||||||
}
|
}
|
||||||
|
|
||||||
start(selection: any): void {
|
start(selection: d3.Selection<any, any, any, any>): void {
|
||||||
if (selection.empty()) {
|
if (selection.empty()) {
|
||||||
// attempting to start the current process group
|
// attempting to start the current process group
|
||||||
this.store.dispatch(startCurrentProcessGroup());
|
this.store.dispatch(startCurrentProcessGroup());
|
||||||
|
@ -299,7 +347,7 @@ export class OperationControl {
|
||||||
id: d.id,
|
id: d.id,
|
||||||
uri: d.uri,
|
uri: d.uri,
|
||||||
type: d.type,
|
type: d.type,
|
||||||
revision: d.revision
|
revision: this.client.getRevision(d)
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
this.store.dispatch(
|
this.store.dispatch(
|
||||||
|
@ -312,11 +360,11 @@ export class OperationControl {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
canStop(selection: any): boolean {
|
canStop(selection: d3.Selection<any, any, any, any>): boolean {
|
||||||
return this.canvasUtils.areAnyStoppable(selection);
|
return this.canvasUtils.areAnyStoppable(selection);
|
||||||
}
|
}
|
||||||
|
|
||||||
stop(selection: any): void {
|
stop(selection: d3.Selection<any, any, any, any>): void {
|
||||||
if (selection.empty()) {
|
if (selection.empty()) {
|
||||||
// attempting to start the current process group
|
// attempting to start the current process group
|
||||||
this.store.dispatch(stopCurrentProcessGroup());
|
this.store.dispatch(stopCurrentProcessGroup());
|
||||||
|
@ -328,7 +376,7 @@ export class OperationControl {
|
||||||
id: d.id,
|
id: d.id,
|
||||||
uri: d.uri,
|
uri: d.uri,
|
||||||
type: d.type,
|
type: d.type,
|
||||||
revision: d.revision
|
revision: this.client.getRevision(d)
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
this.store.dispatch(
|
this.store.dispatch(
|
||||||
|
@ -382,11 +430,11 @@ export class OperationControl {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
canGroup(selection: any): boolean {
|
canGroup(selection: d3.Selection<any, any, any, any>): boolean {
|
||||||
return this.canvasUtils.isDisconnected(selection);
|
return this.canvasUtils.isDisconnected(selection);
|
||||||
}
|
}
|
||||||
|
|
||||||
group(selection: any): void {
|
group(selection: d3.Selection<any, any, any, any>): void {
|
||||||
const moveComponents: MoveComponentRequest[] = [];
|
const moveComponents: MoveComponentRequest[] = [];
|
||||||
selection.each(function (d: any) {
|
selection.each(function (d: any) {
|
||||||
moveComponents.push({
|
moveComponents.push({
|
||||||
|
@ -408,20 +456,20 @@ export class OperationControl {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
canColor(selection: any): boolean {
|
canColor(selection: d3.Selection<any, any, any, any>): boolean {
|
||||||
// TODO
|
// TODO
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
color(selection: any): void {
|
color(selection: d3.Selection<any, any, any, any>): void {
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
canDelete(selection: any): boolean {
|
canDelete(selection: d3.Selection<any, any, any, any>): boolean {
|
||||||
return this.canvasUtils.areDeletable(selection);
|
return this.canvasUtils.areDeletable(selection);
|
||||||
}
|
}
|
||||||
|
|
||||||
delete(selection: any): void {
|
delete(selection: d3.Selection<any, any, any, any>): void {
|
||||||
if (selection.size() === 1) {
|
if (selection.size() === 1) {
|
||||||
const selectionData = selection.datum();
|
const selectionData = selection.datum();
|
||||||
this.store.dispatch(
|
this.store.dispatch(
|
||||||
|
|
Loading…
Reference in New Issue