aboutsummaryrefslogtreecommitdiffstats
path: root/catalog-ui/src/app/ng2/store
diff options
context:
space:
mode:
Diffstat (limited to 'catalog-ui/src/app/ng2/store')
-rw-r--r--catalog-ui/src/app/ng2/store/actions/artifacts.action.ts25
-rw-r--r--catalog-ui/src/app/ng2/store/actions/instance-artifacts.actions.ts32
-rw-r--r--catalog-ui/src/app/ng2/store/actions/workspace.action.ts17
-rw-r--r--catalog-ui/src/app/ng2/store/states/artifacts.state.spec.ts62
-rw-r--r--catalog-ui/src/app/ng2/store/states/artifacts.state.ts140
-rw-r--r--catalog-ui/src/app/ng2/store/states/instance-artifacts.state.ts145
-rw-r--r--catalog-ui/src/app/ng2/store/states/workspace.state.ts48
7 files changed, 469 insertions, 0 deletions
diff --git a/catalog-ui/src/app/ng2/store/actions/artifacts.action.ts b/catalog-ui/src/app/ng2/store/actions/artifacts.action.ts
new file mode 100644
index 0000000000..a00cc3a9ec
--- /dev/null
+++ b/catalog-ui/src/app/ng2/store/actions/artifacts.action.ts
@@ -0,0 +1,25 @@
+/**
+ * Created by ob0695
+ */
+import {ArtifactModel} from "../../../models/artifacts";
+
+export class GetArtifactsByTypeAction {
+ static readonly type = '[ARTIFACTS] GetArtifactsByType';
+
+ constructor(public payload: {componentType:string, componentId:string, artifactType: string}) {
+ }
+}
+
+export class CreateOrUpdateArtifactAction {
+ static readonly type = '[ARTIFACTS] CreateOrUpdateArtifactAction';
+
+ constructor(public payload: {componentType:string, componentId:string, artifact:ArtifactModel}) {
+ }
+}
+
+export class DeleteArtifactAction {
+ static readonly type = '[ARTIFACTS] DeleteArtifactAction';
+
+ constructor(public payload: {componentType:string, componentId:string, artifact: ArtifactModel}) {
+ }
+}
diff --git a/catalog-ui/src/app/ng2/store/actions/instance-artifacts.actions.ts b/catalog-ui/src/app/ng2/store/actions/instance-artifacts.actions.ts
new file mode 100644
index 0000000000..0f1df78352
--- /dev/null
+++ b/catalog-ui/src/app/ng2/store/actions/instance-artifacts.actions.ts
@@ -0,0 +1,32 @@
+/**
+ * Created by ob0695
+ */
+import {ArtifactModel} from "../../../models/artifacts";
+
+export class GetInstanceArtifactsByTypeAction {
+ static readonly type = '[INSTANCE_ARTIFACTS] GetInstanceArtifactsByTypeAction';
+
+ constructor(public payload: { componentType: string, componentId: string, artifactType: string, instanceId: string }) {
+ }
+}
+
+export class CreateInstanceArtifactAction {
+ static readonly type = '[INSTANCE_ARTIFACTS] CreateInstanceArtifactAction';
+
+ constructor(public payload: { componentType: string, componentId: string, instanceId: string, artifact: ArtifactModel }) {
+ }
+}
+
+export class UpdateInstanceArtifactAction {
+ static readonly type = '[INSTANCE_ARTIFACTS] UpdateInstanceArtifactAction';
+
+ constructor(public payload: { componentType: string, componentId: string, instanceId: string, artifact: ArtifactModel }) {
+ }
+}
+
+export class DeleteInstanceArtifactAction {
+ static readonly type = '[INSTANCE_ARTIFACTS] DeleteInstanceArtifactAction';
+
+ constructor(public payload: { componentType: string, componentId: string, instanceId: string, artifact: ArtifactModel }) {
+ }
+}
diff --git a/catalog-ui/src/app/ng2/store/actions/workspace.action.ts b/catalog-ui/src/app/ng2/store/actions/workspace.action.ts
new file mode 100644
index 0000000000..c7f18e0ac6
--- /dev/null
+++ b/catalog-ui/src/app/ng2/store/actions/workspace.action.ts
@@ -0,0 +1,17 @@
+/**
+ * Created by ob0695 on 7/17/2018.
+ */
+
+export class UpdateIsViewOnly {
+ static readonly type = '[WORKSPACE] UpdateIsViewOnly';
+
+ constructor(public isViewOnly:boolean) {
+ }
+}
+
+export class UpdateIsDesigner {
+ static readonly type = '[WORKSPACE] UpdateIsDesigner';
+
+ constructor(public isDesigner:boolean) {
+ }
+}
diff --git a/catalog-ui/src/app/ng2/store/states/artifacts.state.spec.ts b/catalog-ui/src/app/ng2/store/states/artifacts.state.spec.ts
new file mode 100644
index 0000000000..c59a4455b6
--- /dev/null
+++ b/catalog-ui/src/app/ng2/store/states/artifacts.state.spec.ts
@@ -0,0 +1,62 @@
+import { Store } from '@ngxs/store';
+import { Observable } from 'rxjs/Rx';
+import { Mock } from 'ts-mockery';
+import { ArtifactModel } from '../../../models/artifacts';
+import { ArtifactGroupType } from '../../../utils/constants';
+import { ComponentInstanceServiceNg2 } from '../../services/component-instance-services/component-instance.service';
+import { GetInstanceArtifactsByTypeAction, UpdateInstanceArtifactAction } from '../actions/instance-artifacts.actions';
+import { InstanceArtifactsState } from './instance-artifacts.state';
+
+describe('Test Artifact State', () => {
+
+ const heat1 = Mock.of<ArtifactModel>({
+ uniqueId: '1', artifactName: 'heat1', timeout: 0, artifactDisplayName: 'heat1', artifactGroupType: ArtifactGroupType.DEPLOYMENT
+ });
+
+ const heat1env = Mock.of<ArtifactModel>({
+ uniqueId: '2', artifactName: 'heat1env', timeout: 0, generatedFromId: '1', artifactDisplayName: 'heat1env', artifactGroupType: ArtifactGroupType.DEPLOYMENT
+ });
+
+ const storeMock = Mock.of<Store>( { dispatch : jest.fn() });
+
+ const artifacts = [
+ heat1,
+ heat1env
+ ];
+
+ /**
+ * NGXS Store state before we run the update
+ */
+ const ngxsState = {
+ deploymentArtifacts : artifacts
+ };
+
+ /**
+ * The ENV artifact that we wish to update
+ */
+ const updatedArtifact = Mock.of<ArtifactModel>({
+ uniqueId: '2', artifactName: 'heat1env', timeout: 33, generatedFromId: '1', artifactDisplayName: 'heat1env-UPDATE', artifactGroupType: ArtifactGroupType.DEPLOYMENT
+ });
+
+ const componentInstanceServiceMock: ComponentInstanceServiceNg2 = Mock.of<ComponentInstanceServiceNg2>({
+ updateInstanceArtifact: jest.fn().mockImplementation(() => Observable.of(updatedArtifact)),
+ getComponentInstanceArtifactsByGroupType: jest.fn().mockImplementation(() => Observable.of([heat1, updatedArtifact]))
+ });
+
+ const actionMock: UpdateInstanceArtifactAction = Mock.of<UpdateInstanceArtifactAction>({
+ payload: {
+ componentType: '',
+ componentId: '',
+ instanceId: '',
+ artifact: updatedArtifact
+ }
+ });
+
+ it('Test that HEAT timeout is updated', () => {
+ const state: InstanceArtifactsState = new InstanceArtifactsState(storeMock, componentInstanceServiceMock);
+ const context = { getState: jest.fn().mockImplementation(() => ngxsState), patchState: jest.fn(), setState: jest.fn(), dispatch: jest.fn() };
+ state.updateArtifact(context, actionMock ).subscribe( (v) => console.log('OK'));
+ expect(storeMock.dispatch).toBeCalled();
+ });
+
+});
diff --git a/catalog-ui/src/app/ng2/store/states/artifacts.state.ts b/catalog-ui/src/app/ng2/store/states/artifacts.state.ts
new file mode 100644
index 0000000000..64efbe96a9
--- /dev/null
+++ b/catalog-ui/src/app/ng2/store/states/artifacts.state.ts
@@ -0,0 +1,140 @@
+/**
+ * Created by ob0695 on 7/17/2018.
+ */
+import { Action, Selector, State, StateContext } from '@ngxs/store';
+import * as _ from 'lodash';
+import { tap } from 'rxjs/operators';
+import { ArtifactModel } from '../../../models/artifacts';
+import { ArtifactGroupType } from '../../../utils/constants';
+import { TopologyTemplateService } from '../../services/component-services/topology-template.service';
+import { ComponentGenericResponse } from '../../services/responses/component-generic-response';
+import { ServiceGenericResponse } from '../../services/responses/service-generic-response';
+import { CreateOrUpdateArtifactAction, DeleteArtifactAction, GetArtifactsByTypeAction } from '../actions/artifacts.action';
+
+export interface ArtifactsStateModel {
+ artifacts: ArtifactModel[];
+ deploymentArtifacts: ArtifactModel[];
+ toscaArtifacts: ArtifactModel[];
+ serviceApiArtifacts: ArtifactModel[];
+}
+
+@State<ArtifactsStateModel>({
+ name: 'artifacts',
+ defaults: {
+ artifacts: [],
+ deploymentArtifacts: [],
+ toscaArtifacts: [],
+ serviceApiArtifacts: []
+ }
+})
+
+export class ArtifactsState {
+
+ constructor(protected topologyTemplateService: TopologyTemplateService) {
+ }
+
+ @Selector()
+ static getEnvArtifact(state: ArtifactsStateModel, heatEnvArtifact: ArtifactModel) {
+ return (heatEnvArtifact: ArtifactModel) => {
+ _.find(state.deploymentArtifacts, (artifact)=> {
+ return artifact.generatedFromId === heatEnvArtifact.uniqueId
+ })
+ };
+ }
+
+ @Selector()
+ static getArtifactsByType(state: ArtifactsStateModel, type: string) {
+ return (type: string) => {
+ switch (type) {
+ case ArtifactGroupType.TOSCA:
+ return state.toscaArtifacts;
+ case ArtifactGroupType.INFORMATION:
+ return state.artifacts;
+ case ArtifactGroupType.DEPLOYMENT:
+ return state.deploymentArtifacts;
+ case ArtifactGroupType.SERVICE_API:
+ return state.serviceApiArtifacts;
+ }
+ };
+ }
+
+ private updateArtifactState = (artifactsState: ArtifactModel[], artifactToUpdate: ArtifactModel, updatedArtifact: ArtifactModel) => {
+ if (!artifactToUpdate.uniqueId) { // Create Artifact
+ return [...artifactsState, updatedArtifact]
+ } else { // Update Artifact
+ let artifactToUpdateIndex = _.findIndex(artifactsState, (artifact) => {
+ return artifact.uniqueId === artifactToUpdate.uniqueId
+ })
+ let artifacts = Array.from(artifactsState);
+ artifacts[artifactToUpdateIndex] = updatedArtifact;
+ return [...artifacts];
+ }
+ }
+
+ @Action(GetArtifactsByTypeAction)
+ getArtifactsByType({getState, patchState}: StateContext<ArtifactsStateModel>, action: GetArtifactsByTypeAction) {
+ const state = getState();
+ return this.topologyTemplateService.getArtifactsByType(action.payload.componentType, action.payload.componentId, action.payload.artifactType)
+ .pipe(tap((resp: ComponentGenericResponse) => {
+ switch (action.payload.artifactType) {
+ case ArtifactGroupType.INFORMATION:
+ patchState({
+ artifacts: <ArtifactModel[]>_.values(resp.artifacts)
+ });
+
+ case ArtifactGroupType.DEPLOYMENT:
+ patchState({
+ deploymentArtifacts: <ArtifactModel[]>_.values(resp.deploymentArtifacts)
+ });
+
+ case ArtifactGroupType.TOSCA:
+ patchState({
+ toscaArtifacts: <ArtifactModel[]>_.values(resp.toscaArtifacts)
+ });
+
+ case ArtifactGroupType.SERVICE_API:
+ patchState({
+ serviceApiArtifacts: <ArtifactModel[]>_.values((<ServiceGenericResponse>resp).serviceApiArtifacts)
+ });
+ }
+ }));
+ }
+
+ @Action(CreateOrUpdateArtifactAction)
+ createOrUpdateArtifact({getState, patchState}: StateContext<ArtifactsStateModel>, action: CreateOrUpdateArtifactAction) {
+ const state = getState();
+ return this.topologyTemplateService.addOrUpdateArtifact(action.payload.componentType, action.payload.componentId, action.payload.artifact)
+ .pipe(tap((resp: ArtifactModel) => {
+
+ switch (resp.artifactGroupType) {
+ case ArtifactGroupType.DEPLOYMENT:
+ patchState({
+ deploymentArtifacts: this.updateArtifactState(state.deploymentArtifacts, action.payload.artifact, resp)
+ });
+
+ case ArtifactGroupType.INFORMATION:
+ patchState({
+ artifacts: this.updateArtifactState(state.artifacts, action.payload.artifact, resp)
+ });
+ }
+ }));
+ }
+
+ @Action(DeleteArtifactAction)
+ deleteArtifact({getState, patchState}: StateContext<ArtifactsStateModel>, action: DeleteArtifactAction) {
+ const state = getState();
+ return this.topologyTemplateService.deleteArtifact(action.payload.componentId, action.payload.componentType, action.payload.artifact.uniqueId, action.payload.artifact.artifactLabel)
+ .pipe(tap((resp: ArtifactModel) => {
+ switch (resp.artifactGroupType) {
+ case ArtifactGroupType.DEPLOYMENT:
+ patchState({
+ deploymentArtifacts: state.deploymentArtifacts.filter(({uniqueId}) => uniqueId !== action.payload.artifact.uniqueId)
+ });
+ case ArtifactGroupType.INFORMATION:
+ patchState({
+ artifacts: state.artifacts.filter(({uniqueId}) => uniqueId !== action.payload.artifact.uniqueId)
+ });
+ }
+ }));
+ }
+} \ No newline at end of file
diff --git a/catalog-ui/src/app/ng2/store/states/instance-artifacts.state.ts b/catalog-ui/src/app/ng2/store/states/instance-artifacts.state.ts
new file mode 100644
index 0000000000..12ba1ae7ba
--- /dev/null
+++ b/catalog-ui/src/app/ng2/store/states/instance-artifacts.state.ts
@@ -0,0 +1,145 @@
+/**
+ * Created by ob0695 on 7/17/2018.
+ */
+import { Action, Selector, State, StateContext, Store } from '@ngxs/store';
+import * as _ from 'lodash';
+import { tap } from 'rxjs/operators';
+import { ArtifactModel } from '../../../models/artifacts';
+import { ArtifactGroupType } from '../../../utils/constants';
+import { ComponentInstanceServiceNg2 } from '../../services/component-instance-services/component-instance.service';
+import { ComponentGenericResponse } from '../../services/responses/component-generic-response';
+import {
+ CreateInstanceArtifactAction,
+ DeleteInstanceArtifactAction,
+ GetInstanceArtifactsByTypeAction,
+ UpdateInstanceArtifactAction
+} from '../actions/instance-artifacts.actions';
+import { ArtifactsStateModel } from './artifacts.state';
+
+export interface InstanceArtifactsStateModel {
+ artifacts: ArtifactModel[];
+ deploymentArtifacts: ArtifactModel[];
+}
+
+@State<InstanceArtifactsStateModel>({
+ name: 'instance_artifacts',
+ defaults: {
+ artifacts: [],
+ deploymentArtifacts: []
+ }
+})
+export class InstanceArtifactsState {
+
+ constructor(private store: Store, protected componentInstanceService: ComponentInstanceServiceNg2) {
+ }
+
+ @Selector()
+ static getArtifactsByType(state: InstanceArtifactsStateModel) {
+ return (type: string) => {
+ switch (type) {
+ case ArtifactGroupType.INFORMATION:
+ return state.artifacts;
+ case ArtifactGroupType.DEPLOYMENT:
+ return state.deploymentArtifacts;
+ }
+ };
+ }
+
+ @Action(GetInstanceArtifactsByTypeAction)
+ getInstanceArtifactsByType({getState, patchState}: StateContext<InstanceArtifactsStateModel>, action: GetInstanceArtifactsByTypeAction) {
+ const state = getState();
+ return this.componentInstanceService.getComponentInstanceArtifactsByGroupType(action.payload.componentType, action.payload.componentId, action.payload.instanceId, action.payload.artifactType)
+ .pipe(tap((resp: ComponentGenericResponse) => {
+ switch (action.payload.artifactType) {
+ case ArtifactGroupType.INFORMATION:
+ patchState({
+ artifacts: _.values(resp) as ArtifactModel[]
+ });
+ break;
+ case ArtifactGroupType.DEPLOYMENT:
+ patchState({
+ deploymentArtifacts: _.values(resp) as ArtifactModel[]
+ });
+ break;
+ }
+ }));
+ }
+
+ @Action(CreateInstanceArtifactAction)
+ createArtifact({getState, patchState}: StateContext<ArtifactsStateModel>, action: CreateInstanceArtifactAction) {
+ const state = getState();
+ return this.componentInstanceService.addInstanceArtifact(action.payload.componentType, action.payload.componentId, action.payload.instanceId, action.payload.artifact)
+ .pipe(tap((resp: ArtifactModel) => {
+ switch (resp.artifactGroupType) {
+ case ArtifactGroupType.DEPLOYMENT:
+ patchState({
+ deploymentArtifacts: [...state.deploymentArtifacts, resp]
+ });
+ break;
+ case ArtifactGroupType.INFORMATION:
+ patchState({
+ artifacts: [...state.artifacts, resp]
+ });
+ break;
+ }
+ }));
+ }
+
+ @Action(UpdateInstanceArtifactAction)
+ updateArtifact({getState, patchState}: StateContext<ArtifactsStateModel>, action: UpdateInstanceArtifactAction) {
+ const state = getState();
+ return this.componentInstanceService.updateInstanceArtifact(action.payload.componentType, action.payload.componentId, action.payload.instanceId, action.payload.artifact)
+ .pipe(tap((resp: ArtifactModel) => {
+ switch (resp.artifactGroupType) {
+ case ArtifactGroupType.DEPLOYMENT:
+ // We cannot simply update the updated artifact state because updating a deployment ENV file may cause an update to his parent HEAT
+ // file.
+ // Just dispatch an action to refresh the deployment artifacts list
+ this.store.dispatch(new GetInstanceArtifactsByTypeAction(({
+ componentType: action.payload.componentType,
+ componentId: action.payload.componentId,
+ instanceId: action.payload.instanceId,
+ artifactType: ArtifactGroupType.DEPLOYMENT
+ })));
+ break;
+ case ArtifactGroupType.INFORMATION:
+ patchState({
+ artifacts: this.updateInstanceArtifactState(state.artifacts, action.payload.artifact, resp)
+ });
+ break;
+ }
+ }));
+ }
+
+ @Action(DeleteInstanceArtifactAction)
+ deleteInstanceArtifact({getState, patchState}: StateContext<ArtifactsStateModel>, action: DeleteInstanceArtifactAction) {
+ const state = getState();
+ return this.componentInstanceService.
+ deleteInstanceArtifact(action.payload.componentId, action.payload.componentType, action.payload.instanceId, action.payload.artifact.uniqueId, action.payload.artifact.artifactLabel)
+ .pipe(tap((resp: ArtifactModel) => {
+ switch (resp.artifactGroupType) {
+ case ArtifactGroupType.DEPLOYMENT:
+ patchState({
+ deploymentArtifacts: state.deploymentArtifacts.filter(({uniqueId}) => uniqueId !== action.payload.artifact.uniqueId)
+ });
+ break;
+ case ArtifactGroupType.INFORMATION:
+ patchState({
+ artifacts: state.artifacts.filter(({uniqueId}) => uniqueId !== action.payload.artifact.uniqueId)
+ });
+ break;
+ }
+ }));
+ }
+
+ private updateInstanceArtifactState = (artifactsState: ArtifactModel[], artifactToUpdate: ArtifactModel, updatedArtifact: ArtifactModel) => {
+ const artifactToUpdateIndex = _.findIndex(artifactsState, (artifact) => {
+ return artifact.uniqueId === artifactToUpdate.uniqueId;
+ });
+ const artifacts = Array.from(artifactsState);
+ artifacts[artifactToUpdateIndex] = updatedArtifact;
+ const ret = [...artifacts];
+ return ret;
+ }
+
+}
diff --git a/catalog-ui/src/app/ng2/store/states/workspace.state.ts b/catalog-ui/src/app/ng2/store/states/workspace.state.ts
new file mode 100644
index 0000000000..eb8200f6e0
--- /dev/null
+++ b/catalog-ui/src/app/ng2/store/states/workspace.state.ts
@@ -0,0 +1,48 @@
+/**
+ * Created by ob0695 on 7/17/2018.
+ */
+import {State, Action, StateContext} from '@ngxs/store';
+import {UpdateIsDesigner, UpdateIsViewOnly} from "../actions/workspace.action";
+import {Selector} from "@ngxs/store";
+
+export interface WorkspaceStateModel {
+ isViewOnly: boolean;
+ isDesigner: boolean;
+}
+
+@State<WorkspaceStateModel>({
+ name: 'workspace',
+ defaults: {
+ isViewOnly: false,
+ isDesigner: true
+ }
+})
+
+export class WorkspaceState {
+
+ constructor(){}
+
+ @Selector() static isViewOnly(state: WorkspaceStateModel):boolean {
+ return state.isViewOnly;
+ }
+ @Selector() static isDesigner(state: WorkspaceStateModel): boolean {
+ return state.isDesigner;
+ }
+
+ @Action(UpdateIsViewOnly)
+ updateIsViewOnly({getState, setState}: StateContext<WorkspaceStateModel>, action:UpdateIsViewOnly) {
+ const state = getState();
+ setState({
+ ...state,
+ isViewOnly: action.isViewOnly
+ });
+ }
+
+ @Action(UpdateIsDesigner)
+ updateIsDesigner({getState, patchState}: StateContext<WorkspaceStateModel>, action:UpdateIsDesigner) {
+ const state = getState();
+ patchState({
+ isDesigner: action.isDesigner
+ });
+ }
+} \ No newline at end of file