operation artifact optional and fixes

Change-Id: Ibce96d60248b26716ed518747444836b437f209f
Issue-ID: SDC-2249
Signed-off-by: Arielk <Ariel.Kenan@amdocs.com>
diff --git a/catalog-ui/src/app/models/operation.ts b/catalog-ui/src/app/models/operation.ts
index 7b0039b..bf03772 100644
--- a/catalog-ui/src/app/models/operation.ts
+++ b/catalog-ui/src/app/models/operation.ts
@@ -39,7 +39,10 @@
     workflowId: string;
     workflowVersionId: string;
 
-    implementation?: { artifactUUID: string; };
+    implementation?: {
+        artifactName: string;
+        artifactUUID: string;
+    };
 
     constructor(operation?: any) {
         if (operation) {
@@ -53,7 +56,7 @@
             this.workflowAssociationType = operation.workflowAssociationType;
             this.workflowId = operation.workflowId;
             this.workflowVersionId = operation.workflowVersionId;
-            this.implementation = operation.implementation;
+            this.implementation = operation.implementation || {};
         }
     }
 
@@ -76,7 +79,7 @@
 export class OperationModel extends BEOperationModel {
     interfaceType: string;
     interfaceId: string;
-    artifactFile: any;
+    artifactFileName: string;
     artifactData: any;
 
     constructor(operation?: any) {
@@ -84,12 +87,13 @@
         if (operation) {
             this.interfaceId = operation.interfaceId;
             this.interfaceType = operation.interfaceType;
+            this.artifactFileName = operation.artifactFileName;
+            this.artifactData = operation.artifactData;
         }
     }
 
     public displayType(): string {
-        const lastDot = this.interfaceType ? this.interfaceType.lastIndexOf('.') : -1;
-        return lastDot === -1 ? this.interfaceType : this.interfaceType.substr(lastDot + 1);
+        return displayType(this.interfaceType);
     }
 }
 
@@ -107,7 +111,8 @@
     }
 
     public displayType(): string {
-        const lastDot = this.type ? this.type.lastIndexOf('.') : -1;
-        return lastDot === -1 ? this.type : this.type.substr(lastDot + 1);
+        return displayType(this.type);
     }
 }
+
+const displayType = (type:string) => type && type.substr(type.lastIndexOf('.') + 1);
diff --git a/catalog-ui/src/app/ng2/pages/interface-operation/interface-operation.page.component.ts b/catalog-ui/src/app/ng2/pages/interface-operation/interface-operation.page.component.ts
index 7c0f232..9db24b6 100644
--- a/catalog-ui/src/app/ng2/pages/interface-operation/interface-operation.page.component.ts
+++ b/catalog-ui/src/app/ng2/pages/interface-operation/interface-operation.page.component.ts
@@ -315,10 +315,12 @@
     private createOperation = (operation: OperationModel): void => {
         this.ComponentServiceNg2.createInterfaceOperation(this.component, operation).subscribe((response: OperationModel) => {
             this.openOperation = null;
+
             let curInterf = _.find(
                 this.interfaces,
                 interf => interf.type === operation.interfaceType
             );
+
             if (!curInterf) {
                 curInterf = new UIInterfaceModel({
                     type: response.interfaceType,
@@ -327,11 +329,13 @@
                 });
                 this.interfaces.push(curInterf);
             }
-            curInterf.operations.push(new UIOperationModel(response));
+
+            const newOpModel = new UIOperationModel(response);
+            curInterf.operations.push(newOpModel);
             this.sortInterfaces();
 
-            if (operation.workflowAssociationType === WORKFLOW_ASSOCIATION_OPTIONS.EXTERNAL) {
-                this.ComponentServiceNg2.uploadInterfaceOperationArtifact(this.component, response, operation).subscribe();
+            if (operation.workflowAssociationType === WORKFLOW_ASSOCIATION_OPTIONS.EXTERNAL && operation.artifactData) {
+                this.ComponentServiceNg2.uploadInterfaceOperationArtifact(this.component, newOpModel, operation).subscribe();
             } else if (response.workflowId && operation.workflowAssociationType === WORKFLOW_ASSOCIATION_OPTIONS.EXISTING) {
                 this.WorkflowServiceNg2.associateWorkflowArtifact(this.component, response).subscribe();
             } else if (operation.workflowAssociationType === WORKFLOW_ASSOCIATION_OPTIONS.NEW) {
@@ -341,7 +345,7 @@
     }
 
     private updateOperation = (operation: OperationModel): void => {
-        this.ComponentServiceNg2.updateInterfaceOperation(this.component, operation).subscribe(newOperation => {
+        this.ComponentServiceNg2.updateInterfaceOperation(this.component, operation).subscribe((newOperation: OperationModel) => {
             this.openOperation = null;
 
             let oldOpIndex, oldInterf;
@@ -356,11 +360,12 @@
             oldInterf.operations.splice(oldOpIndex, 1);
 
             const newInterf = _.find(this.interfaces, interf => interf.type === operation.interfaceType);
-            newInterf.operations.push(new UIOperationModel(newOperation));
+            const newOpModel = new UIOperationModel(newOperation);
+            newInterf.operations.push(newOpModel);
             this.sortInterfaces();
 
-            if (operation.workflowAssociationType === WORKFLOW_ASSOCIATION_OPTIONS.EXTERNAL) {
-                this.ComponentServiceNg2.uploadInterfaceOperationArtifact(this.component, newOperation, operation).subscribe();
+            if (operation.workflowAssociationType === WORKFLOW_ASSOCIATION_OPTIONS.EXTERNAL && operation.artifactData) {
+                this.ComponentServiceNg2.uploadInterfaceOperationArtifact(this.component, newOpModel, operation).subscribe();
             } else if (newOperation.workflowId && operation.workflowAssociationType === WORKFLOW_ASSOCIATION_OPTIONS.EXISTING) {
                 this.WorkflowServiceNg2.associateWorkflowArtifact(this.component, newOperation).subscribe();
             }
diff --git a/catalog-ui/src/app/ng2/pages/interface-operation/operation-creator/operation-creator.component.html b/catalog-ui/src/app/ng2/pages/interface-operation/operation-creator/operation-creator.component.html
index 5faddd8..8f70f7f 100644
--- a/catalog-ui/src/app/ng2/pages/interface-operation/operation-creator/operation-creator.component.html
+++ b/catalog-ui/src/app/ng2/pages/interface-operation/operation-creator/operation-creator.component.html
@@ -86,15 +86,15 @@
             <div
                 *ngIf="isUsingExternalWF()"
                 class="form-item sdc-input">
-                <label class="sdc-input__label required">{{ 'OPERATION_ARTIFACT' | translate }}</label>
+                <label class="sdc-input__label">{{ 'OPERATION_ARTIFACT' | translate }}</label>
                 <div class="i-sdc-form-item i-sdc-form-file-upload">
                     <span
                         class="i-sdc-form-file-name"
                         data-tests-id="artifactFilename">
-                        {{ operation.artifactFile && operation.artifactFile.name }}
+                        {{ operation.artifactFileName }}
                     </span>
                     <div
-                        *ngIf="operation.artifactFile && operation.artifactFile.name"
+                        *ngIf="operation.artifactFileName"
                         class="i-sdc-form-file-upload-x-btn"
                         data-tests-id="clearArtifact"
                         (click)="onChangeArtifactFile({ target: {} })"></div>
@@ -107,6 +107,7 @@
                             maxsize="10240"
                             data-tests-id="artifactUpload"
                             (change)="onChangeArtifactFile($event)"
+                            (click)="$event.target.value = ''"
                         />
                         <div class="file-upload-browse-btn">Browse</div>
                     </label>
diff --git a/catalog-ui/src/app/ng2/pages/interface-operation/operation-creator/operation-creator.component.ts b/catalog-ui/src/app/ng2/pages/interface-operation/operation-creator/operation-creator.component.ts
index 7b36062..a574460 100644
--- a/catalog-ui/src/app/ng2/pages/interface-operation/operation-creator/operation-creator.component.ts
+++ b/catalog-ui/src/app/ng2/pages/interface-operation/operation-creator/operation-creator.component.ts
@@ -186,6 +186,8 @@
         if (inputOperation) {
             this.onSelectInterface(new DropDownOption(this.operation.interfaceType));
 
+            this.operation.artifactFileName = this.operation.artifactFileName || this.operation.implementation.artifactName;
+
             if (this.enableWorkflowAssociation && inputOperation.workflowVersionId && this.isUsingExistingWF(inputOperation)) {
                 this.assignInputParameters[this.operation.workflowId] = {[inputOperation.workflowVersionId]: []};
                 this.assignOutputParameters[this.operation.workflowId] = {[inputOperation.workflowVersionId]: []};
@@ -317,13 +319,13 @@
                 ).sort((a, b) => a.name.localeCompare(b.name)),
                 (version: any) => {
                     if (!this.assignInputParameters[this.operation.workflowId][version.id] && version.id !== selectedVersionId) {
-                        this.assignInputParameters[this.operation.workflowId][version.id] = _.map(version.inputs, (input: OperationParameter) => {
-                            return new OperationParameter({...input, type: input.type.toLowerCase(), required: Boolean(input.required)});
+                        this.assignInputParameters[this.operation.workflowId][version.id] = _.map(version.inputs, (input: any) => {
+                            return new OperationParameter({...input, type: input.type.toLowerCase(), required: Boolean(input.mandatory)});
                         })
                         .sort((a, b) => a.name.localeCompare(b.name));
 
-                        this.assignOutputParameters[this.operation.workflowId][version.id] = _.map(version.outputs, (output: OperationParameter) => {
-                            return new OperationParameter({...output, type: output.type.toLowerCase(), required: Boolean(output.required)});
+                        this.assignOutputParameters[this.operation.workflowId][version.id] = _.map(version.outputs, (output: any) => {
+                            return new OperationParameter({...output, type: output.type.toLowerCase(), required: Boolean(output.mandatory)});
                         })
                         .sort((a, b) => a.name.localeCompare(b.name));
                     }
@@ -383,9 +385,9 @@
 
     onChangeArtifactFile(e: any) {
         const file = e.target.files && e.target.files[0];
-        this.operation.artifactFile = file;
+        this.operation.artifactFileName = file && file.name;
 
-        if (!this.operation.artifactFile) {
+        if (!this.operation.artifactFileName) {
             this.operation.artifactData = null;
             this.validityChanged();
             return;
@@ -495,9 +497,7 @@
 
     checkFormValidForSubmit = (): boolean => {
         return this.operation.name &&
-            (this.isUsingExternalWF() ?
-                (this.operation.artifactFile && this.operation.artifactFile.name) :
-                (!this.isUsingExistingWF() || this.operation.workflowVersionId)) &&
+            (!this.isUsingExistingWF() || this.operation.workflowVersionId) &&
             this.isParamsValid();
     }
 
diff --git a/catalog-ui/src/app/ng2/services/component-services/component.service.ts b/catalog-ui/src/app/ng2/services/component-services/component.service.ts
index c313a3f..445e123 100644
--- a/catalog-ui/src/app/ng2/services/component-services/component.service.ts
+++ b/catalog-ui/src/app/ng2/services/component-services/component.service.ts
@@ -25,7 +25,7 @@
 import 'rxjs/add/operator/toPromise';
 import {Response, URLSearchParams, Headers} from '@angular/http';
 import { Component, ComponentInstance, InputBEModel, InstancePropertiesAPIMap, FilterPropertiesAssignmentData,
-    PropertyBEModel, OperationModel, BEOperationModel, Capability, Requirement, PolicyInstance} from "app/models";
+    PropertyBEModel, InterfaceModel, OperationModel, BEOperationModel, Capability, Requirement, PolicyInstance} from "app/models";
 import {COMPONENT_FIELDS, CommonUtils, SERVICE_FIELDS} from "app/utils";
 import {downgradeInjectable} from '@angular/upgrade/static';
 import {ComponentGenericResponse} from "../responses/component-generic-response";
@@ -156,12 +156,13 @@
         };
         return this.http.post(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/interfaceOperations', operationList)
             .map((res:Response) => {
-                const interf = _.find(res.json().interfaces, (interf: any) => interf.type === operation.interfaceType);
-                const newOperation = _.find(interf.operations, (op:OperationModel) => op.name === operation.name);
+                const interf:InterfaceModel = _.find(res.json().interfaces, interf => interf.type === operation.interfaceType);
+                const newOperation:OperationModel = _.find(interf.operations, op => op.name === operation.name);
                 return new OperationModel({
                     ...newOperation,
                     interfaceType: interf.type,
-                    interfaceId: interf.uniqueId
+                    interfaceId: interf.uniqueId,
+                    artifactFileName: operation.artifactFileName
                 });
             });
     }
@@ -179,12 +180,13 @@
         };
         return this.http.put(this.baseUrl + component.getTypeUrl() + component.uniqueId + '/interfaceOperations', operationList)
             .map((res:Response) => {
-                const interf = _.find(res.json().interfaces, (interf: any) => interf.type === operation.interfaceType);
-                const newOperation = _.find(interf.operations, (op:OperationModel) => op.name === operation.name);
+                const interf:InterfaceModel = _.find(res.json().interfaces, interf => interf.type === operation.interfaceType);
+                const newOperation:OperationModel = _.find(interf.operations, op => op.name === operation.name);
                 return new OperationModel({
                     ...newOperation,
                     interfaceType: interf.type,
-                    interfaceId: interf.uniqueId
+                    interfaceId: interf.uniqueId,
+                    artifactFileName: operation.artifactFileName
                 });
             });
     }
@@ -207,12 +209,12 @@
             });
     }
 
-    uploadInterfaceOperationArtifact(component:Component, response:OperationModel, UIOperation:OperationModel) {
+    uploadInterfaceOperationArtifact(component:Component, newOperation:OperationModel, oldOperation:OperationModel) {
         const payload = {
             artifactType: "WORKFLOW",
-            artifactName: UIOperation.artifactFile.name,
+            artifactName: oldOperation.artifactFileName,
             description: "Workflow Artifact Description",
-            payloadData: UIOperation.artifactData
+            payloadData: oldOperation.artifactData
         };
 
         const headers = new Headers();
@@ -221,10 +223,12 @@
         const md5Result = md5(payloadString).toLowerCase();
         headers.append('Content-MD5', btoa(md5Result));
 
-        return this.http.post(this.baseUrl + component.getTypeUrl() + component.uuid + '/interfaces/' + response.interfaceId + '/operations/' + response.uniqueId + '/artifacts/' + response.implementation.artifactUUID,
+        return this.http.post(this.baseUrl + component.getTypeUrl() + component.uuid + '/interfaces/' + newOperation.interfaceId + '/operations/' + newOperation.uniqueId + '/artifacts/' + newOperation.implementation.artifactUUID,
                 payload,
                 {headers}
             ).map((res: Response) => {
+                const fileName = res.json().artifactDisplayName || res.json().artifactName;
+                newOperation.artifactFileName = fileName;
                 return res.json();
             });
     }
diff --git a/catalog-ui/src/app/ng2/shared/translator/translate.pipe.ts b/catalog-ui/src/app/ng2/shared/translator/translate.pipe.ts
index 42e0198..4ec756b 100644
--- a/catalog-ui/src/app/ng2/shared/translator/translate.pipe.ts
+++ b/catalog-ui/src/app/ng2/shared/translator/translate.pipe.ts
@@ -54,7 +54,6 @@
         if (this.shouldUpdate(curParams)) {
             this.lastParams = curParams;
             this.translated = this.translateService.translate(phrase, args, language);
-            console.log('*updated:', this.translated);
         }
 
         return this.translated;