http://git-wip-us.apache.org/repos/asf/falcon/blob/76dc2e18/falcon-ui/app/html/process/processFormInputsAndOutputsStepTpl.html ---------------------------------------------------------------------- diff --git a/falcon-ui/app/html/process/processFormInputsAndOutputsStepTpl.html b/falcon-ui/app/html/process/processFormInputsAndOutputsStepTpl.html index 528ce14..09b4aa2 100644 --- a/falcon-ui/app/html/process/processFormInputsAndOutputsStepTpl.html +++ b/falcon-ui/app/html/process/processFormInputsAndOutputsStepTpl.html @@ -17,31 +17,33 @@ * limitations under the License. */ --> -<form name="processForm" novalidate id="processFormInOutStep"> - <div class="col-sm-offset-1 col-sm-22"> - <h4 ng-if="process.inputs.length === 0">Inputs</h4> +<form name="processForm" novalidate> + <div class="col-sm-24"> + <div ng-if="process.inputs.length === 0"> + <label class="mt15">INPUTS</label> + </div> - <div ng-repeat="input in process.inputs" class="row"> - <h4 class="col-xs-24">Input</h4> + <div ng-repeat="input in process.inputs"> + <div><label class="mt15">INPUT</label></div> <div class="col-xs-24 detailsBox processCluster"> <div class="row"> <div class="col-xs-24"> - <label class="light">Name</label> + <label class="light">Name<mandatory-field></mandatory-field></label> <input type="text" class="form-control" ng-class="{firstInput: $index === 0}" validation-message="{{validations.messages.name}}" ng-model="input.name" ng-required="true" - ng-maxlength="100" - ng-pattern="validations.patterns.name"/> + ng-maxlength="39" + ng-pattern="validations.patterns.inputName"/> </div> </div> <div class="row"> <div class="col-xs-24"> - <label class="light">Feed</label> + <label class="light">Feed<mandatory-field></mandatory-field></label> <select ng-model="input.feed" ng-required="true" class="col-sm-24 form-control padding0" validation-message="{{validations.messages.feed}}"> @@ -51,22 +53,20 @@ </div> </div> - <div class="clearfix"></div> - <h5>Instance</h5> + <div><label class="mt15">INSTANCE</label></div> <div class="row"> <div class="col-xs-12"> - <label class="light">Start</label> + <label class="light">Start<mandatory-field></mandatory-field></label> <input type="text" class="form-control" validation-message="{{validations.messages.value}}" ng-model="input.start" ng-required="true" - ng-maxlength="100" - on-blur="validateStartEndDate"/> + ng-maxlength="39"/> </div> <div class="col-xs-12"> - <label class="light">End</label> + <label class="light">End<mandatory-field></mandatory-field></label> <input type="text" class="form-control {{invalidEndDate}}" validation-message="{{validations.messages.value}}" ng-model="input.end" @@ -76,11 +76,11 @@ <label ng-show="invalidEndDate" class="custom-danger nameValidationMessage">End should be equal or greater than Start</label> </div> - <div class="col-xs-24 mt10"> + </div> + <div class="col-xs-24 mt10"> <button type="button" class="btn btn-default pull-right btn-xs" ng-click="removeInput($index)"> <span class="entypo minus"></span> delete </button> - </div> </div> </div> </div> @@ -89,28 +89,29 @@ <span class="entypo plus"></span> add input </button> - <h4 ng-if="process.outputs.length === 0">Outputs</h4> - - <div ng-repeat="output in process.outputs" class="row"> - <h4 class="col-xs-24">Output</h4> + <div ng-if="process.outputs.length === 0"> + <label class="mt15">OUTPUTS</label> + </div> + <div ng-repeat="output in process.outputs"> + <div><label class="mt15">OUTPUT</label></div> <div class="col-xs-24 detailsBox processCluster"> <div class="row"> <div class="col-xs-24"> - <label class="light">Name</label> + <label class="light">Name<mandatory-field></mandatory-field></label> <input type="text" ng-class="{firstOutput: $index === 0}" class="form-control" validation-message="{{validations.messages.name}}" ng-model="output.name" ng-required="true" - ng-maxlength="100" + ng-maxlength="39" ng-pattern="validations.patterns.id"/> </div> </div> <div class="row"> <div class="col-xs-24"> - <label class="light">Feed</label> + <label class="light">Feed<mandatory-field></mandatory-field></label> <select ng-model="output.feed" ng-required="true" class="col-sm-24 form-control padding0" validation-message="{{validations.messages.feed}}" > <option value="" disabled selected style='display:none;'>-Select feed-</option> @@ -118,16 +119,16 @@ </select> </div> </div> - <div class="clearfix"></div> - <h5>Instance</h5> + + <div><label class="mt15">INSTANCE</label></div> <div class="row"> <div class="col-xs-24"> - <label class="light">Instance</label> + <label class="light">Instance<mandatory-field></mandatory-field></label> <input type="text" class="form-control" validation-message="{{validations.messages.value}}" ng-model="output.outputInstance" ng-required="true" - ng-maxlength="100"/> + ng-maxlength="39"/> </div> </div> <div class="row mt10"> @@ -143,21 +144,21 @@ <span class="entypo plus"></span> add output </button> </div> - <div class="row"> - <div class="col-xs-24 mt20"> - <button class="btn prevBtn" type="button" - ng-click="goBack('forms.process.clusters')" - ng-disabled="buttonSpinners.backShow"> - Previous <img src="css/img/ajax-loader.gif" ng-if="buttonSpinners.backShow" /> - </button> - <button class="btn nextBtn pull-right" + <div class="col-xs-24 pb15px mt35"> + <button class="btn prevBtn" type="button" + ng-click="goBack()" + ng-disabled="buttonSpinners.backShow"> + PREVIOUS <img src="css/img/ajax-loader.gif" ng-if="buttonSpinners.backShow" /> + </button> + <div class="pull-right"> + <a class="btn cnclBtn" ui-sref="main"> + CANCEL + </a> + <button class="btn nextBtn" ng-disabled="invalidEndDate || buttonSpinners.show" - ng-click="goNext(processForm.$invalid, 'forms.process.summary')" > - Next <img src="css/img/ajax-loader.gif" ng-if="buttonSpinners.show" /> - </button> - <a class="pull-right" ui-sref="main"> - Cancel - </a> + ng-click="goNext(processForm.$invalid)" scroll-to-error> + NEXT <img src="css/img/ajax-loader.gif" ng-if="buttonSpinners.show" /> + </button> </div> </div> -</form> \ No newline at end of file +</form>
http://git-wip-us.apache.org/repos/asf/falcon/blob/76dc2e18/falcon-ui/app/html/process/processFormPropertiesStepTpl.html ---------------------------------------------------------------------- diff --git a/falcon-ui/app/html/process/processFormPropertiesStepTpl.html b/falcon-ui/app/html/process/processFormPropertiesStepTpl.html index 657a1cb..1af0bdb 100644 --- a/falcon-ui/app/html/process/processFormPropertiesStepTpl.html +++ b/falcon-ui/app/html/process/processFormPropertiesStepTpl.html @@ -17,19 +17,19 @@ * limitations under the License. */ --> -<form name="processForm" class="mt10" novalidate id="processFormPropsStep"> +<form name="processForm" novalidate> - <h5 class="col-xs-24">Timing</h5> + <div class="col-xs-24"><label class="mt15">TIMING</label></div> <div class="col-xs-24 mb10"> - <label class="light">Timezone</label> - <time-zone-select ng-model="process.timezone" id="timeZoneSelect"></time-zone-select> + <label class="light" tooltip="process.properties.timezone">Timezone<mandatory-field></mandatory-field></label> + <time-zone-select ng-model="process.timezone" id="timeZoneSelect" required="true"> + </time-zone-select> </div> - - <div class="col-xs-9"> + <div class="col-xs-24 plr0px"> + <div class="col-xs-9"> <div class="inlineInputsGroup"> - <div>Frequency</div> - <span>Every</span> + <div><label class="light">Frequency Every<mandatory-field></mandatory-field></label></div> <input type="text" class="form-control" validation-message="{{validations.messages.number}}" ng-model="process.frequency.quantity" ng-keydown="validations.acceptOnlyNumber($event)" id="frequencyQuantity" @@ -45,39 +45,48 @@ <option value="months">months</option> </select> </div> - </div> - <div class="col-xs-7"> + </div> + <div class="col-xs-7"> <div class="inlineInputsGroup"> - <div>Maximum Parallel Instances</div> + <div><label class="light">Maximum Parallel Instances<mandatory-field></mandatory-field></label></div> <select ng-model="process.parallel" ng-required="true"> <option ng-repeat="value in [1,2,3,4,5,6,7,8,9,10,11,12]">{{value}}</option> </select> </div> - </div> - <div class="col-xs-8"> + </div> + <div class="col-xs-8"> <div class="inlineInputsGroup"> - <div>Order</div> + <div> + <label class="light" tooltip="process.properties.order"> + Instance Usage<mandatory-field></mandatory-field> + </label> + </div> <select ng-model="process.order" ng-required="true" validation-message="{{validations.messages.option}}"> <option value="" disabled selected style='display:none;'>-Select order-</option> <option ng-repeat="value in ['FIFO', 'LIFO', 'LAST_ONLY']">{{value}}</option> </select> </div> + </div> </div> - <div class="clearfix mb10"></div> - <h4 class="col-xs-24">Retry</h4> - - <div class="col-xs-9 inlineInputsGroup"> - <div class="mt10 mb10">Policy</div> + <div class="col-xs-24"><label class="mt15">RETRY</label></div> + <div class="col-xs-24 plr0px"> + <div class="col-xs-9 inlineInputsGroup"> + <div> + <label class="light" tooltip="process.properties.retryPolicy" tooltip-position="up"> + Retry Policy<mandatory-field></mandatory-field> + </label> + </div> <select ng-model="process.retry.policy" ng-required="true" validation-message="{{validations.messages.option}}"> <option value="" disabled selected style='display:none;'>-Select policy-</option> - <option ng-repeat="value in ['periodic', 'exp-backoff', 'final']">{{value}}</option> + <option value="periodic">Periodic</option> + <option value="exp-backoff">Exponential Backup</option> + <option value="final">None</option> </select> </div> - </div> - <div class="col-xs-7 inlineInputsGroup"> - <div class="mt10">Attempts</div> + <div class="col-xs-7 inlineInputsGroup"> + <div><label class="light">Attempts<mandatory-field></mandatory-field></label></div> <input type="text" class="form-control" validation-message="{{validations.messages.number}}" ng-model="process.retry.attempts" ng-keydown="validations.acceptOnlyNumber($event)" @@ -85,11 +94,9 @@ ng-required="true" ng-pattern="validations.patterns.twoDigits"/> </div> - </div> - <div class="col-xs-8"> + <div class="col-xs-8"> <div class="inlineInputsGroup"> - <div class="mt10">Delay</div> - <span>Up to</span> + <div><label class="light">Delay Up to<mandatory-field></mandatory-field></label></div> <input type="text" class="form-control" ng-model="process.retry.delay.quantity" validation-message="{{validations.messages.number}}" id="delayQuantity" ng-keydown="validations.acceptOnlyNumber($event)" @@ -104,23 +111,25 @@ <option value="months">months</option> </select> </div> + </div> </div> - - <div class="col-xs-24 mt20"> + <div class="col-xs-24 mt35 pb15px pl0px"> <button class="btn prevBtn" type="button" - ng-click="goBack('forms.process.general')" + ng-click="goBack()" ng-disabled="buttonSpinners.backShow"> - Previous <img src="css/img/ajax-loader.gif" ng-if="buttonSpinners.backShow" /> + PREVIOUS <img src="css/img/ajax-loader.gif" ng-if="buttonSpinners.backShow" /> </button> - <button class="btn nextBtn pull-right" + <div class="pull-right"> + <a class="btn cnclBtn" ui-sref="main"> + CANCEL + </a> + <button class="btn nextBtn" ng-disabled="buttonSpinners.show" - ng-click="goNext(processForm.$invalid, 'forms.process.clusters')" > - Next <img src="css/img/ajax-loader.gif" ng-if="buttonSpinners.show" /> - </button> - <a class="pull-right" ui-sref="main"> - Cancel - </a> + ng-click="goNext(processForm.$invalid)" scroll-to-error> + NEXT <img src="css/img/ajax-loader.gif" ng-if="buttonSpinners.show" /> + </button> + </div> </div> -</form> \ No newline at end of file +</form> http://git-wip-us.apache.org/repos/asf/falcon/blob/76dc2e18/falcon-ui/app/html/process/processFormSummaryStepTpl.html ---------------------------------------------------------------------- diff --git a/falcon-ui/app/html/process/processFormSummaryStepTpl.html b/falcon-ui/app/html/process/processFormSummaryStepTpl.html index b60dd4e..086e8fc 100644 --- a/falcon-ui/app/html/process/processFormSummaryStepTpl.html +++ b/falcon-ui/app/html/process/processFormSummaryStepTpl.html @@ -19,155 +19,192 @@ --> <form name="processForm" class="mt10" novalidate id="processFormSummaryStep"> - <div class="row"> - <h4 class="col-sm-24">Process</h4> + <div class="row" id="processSummaryStep"> + <h4 class="col-sm-24">General</h4> - <div class="clearfix hidden-md"> </div> - - <label class="col-sm-24">Name</label> - <label class="col-sm-24 light">{{process.name}}</label> - - <div class="clearfix hidden-md"> </div> + <div class="col-sm-24"> + <label>Process Name</label>: <span data-qe-id="processName">{{process.name}}</span> + </div> - <label class="col-sm-24">Tags</label> <div class="col-sm-24"> - <div ng-repeat="tag in process.tags | filter:{key: '!!'}"> - {{tag.key}} = {{tag.value}} + <label>Tags</label>: + <div ng-repeat="tag in process.tags | filter:{key: '!!'} track by $index"> + <span data-qe-id="processTags">{{tag.key}} = {{tag.value}}</span> </div> - <div ng-show="!hasTags()">No tags selected</div> + <div ng-show="!hasTags()"><span data-qe-id="processTags">No tags selected</span></div> </div> - <div class="clearfix hidden-md"> </div> + <h4 class="col-sm-24"> + Access Control List + </h4> + <div class="col-sm-24"> + <label>Owner</label>: <span data-qe-id="processACLOwner">{{optional(process.ACL.owner)}}</span> + <label>Group</label>: <span data-qe-id="processACLGroup">{{optional(process.ACL.group)}}</span> + <label>Permissions</label>:<span data-qe-id="processACLPermission"> {{optional(process.ACL.permission)}}</span> + </div> <h4 class="col-sm-24">Workflow</h4> - <div class="clearfix hidden-md"> </div> - <div class="row"> - <div class="col-sm-8"> - <label class="col-sm-24">Name</label> - <label class="col-sm-24 light">{{process.workflow.name}}</label> - </div> - <div class="col-sm-8"> - <label class="col-sm-24">Engine</label> - <label class="col-sm-24 light">{{process.workflow.engine}}</label> - </div> - <div class="col-sm-8"> - <label class="col-sm-24">Version</label> - <label class="col-sm-24 light">{{process.workflow.version}}</label> - </div> + <div class="col-sm-24"> + <label>Workflow Name</label>: + <label class="light" data-qe-id="processWorkflowName">{{process.workflow.name}}</label> + </div> + <div class="col-sm-24"> + <label>Engine</label>: + <label class="light" data-qe-id="processWorkflowEngine">{{process.workflow.engine}}</label> + </div> + <div class="col-sm-24"> + <label>Workflow Path</label>: + <label class="light" data-qe-id="processWorkflowPath">{{process.workflow.path}}</label> </div> - <label class="col-sm-24">Path</label> - <label class="col-sm-24 light">{{process.workflow.path}}</label> - - <h4 class="col-sm-24">Timing</h4> - <div class="clearfix hidden-md"> </div> - <label class="col-sm-24">Timezone</label> - <label class="col-sm-24 light">{{optional(process.timezone)}}</label> - <div class="row"> - <div class="col-sm-8"> - <label class="col-sm-24">Frequency</label> - <label class="col-sm-24 light">Every {{process.frequency.quantity}} {{process.frequency.unit}}</label> + <div class="col-sm-24 plr0px" ng-show="process.workflow.engine==='spark'"> + <h4 class="col-sm-24">Spark Attributes</h4> + <div class="col-sm-24"> + <label>Aplication</label>: + <label class="light" data-qe-id="processSparkApplication">{{process.workflow.spark.name}}</label> </div> - <div class="col-sm-8"> - <label class="col-sm-24">Max. parallel instances</label> - <label class="col-sm-24 light">{{process.parallel}}</label> + <div class="col-sm-24"> + <label>Main Class</label>: + <label class="light" data-qe-id="processSparkMainClass">{{process.workflow.spark.class}}</label> </div> - <div class="col-sm-8"> - <label class="col-sm-24">Order</label> - <label class="col-sm-24 light">{{optional(process.order)}}</label> + <div class="col-sm-24"> + <label>Runs On</label>: + <label class="light" data-qe-id="processSparkRunsOn">{{process.workflow.spark.master}}</label> </div> - </div> - <div class="clearfix hidden-md"> </div> - <h4 class="col-sm-24">Retry</h4> - <div class="clearfix hidden-md"> </div> - <div class="row"> - <div class="col-sm-8"> - <label class="col-sm-24">Policy</label> - <label class="col-sm-24 light">{{process.retry.policy}}</label> + <div class="col-sm-24"> + <label>Mode</label>: + <label class="light" data-qe-id="processSparkMode">{{process.workflow.spark.mode}}</label> + </div> + <div class="col-sm-24"> + <label>Jar</label>: + <label class="light" data-qe-id="processSparkJar">{{process.workflow.spark.jar}}</label> </div> - <div class="col-sm-8"> - <label class="col-sm-24">Attempts</label> - <label class="col-sm-24 light">{{process.retry.attempts}}</label> + <div class="col-sm-24"> + <label>Spark Options</label>: + <label class="light" data-qe-id="processSparkOpts">{{process.workflow.spark.sparkOptions}}</label> </div> - <div class="col-sm-8"> - <label class="col-sm-24">Delay</label> - <label class="col-sm-24 light">Up to {{process.retry.delay.quantity}} {{process.retry.delay.unit}}</label> + + <div class="col-sm-24"> + <label>Spark Arguments</label>: + <label class="light" data-qe-id="processSparkOpts">{{process.workflow.spark.arg}}</label> </div> </div> - <div class="clearfix hidden-md"> </div> + + <h4 class="col-sm-24">Timing</h4> + <div class="col-sm-24"> + <label>Timezone</label>: + <label class="light" data-qe-id="processTimezone">{{optional(process.timezone)}}</label> + </div> + <div class="col-sm-24"> + <label>Frequency</label>: + <label class="light">Every + <span data-qe-id="processFrequencyQuantity">{{process.frequency.quantity}}</span> + <span data-qe-id="processFrequencyUnit">{{process.frequency.unit}}</span> + </label> + </div> + <div class="col-sm-24"> + <label>Max. parallel instances</label>: + <label class="light" data-qe-id="processParallel">{{process.parallel}}</label> + </div> + <div class="col-sm-24"> + <label>Instance Usage</label>: + <label class="light" data-qe-id="processOrder">{{optional(process.order)}}</label> + </div> + + <h4 class="col-sm-24">Retry</h4> + <div class="col-sm-24"> + <label>Retry Policy</label>: + <label class="light" data-qe-id="processRetryPolicy">{{process.retry.policy}}</label> + </div> + <div class="col-sm-24"> + <label>Attempts</label>: + <label class="light" data-qe-id="processRetryAttempts">{{process.retry.attempts}}</label> + </div> + <div class="col-sm-24"> + <label>Delay</label>: + <label class="light">Up to + <span data-qe-id="processRetryDelayQuantity">{{process.retry.delay.quantity}}</span> + <span data-qe-id="processRetryDelayUnit">{{process.retry.delay.unit}}</span> + </label> + </div> + + <h4 class="col-sm-24" ng-if="(process.properties | filter:{name: '!!'}).length > 0">Properties</h4> + <div class="col-sm-24" ng-repeat="property in process.properties | filter:{name: '!!'} track by $index"> + <label>{{property.name}}</label>:<span> {{property.value}}</span> + </div> + <h4 class="col-sm-24">Clusters</h4> - <div ng-repeat="cluster in process.clusters"> + <div ng-repeat="cluster in process.clusters track by $index" data-qe-id="processClusters"> <div class="row col-sm-offset-1 col-sm-22 detailsBox"> - <label class="col-sm-24">Name</label> - <label class="col-sm-24 light">{{cluster.name}}</label> - <div class="clearfix hidden-md"> </div> - <h4 class="col-sm-24">Validity</h4> - <div class="row"> - <div class="col-sm-12"> - <label class="col-sm-24">Start</label> - <label class="col-sm-24 light">{{cluster.validity.start.date|date:'yyyy-MM-dd'}} {{cluster.validity.start.time|date:'HH:mm'}}</label> - </div> - <div class="col-sm-12"> - <label class="col-sm-24">End</label> - <label class="col-sm-24 light">{{cluster.validity.end.date|date:'yyyy-MM-dd'}} {{cluster.validity.end.time|date:'HH:mm'}}</label> - </div> + <div class="col-sm-24"> + <label>Cluster Name</label>: + <label class="light" data-qe-id="processClusterName">{{cluster.name}}</label> + </div> + <label class="col-sm-24">Validity</label> + <div class="col-sm-24"> + <label>Start</label>: + <label class="light" data-qe-id="processClusterStart">{{cluster.validity.start.date|date:'yyyy-MM-dd'}} {{cluster.validity.start.time|date:'HH:mm'}}</label> + <label>End</label>: + <label class="light" data-qe-id="processClusterEnd">{{cluster.validity.end.date|date:'yyyy-MM-dd'}} {{cluster.validity.end.time|date:'HH:mm'}}</label> </div> </div> </div> - <div class="clearfix hidden-md"> </div> <h4 class="col-sm-24">Inputs</h4> - <div ng-repeat="input in process.inputs"> + <div ng-repeat="input in process.inputs track by $index" data-qe-id="processInputs"> <div class="row col-sm-offset-1 col-sm-22 detailsBox"> - <label class="col-sm-24">Name</label> - <label class="col-sm-24 light">{{input.name}}</label> - <label class="col-sm-24">Feed</label> - <label class="col-sm-24 light">{{input.feed}}</label> - <div class="clearfix hidden-md"> </div> - <h4 class="col-sm-24">Instance</h4> - <div class="row"> - <div class="col-sm-12"> - <label class="col-sm-24">Start</label> - <label class="col-sm-24 light">{{input.start}}</label> - </div> - <div class="col-sm-12"> - <label class="col-sm-24">End</label> - <label class="col-sm-24 light">{{input.end}}</label> - </div> + <div class="col-sm-24"> + <label>Name</label>: + <label class="light" data-qe-id="processInputName">{{input.name}}</label> + </div> + <div class="col-sm-24"> + <label>Feed</label>: + <label class="light" data-qe-id="processInputFeed">{{input.feed}}</label> + </div> + <label class="col-sm-24">Instance</label> + <div class="col-sm-24"> + <label>Start</label>: + <label class="light" data-qe-id="processInstanceStart">{{input.start}}</label> + <label>End</label>: + <label class="light" data-qe-id="processInstanceEnd">{{input.end}}</label> </div> </div> </div> <h4 class="col-sm-24">Outputs</h4> - <div ng-repeat="output in process.outputs"> + <div ng-repeat="output in process.outputs track by $index" data-qe-id="processOutputs"> <div class="row col-sm-offset-1 col-sm-22 detailsBox"> - <label class="col-sm-24">Name</label> - <label class="col-sm-24 light">{{output.name}}</label> - <label class="col-sm-24">Feed</label> - <label class="col-sm-24 light">{{output.feed}}</label> - <div class="clearfix hidden-md"> </div> - <h4 class="col-sm-24">Instance</h4> + <div class="col-sm-24"> + <label>Name</label> + <label class="light" data-qe-id="processOutputName">{{output.name}}</label> + </div> + <div class="col-sm-24"> + <label>Feed</label> + <label class="light" data-qe-id="processOutputFeed">{{output.feed}}</label> + </div> <label class="col-sm-24">Instance</label> - <label class="col-sm-24 light">{{output.outputInstance}}</label> + <div class="col-sm-24"> + <label>Instance</label> + <label class="light" data-qe-id="processOutputInstance">{{output.outputInstance}}</label> + </div> </div> </div> </div> - <div class="clearfix hidden-md"> </div> - <div class="row"> - <div class="col-xs-24 mt20"> - <button type="button" class="btn prevBtn" - ng-click="goBack('forms.process.io')" - ng-disabled="buttonSpinners.backShow"> - Previous <img src="css/img/ajax-loader.gif" ng-if="buttonSpinners.backShow" /> - </button> - <button class="btn nextBtn pull-right" + <div class="col-xs-24 mt35 pb15px pl0px"> + <button type="button" class="btn prevBtn" + ng-click="goBack()" + ng-disabled="buttonSpinners.backShow"> + PREVIOUS <img src="css/img/ajax-loader.gif" ng-if="buttonSpinners.backShow" /> + </button> + <div class="pull-right"> + <a class="btn cnclBtn" ui-sref="main"> + CANCEL + </a> + <button class="btn nextBtn" ng-disabled="processForm.$invalid || buttonSpinners.show" - ng-click="saveEntity()"> - Save <img src="css/img/ajax-loader.gif" ng-if="buttonSpinners.show" /> + ng-click="saveEntity()" scroll-to-error> + SAVE <img src="css/img/ajax-loader.gif" ng-if="buttonSpinners.show" /> </button> - <a class="pull-right" ui-sref="main"> - Cancel - </a> </div> </div> -</form> \ No newline at end of file +</form> http://git-wip-us.apache.org/repos/asf/falcon/blob/76dc2e18/falcon-ui/app/html/process/processFormTpl.html ---------------------------------------------------------------------- diff --git a/falcon-ui/app/html/process/processFormTpl.html b/falcon-ui/app/html/process/processFormTpl.html index 00d2c66..7c4a9e1 100644 --- a/falcon-ui/app/html/process/processFormTpl.html +++ b/falcon-ui/app/html/process/processFormTpl.html @@ -17,90 +17,77 @@ * limitations under the License. */ --> -<div class="col-xs-22 col-xs-offset-1 entityForm" id="processFormTmpl"> +<div class="entityForm"> <div class="col-xs-24"> - <div class="row"> - - <h3 id="formTitle" class="col-xs-24"> - <span class="entypo cycle icon-lg"></span> New Process - </h3> - - <div ng-class="{'col-xs-12' : propsOpen, 'col-xs-20' : !propsOpen}"> - <div class="detailsBox"> - <div class="processProgressBox" ng-class="{ - general:isActive('forms.process.general'), - properties:isActive('forms.process.properties'), - clusters:isActive('forms.process.clusters'), - inputsAndOutputs: isActive('forms.process.io'), - summary:isActive('forms.process.summary') - }"> - <div class="progressBar col-xs-24"> - <div> - <span> - <div class="fir">1<span class="entypo check"></span></div> - <h6>General</h6> - </span> - <span> - <div class="sec">2<span class="entypo check"></span></div> - <h6>Properties</h6> - </span> - <span> - <div class="thi">3<span class="entypo check"></span></div> - <h6>Clusters</h6> - </span> - <span> - <div class="fou">4<span class="entypo check"></span></div> - <h6>Inputs & Outputs</h6> - </span> - <span> - <div class="fif">5<span class="entypo check"></span></div> - <h6>Summary</h6> - </span> - </div> - </div> + <div class="preview pullOver"> + <button id="previewXMLBtn" type="button" class="btn btn-default btn-md pull-right nextBtn" ng-click="toggleclick()" >Preview XML</button> + </div> + <br/> + <div> + <div class=" formBoxContainer detailsBox"> + <div class="row processProgressBox" ng-class="{ + general:isActive('forms.process.general'), + summary:isActive('forms.process.summary') + }"> + <div class="progressBar col-xs-24"> + <div class="text-center fir" ng-class="{ + active:isActive('forms.process.general'), + completed:isCompleted('forms.process.general')}">General</div> + <div class="text-center thi" ng-class="{ + active:isActive('forms.process.summary'), + completed:isCompleted('forms.process.summary')}">Summary</div> </div> + </div> - <div class="row"> - <div class="col-xs-offset-1 col-xs-22"> - <fieldset id="fieldWrapper" ng-disabled="!editXmlDisabled"> - <div ui-view class="formViewContainer"></div> - </fieldset> - </div> + <div class="row customContainer"> + <div class="col-xs-offset-1 col-xs-22"> + <fieldset id="fieldWrapper" ng-disabled="!editXmlDisabled"> + <div class="formViewContainer"> + <div class="col-xs-24"> + <label class="title"><span class="entypo cycle icon-lg entypo-align-sub"></span> NEW PROCESS</label> + </div> + <div ui-view></div> + </div> + </fieldset> </div> </div> - </div> - - <div ng-class="{'col-xs-12' : propsOpen, 'col-xs-4' : !propsOpen}"> - <div class="detailsBox"> - <div class="row"> - - <div class="col-xs-13 col-xs-offset-1 noSpecial"> - <h5><i class="pointer glyphicon" ng-click="propsOpen = !propsOpen" ng-class="propsOpen ? 'glyphicon-minus-sign':'glyphicon-plus-sign'"></i> XML Preview</h5> + </div> + <div class="hide xmlPreviewContainer detailsBox"> + <div class="row dt"> + <div class="col-xs-24 pt15px"> + <div class="col-xs-13 noSpecial"> + <h5>XML Preview</h5> + <label style="margin-top: -10px;margin-bottom: -2px;" ng-if="invalidXml" class="custom-danger">Invalid Xml</label> </div> - - <div ng-if="propsOpen" class="col-xs-9"> + <div class="pull-right"> <button type="button" id="editXmlButton" - class="btn btn-default btn-xs pull-right" + class="btn btn-default btn-xs" ng-click="toggleEditXml()" - ng-class="{'btn-warning':!editXmlDisabled}"> + ng-class="{'btn-warning':!editXmlDisabled}" + ng-disabled="invalidXml"> <div ng-if="editXmlDisabled">Edit XML</div> <div ng-if="!editXmlDisabled">Finish</div> </button> - </div> - <div ng-show="propsOpen" class="col-xs-24"> - <div class="row"> - <div class="col-xs-22 col-xs-offset-1" > - <textarea ng-model="prettyXml" class="form-control prettyXml" elastic ng-disabled="editXmlDisabled"></textarea> - </div> - </div> + <button type="button" + id="revertXMLBtn" + class="btn btn-default btn-xs" + ng-if="invalidXml" + ng-click="revertXml()"> + <div>Revert</div> + </button> </div> - + </div> + <div class="col-xs-24 showValidationStyle"> + <textarea ng-model="prettyXml" + class="form-control" + elastic + ng-disabled="editXmlDisabled" + ng-class="{fakeInvalid:invalidXml}"> + </textarea> </div> </div> </div> - - </div> </div> </div> http://git-wip-us.apache.org/repos/asf/falcon/blob/76dc2e18/falcon-ui/app/html/process/processSummary.html ---------------------------------------------------------------------- diff --git a/falcon-ui/app/html/process/processSummary.html b/falcon-ui/app/html/process/processSummary.html index e9eb4a4..cc4a1d9 100644 --- a/falcon-ui/app/html/process/processSummary.html +++ b/falcon-ui/app/html/process/processSummary.html @@ -30,7 +30,6 @@ <div ng-repeat="tag in process.tags | filter:{key: '!!'}"> {{tag.key}} = {{tag.value}} </div> - <div ng-show="!hasTags()">No tags selected</div> </div> <h5 class="col-sm-24">Access Control List</h5> @@ -61,14 +60,41 @@ <label class="col-sm-24">Engine</label> <label class="col-sm-24 light">{{process.workflow.engine}}</label> </div> - <div class="col-sm-8"> - <label class="col-sm-24">Version</label> - <label class="col-sm-24 light">{{process.workflow.version}}</label> - </div> </div> <label class="col-sm-24">Path</label> <label class="col-sm-24 light">{{process.workflow.path}}</label> + <div class="col-sm-24 plr0px" ng-show="process.workflow.engine==='spark'"> + <h5 class="col-sm-24">Spark Attributes</h4> + <div class="col-sm-24"> + <label>Aplication</label>: + <label class="light" data-qe-id="processSparkApplication">{{process.workflow.spark.name}}</label> + </div> + <div class="col-sm-24"> + <label>Main Class</label>: + <label class="light" data-qe-id="processSparkMainClass">{{process.workflow.spark.class}}</label> + </div> + <div class="col-sm-24"> + <label>Runs On</label>: + <label class="light" data-qe-id="processSparkRunsOn">{{process.workflow.spark.master}}</label> + </div> + <div class="col-sm-24"> + <label>Mode</label>: + <label class="light" data-qe-id="processSparkMode">{{process.workflow.spark.mode}}</label> + </div> + <div class="col-sm-24"> + <label>Jar</label>: + <label class="light" data-qe-id="processSparkJar">{{process.workflow.spark.jar}}</label> + </div> + <div class="col-sm-24"> + <label>Spark Options</label>: + <label class="light" data-qe-id="processSparkOpts">{{process.workflow.spark.sparkOptions}}</label> + </div> + <div class="col-sm-24"> + <label>Spark Arguments</label>: + <label class="light" data-qe-id="processSparkOpts">{{process.workflow.spark.arg}}</label> + </div> + </div> <h5 class="col-sm-24">Timing</h5> <label class="col-sm-24" ng-if="process.timezone">Timezone</label> @@ -89,6 +115,11 @@ </div> </div> + <h5 class="col-sm-24" ng-if="(process.properties | filter:{name: '!!'}).length > 0">Properties</h5> + <div class="col-sm-24" ng-repeat="property in process.properties | filter:{name: '!!'}"> + <label>{{property.name}}</label>:<span> {{property.value}}</span> + </div> + <h5 class="col-sm-24">Retry</h5> <div class="row"> @@ -181,4 +212,4 @@ </div> </div> </div> -</div> \ No newline at end of file +</div> http://git-wip-us.apache.org/repos/asf/falcon/blob/76dc2e18/falcon-ui/app/html/snapshot/snapshotFormAdvancedStepTpl.html ---------------------------------------------------------------------- diff --git a/falcon-ui/app/html/snapshot/snapshotFormAdvancedStepTpl.html b/falcon-ui/app/html/snapshot/snapshotFormAdvancedStepTpl.html new file mode 100644 index 0000000..d0fb50b --- /dev/null +++ b/falcon-ui/app/html/snapshot/snapshotFormAdvancedStepTpl.html @@ -0,0 +1,194 @@ +<!-- +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<form name="snapshotForm" novalidate id="snapshotFormAdvancedStep"> + + <div class="col-xs-24"> + <label tooltip="dataset.tdeEncryptionEnabled">TDE Encryption</label> + <input type="checkbox" ng-model="snapshot.tdeEncryptionEnabled" ng-checked="snapshot.tdeEncryptionEnabled"/> + </div> + <hr class="col-xs-24" /> + + <div class="col-xs-24"><label>Retry Policy</label></div> + <div class="col-xs-24"> + <label class="light" tooltip="snapshot.retryPolicy" tooltip-position="up"> + Type + </label> + </div> + <div class="col-xs-6"> + <select ng-model="snapshot.retry.policy" ng-required="true" validation-message="{{validations.messages.option}}" + ng-change="policyChange()"> + <option value="" disabled selected style='display:none;'>-Select policy-</option> + <option value="periodic">Periodic</option> + <option value="exp-backoff">Exponential Backup</option> + <option value="final">None</option> + </select> + </div> + <div class="col-xs-24"> + <label class="light">Delay Up to</label> + </div> + <div class="col-xs-3"> + <input type="text" class="form-control" + ng-model="snapshot.retry.delay.quantity" validation-message="{{validations.messages.number}}" + id="delayQuantity" ng-keydown="validations.acceptOnlyNumber($event)" + ng-required="true" + ng-disabled = "snapshot.retry.policy === 'final'" + ng-pattern="validations.patterns.twoDigits"/> + </div> + <div class="col-xs-3 plr0px"> + <select ng-model="snapshot.retry.delay.unit" ng-required="true" + validation-message="{{validations.messages.option}}" + ng-disabled = "snapshot.retry.policy === 'final'"> + <option value="" disabled selected style='display:none;'>-Select delay-</option> + <option value="minutes">minutes</option> + <option value="hours">hours</option> + <option value="days">days</option> + <option value="months">months</option> + </select> + </div> + <div class="col-xs-24"> + <label class="light">Attempts</label> + </div> + <div class="col-xs-6"> + <input type="text" class="form-control" validation-message="{{validations.messages.number}}" + ng-model="snapshot.retry.attempts" ng-keydown="validations.acceptOnlyNumber($event)" + id="attemptsField" + ng-disabled = "snapshot.retry.policy === 'final'" + ng-required="true" + ng-pattern="validations.patterns.twoDigits"/> + </div> + <hr class="col-xs-24" /> + + <div class="col-xs-24"><label>Performance & Throttling - Distributed Copy</label></div> + <div class="col-xs-12 plr0px"> + <div class="col-xs-12 plr0px"> + <div class="col-xs-24 plr0px"> + <div class="col-xs-24"> + <label class="light" tooltip="dataset.distcpMapBandwidth">Max Bandwidth</label> + </div> + <div class="col-xs-20"> + <input type="text" + name="distcpMapBandwidth" + ng-model="snapshot.allocation.distcpMapBandwidth" + class="form-control" /> + </div> + <label class="light bandwidth-label">MB</label> + </div> + <div class="col-xs-20"> + <label class="light" tooltip="dataset.distcpMaxMaps">Max Map Jobs</label> + <input type="text" + name="distcpMaxMaps" + ng-model="snapshot.allocation.distcpMaxMaps" + class="form-control" /> + </div> + </div> + </div> + <hr class="col-xs-24" /> + + <div class="col-xs-24"> + <label>Alerts</label> + </div> + + <div class="col-xs-24"> + <label class="light" tooltip="dataset.jobNotificationReceivers">Send alerts to</label> + </div> + <div class="col-xs-12 alertsBox plr0px"> + <div class="emailBox"> + <div class="col-xs-16"> + <input class="form-control" + name="emailAlertInput" + ng-model="snapshot.alert.email" + type="text" + placeholder="Email" + ng-pattern="validations.patterns.email" + validation-optional-message="{{validations.messages.email}}"> + </div> + </div> + <div class="addAlertBox col-xs-3"> + <button class="btn btn-default btn-xs" + ng-disabled="!snapshot.alert.email" + type="button" + ng-click="addAlert()"> + <span class="glyphicon glyphicon-plus"></span>add alert + </button> + </div> + </div> + <div class="col-xs-24"> + <div class="col-xs-12 emailArrayRow mt10" ng-repeat="email in snapshot.alerts"> + <span class="col-xs-16">{{email}}</span> + <div class="col-xs-3"><button class="btn btn-default btn-xs" + type="button" + ng-click="removeAlert()"> + <span class="glyphicon glyphicon-minus"></span> delete + </button></div> + </div> + </div> + <hr class="col-xs-24" /> + + <div class="col-xs-24"><label>Access Control List</label></div> + <div class="col-xs-12 plr0px"> + <div class="col-xs-24 plr0px"> + <div class="col-xs-12"> + <label class="light">Owner<mandatory-field></mandatory-field></label> + <input type="text" + name="aclOwnerInput" + ng-model="snapshot.ACL.owner" + ng-pattern="validations.patterns.unixId" + class="form-control" + ng-required="true" + validation-message="{{validations.messages.acl.owner}}"/> + </div> + <div class="col-xs-12 pl0px"> + <label class="light">Group<mandatory-field></mandatory-field></label> + <input type="text" + name="aclGroupInput" + ng-model="snapshot.ACL.group" + ng-pattern="validations.patterns.unixId" + class="form-control" + ng-required="true" + validation-message="{{validations.messages.acl.group}}" /> + </div> + </div> + <div class="col-xs-24"> + <div class="col-xs-8 plr0px"> + <label class="light">Permissions<mandatory-field></mandatory-field></label> + <acl-permissions acl-model="snapshot.ACL.permission"></acl-permissions> + </div> + </div> + </div> + + <div class="col-xs-24 mt35 pb15px plr0px"> + <button id="snapshot.backToStep1" class="btn prevBtn" type="button" ng-click="goBack()" ng-disabled="buttonSpinners.backShow"> + PREVIOUS <img src="css/img/ajax-loader.gif" ng-if="buttonSpinners.backShow"> + </button> + <div class="pull-right"> + <a class="btn cnclBtn" ui-sref="main"> + CANCEL + </a> + <button id="snapshot.step2" class="btn nextBtn" ng-click="goNext(snapshotForm.$invalid)" scroll-to-error> + NEXT <img src="css/img/ajax-loader.gif" ng-if="buttonSpinners.show"> + </button> + <button id="snapshot.step3" class="btn advancedSaveBtn" ng-click="save(snapshotForm.$invalid)" + ng-disabled="buttonSpinners.saveShow" scroll-to-error> + SAVE ADVANCED OPTIONS <img src="css/img/ajax-loader.gif" ng-if="buttonSpinners.saveShow"> + </button> + </div> + </div> + +</form> http://git-wip-us.apache.org/repos/asf/falcon/blob/76dc2e18/falcon-ui/app/html/snapshot/snapshotFormGeneralStepTpl.html ---------------------------------------------------------------------- diff --git a/falcon-ui/app/html/snapshot/snapshotFormGeneralStepTpl.html b/falcon-ui/app/html/snapshot/snapshotFormGeneralStepTpl.html new file mode 100644 index 0000000..9990554 --- /dev/null +++ b/falcon-ui/app/html/snapshot/snapshotFormGeneralStepTpl.html @@ -0,0 +1,505 @@ +<!-- +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<form id="snapshotFormGeneralStep" name="datasetForm" novalidate> + + <div class="col-xs-6"> + <label class="light" tooltip="dataset.name">Name<mandatory-field></mandatory-field></label> + <input type="text" + name="nameInput" + class="form-control" + ng-model="snapshot.name" + placeholder="" + ng-disabled="editingMode" + ng-pattern="validations.patterns.name" + ng-required="true" + check-name="{type:'process', check:!editingMode}"/> + </label> + </div> + + <div class="col-xs-24"> + <label class="light">Tags</label> + </div> + + <div class="col-xs-12"> + <div ng-repeat="tag in snapshot.tags"> + <div class="row dynamic-table-spacer"> + <div class="col-xs-8"> + <input type="text" class="form-control" ng-model="tag.key" + validation-optional-message="{{validations.messages.key}}" + ng-pattern="validations.patterns.alpha" ng-required="tag.value" placeholder="name"/> + </div> + <div class="col-xs-8"> + <input type="text" class="form-control" validation-optional-message="{{validations.messages.value}}" + ng-model="tag.value" ng-pattern="validations.patterns.alpha" + ng-required="tag.key" placeholder="value"/> + </div> + <div class="col-xs-8"> + <button type="button" class="btn btn-default btn-xs" ng-click="removeTag($index)" ng-if="!$first || !$last"> + <span class="entypo minus"></span> delete + </button> + <button type="button" class="btn btn-default btn-xs" ng-click="addTag()" ng-if="$last"> + <span class="entypo plus"></span> add tag + </button> + </div> + </div> + </div> + </div> + + <div class="col-xs-24 plr0px"> + <div class="col-xs-12 plr0px"> + <div class="col-xs-24 plr0px clusterBox"> + <h3>Source</h3> + <div class="runJobOnBox"> + <input type="radio" id="runJobOnSourceRadio" ng-model="snapshot.runOn" ng-rquired="true" value="source"/> + Run job here + </div> + + <div class="col-xs-24 plr0px"> + <div class="col-xs-6"><label class="light">Cluster<mandatory-field></mandatory-field></label></div> + <div class="col-xs-10 mt10"> + <select ng-model="snapshot.source.cluster" + ng-required="true" validation-message="{{validations.messages.cluster}}" + name="sourceClusterSelect" class="form-control padding0" + ng-change="validateCluster()"> + <option value="" disabled style='display:none;'>-Select source cluster-</option> + <option ng-selected="snapshot.source.cluster === cluster.name" + ng-repeat="cluster in clusterList" + value="{{cluster.name}}"> + {{cluster.name}} + </option> + </select> + </div> + </div> + <div class="col-xs-24 plr0px"> + <div class="col-xs-6"> + <label class="light" tooltip="dataset.snapshot.sourceSnapshotDir"> + Source Directory<mandatory-field></mandatory-field> + </label> + </div> + <div class="col-xs-10 mt10"> + <input type="text" + name="sourceDirectoryPath" + ng-model="snapshot.source.directoryPath" + ng-pattern="validations.patterns.path" + class="form-control" + ng-required="true" + validation-message="{{validations.messages.path}}" /> + </div> + </div> + <div class="col-xs-24 plr0px"> + <div class="col-xs-6"> + <label class="light" tooltip="dataset.snapshot.sourceSnapshotRetentionAgeLimit">Delete Snapshot After</label> + </div> + <div class="col-xs-4 mt10"> + <input type="text" + name="sourceDeleteFrequency" + ng-model="snapshot.source.deleteFrequency.quantity" + ng-pattern="validations.patterns.twoDigits" + ng-keydown="validations.acceptOnlyNumber($event)" + class="form-control" + ng-rquired="true" + validation-message="{{validations.messages.number}}" /> + </div> + <div class="col-xs-8 mt10"> + <select ng-model="snapshot.source.deleteFrequency.unit" + class="form-control padding0" ng-rquired="true"> + <option selected value="minutes">minutes</option> + <option value="hours">hours</option> + <option value="days">days</option> + <option value="months">months</option> + </select> + </div> + </div> + <div class="col-xs-24 plr0px"> + <div class="col-xs-6"> + <label class="light" tooltip="dataset.snapshot.sourceSnapshotRetentionNumber">Keep Last</label> + </div> + <div class="col-xs-4 mt10"> + <input type="text" + name="sourceRetentionNumber" + ng-model="snapshot.source.retentionNumber" + ng-pattern="validations.patterns.twoDigits" + ng-keydown="validations.acceptOnlyNumber($event)" + class="form-control" + ng-rquired="true" + validation-message="{{validations.messages.number}}" /> + </div> + <label class="light">snapshots</label> + </div> + </div> + </div> + + <div class="col-xs-12 plr0px pl5"> + <div class="col-xs-24 plr0px clusterBox"> + <h3>Target</h3> + <div class="runJobOnBox"> + <input type="radio" id="runJobOnTargetRadio" ng-model="snapshot.runOn" value="target" ng-rquired="true" /> + Run job here + </div> + + <div class="col-xs-24 plr0px"> + <div class="col-xs-6"><label class="light">Cluster<mandatory-field></mandatory-field></label></div> + <div class="col-xs-10 mt10"> + <select ng-model="snapshot.target.cluster" + ng-required="true" validation-message="{{validations.messages.cluster}}" + name="targetClusterSelect" class="form-control padding0" + ng-change="validateCluster()"> + <option value="" disabled style='display:none;'>-Select target cluster-</option> + <option ng-selected="snapshot.target.cluster === cluster.name" + ng-repeat="cluster in clusterList" + value="{{cluster.name}}"> + {{cluster.name}} + </option> + </select> + <div class="custom-danger" ng-show="clusterErrorMessage != ''"> + {{clusterErrorMessage}} + </div> + </div> + </div> + + <div class="col-xs-24 plr0px"> + <div class="col-xs-6"> + <label class="light" tooltip="dataset.snapshot.targetSnapshotDir"> + Target Directory<mandatory-field></mandatory-field> + </label> + </div> + <div class="col-xs-10 mt10"> + <input type="text" + name="targetDirectoryPath" + ng-model="snapshot.target.directoryPath" + ng-pattern="validations.patterns.path" + class="form-control" + ng-required="true" + validation-message="{{validations.messages.path}}" /> + </div> + </div> + <div class="col-xs-24 plr0px"> + <div class="col-xs-6"> + <label class="light" tooltip="dataset.snapshot.targetSnapshotRetentionAgeLimit">Delete Snapshot After</label> + </div> + <div class="col-xs-4 mt10"> + <input type="text" + name="targetDeleteFrequency" + ng-model="snapshot.target.deleteFrequency.quantity" + ng-pattern="validations.patterns.twoDigits" + ng-keydown="validations.acceptOnlyNumber($event)" + class="form-control" + ng-rquired="true" + validation-message="{{validations.messages.number}}" /> + </div> + <div class="col-xs-8 mt10"> + <select ng-model="snapshot.target.deleteFrequency.unit" class="form-control padding0" ng-rquired="true"> + <option selected value="minutes">minutes</option> + <option value="hours">hours</option> + <option value="days">days</option> + <option value="months">months</option> + </select> + </div> + </div> + <div class="col-xs-24 plr0px"> + <div class="col-xs-6"> + <label class="light" tooltip="dataset.snapshot.targetSnapshotRetentionNumber">Keep Last</label> + </div> + <div class="col-xs-4 mt10"> + <input type="text" + name="targetRetentionNumber" + ng-model="snapshot.target.retentionNumber" + ng-pattern="validations.patterns.twoDigits" + ng-keydown="validations.acceptOnlyNumber($event)" + class="form-control" + ng-rquired="true" + validation-message="{{validations.messages.number}}" /> + </div> + <label class="light">snapshots</label> + </div> + </div> + </div> + </div> + + <div class="col-xs-24"><label>Run Duration</label></div> + <div class="col-xs-24 validityBox plr0px"> + <div class="col-xs-24 plr0px"> + <div class="startDateBox col-xs-4"> + <label class="light">Start</label> + <input type="text" + name="startDateInput" + class="form-control dateInput" + placeholder="{{dateFormat | lowercase}}" + ng-model="snapshot.validity.start.date" + ng-required="true" + simple-date-picker /> + + </div> + <div class="startTimeBox col-xs-4"> + <label class="light">Begin Time</label> + <timepicker ng-change="constructDate()" + ng-model="snapshot.validity.start.time" + ng-required="true" + hour-step="1" + minute-step="1" + show-meridian="true"> + </timepicker> + </div> + </div> + <div class="col-xs-24 plr0px"> + <div class="endDateBox col-xs-4"> + <label class="light">End</label> + <input type="text" + name="startDateInput" + class="form-control dateInput" + placeholder="{{dateFormat | lowercase}}" + ng-model="snapshot.validity.end.date" + ng-required="true" + simple-date-picker /> + + </div> + <div class="endTimeBox col-xs-4"> + <label class="light">End Time<mandatory-field></mandatory-field></label> + <timepicker ng-change="constructDate()" + ng-model="snapshot.validity.end.time" + ng-required="true" + hour-step="1" + minute-step="1" + show-meridian="true"> + </timepicker> + </div> + </div> + </div> + + <div class="col-xs-12 frequencyBox plr0px"> + <div class="col-xs-24"> + <label>Frequency</label> + </div> + <div class="col-xs-24"> + <label class="light">Repeat Every</label> + </div> + <div class="col-xs-24 plr0px"> + <div class="col-xs-8"> + <input type="text" + name="frequencyQuantity" + ng-model="snapshot.frequency.quantity" + ng-pattern="validations.patterns.twoDigits" + ng-keydown="validations.acceptOnlyNumber($event)" + ng-keyup="checkMininumFrequency(snapshot.frequency.quantity, snapshot.frequency.unit, datasetForm.frequencyQuantity)" + class="form-control" + ng-required="true" + validation-message="{{validations.messages.number}}" /> + </div> + <div class="col-xs-8"> + <select ng-model="snapshot.frequency.unit" class="form-control padding0" ng-required="true" + ng-change="checkMininumFrequency(snapshot.frequency.quantity, snapshot.frequency.unit, datasetForm.frequencyQuantity)"> + <option selected value="minutes">minutes</option> + <option value="hours">hours</option> + <option value="days">days</option> + <option value="months">months</option> + </select> + </div> + <div class="col-xs-24 custom-danger" ng-if="!isFrequencyValid">{{validations.messages.frequency.minimum}}</div> + </div> + + <div class="col-xs-24"> + <label class="light">Timezone</label> + </div> + <div class="col-xs-24"> + <time-zone-select ng-model="snapshot.validity.timezone"></time-zone-select> + </div> + </div> + + <div class="col-xs-24 advancedOption" ng-click="expandOptions = !expandOptions" id="snapshotAdvancedOption"> + <label class="mt15 pointer blink-success">ADVANCED OPTIONS</label> + <i class="glyphicon glyphicon-chevron-down mt15" ng-if="!expandOptions"></i> + <i class="glyphicon glyphicon-chevron-up mt15" ng-if="expandOptions"></i> + </div> + + <div id="advancedOptionsBox" class="col-xs-24 plr0px" ng-class="{expanded:expandOptions}"> + <div class="col-xs-24"> + <label tooltip="dataset.tdeEncryptionEnabled">TDE Encryption</label> + <input type="checkbox" ng-model="snapshot.tdeEncryptionEnabled" ng-checked="snapshot.tdeEncryptionEnabled"/> + </div> + <hr class="col-xs-24" /> + + <div class="col-xs-24"><label>Retry Policy</label></div> + <div class="col-xs-24"> + <label class="light" tooltip="snapshot.retryPolicy" tooltip-position="up"> + Type + </label> + </div> + <div class="col-xs-6"> + <select ng-model="snapshot.retry.policy" ng-required="true" validation-message="{{validations.messages.option}}" + ng-change="policyChange()"> + <option value="" disabled selected style='display:none;'>-Select policy-</option> + <option value="periodic">Periodic</option> + <option value="exp-backoff">Exponential Backup</option> + <option value="final">None</option> + </select> + </div> + <div class="col-xs-24"> + <label class="light">Delay Up to</label> + </div> + <div class="col-xs-3"> + <input type="text" class="form-control" + ng-model="snapshot.retry.delay.quantity" validation-message="{{validations.messages.number}}" + id="delayQuantity" ng-keydown="validations.acceptOnlyNumber($event)" + ng-required="true" + ng-disabled = "snapshot.retry.policy === 'final'" + ng-pattern="validations.patterns.twoDigits"/> + </div> + <div class="col-xs-3 plr0px"> + <select ng-model="snapshot.retry.delay.unit" ng-required="true" + validation-message="{{validations.messages.option}}" + ng-disabled = "snapshot.retry.policy === 'final'"> + <option value="" disabled selected style='display:none;'>-Select delay-</option> + <option value="minutes">minutes</option> + <option value="hours">hours</option> + <option value="days">days</option> + <option value="months">months</option> + </select> + </div> + <div class="col-xs-24"> + <label class="light">Attempts</label> + </div> + <div class="col-xs-6"> + <input type="text" class="form-control" validation-message="{{validations.messages.number}}" + ng-model="snapshot.retry.attempts" ng-keydown="validations.acceptOnlyNumber($event)" + id="attemptsField" + ng-disabled = "snapshot.retry.policy === 'final'" + ng-required="true" + ng-pattern="validations.patterns.twoDigits"/> + </div> + <hr class="col-xs-24" /> + + <div class="col-xs-24"><label>Performance & Throttling - Distributed Copy</label></div> + <div class="col-xs-12 plr0px"> + <div class="col-xs-12 plr0px"> + <div class="col-xs-24 plr0px"> + <div class="col-xs-24"> + <label class="light" tooltip="dataset.distcpMapBandwidth">Max Bandwidth</label> + </div> + <div class="col-xs-20"> + <input type="text" + name="distcpMapBandwidth" + ng-model="snapshot.allocation.distcpMapBandwidth" + class="form-control" /> + </div> + <label class="light bandwidth-label">MB</label> + </div> + <div class="col-xs-20"> + <label class="light" tooltip="dataset.distcpMaxMaps">Max Map Jobs</label> + <input type="text" + name="distcpMaxMaps" + ng-model="snapshot.allocation.distcpMaxMaps" + class="form-control" /> + </div> + </div> + </div> + <hr class="col-xs-24" /> + + <div class="col-xs-24"> + <label>Alerts</label> + </div> + + <div class="col-xs-24"> + <label class="light" tooltip="dataset.jobNotificationReceivers">Send alerts to</label> + </div> + <div class="col-xs-12 alertsBox plr0px"> + <div class="emailBox"> + <div class="col-xs-16"> + <input class="form-control" + name="emailAlertInput" + ng-model="snapshot.alert.email" + type="text" + placeholder="Email" + ng-pattern="validations.patterns.email" + validation-optional-message="{{validations.messages.email}}"> + </div> + </div> + <div class="addAlertBox col-xs-3"> + <button class="btn btn-default btn-xs" + ng-disabled="!snapshot.alert.email" + type="button" + ng-click="addAlert()"> + <span class="glyphicon glyphicon-plus"></span>add alert + </button> + </div> + </div> + <div class="col-xs-24"> + <div class="col-xs-12 emailArrayRow mt10" ng-repeat="email in snapshot.alerts"> + <span class="col-xs-16">{{email}}</span> + <div class="col-xs-3"><button class="btn btn-default btn-xs" + type="button" + ng-click="removeAlert()"> + <span class="glyphicon glyphicon-minus"></span> delete + </button></div> + </div> + </div> + <hr class="col-xs-24" /> + + <div class="col-xs-24"><label>Access Control List</label></div> + <div class="col-xs-12 plr0px"> + <div class="col-xs-24 plr0px"> + <div class="col-xs-12"> + <label class="light">Owner<mandatory-field></mandatory-field></label> + <input type="text" + name="aclOwnerInput" + ng-model="snapshot.ACL.owner" + ng-pattern="validations.patterns.unixId" + class="form-control" + ng-required="true" + validation-message="{{validations.messages.acl.owner}}"/> + </div> + <div class="col-xs-12 pl0px"> + <label class="light">Group<mandatory-field></mandatory-field></label> + <input type="text" + name="aclGroupInput" + ng-model="snapshot.ACL.group" + ng-pattern="validations.patterns.unixId" + class="form-control" + ng-required="true" + validation-message="{{validations.messages.acl.group}}" /> + </div> + </div> + <div class="col-xs-24"> + <div class="col-xs-8 plr0px"> + <label class="light">Permissions<mandatory-field></mandatory-field></label> + <acl-permissions acl-model="snapshot.ACL.permission"></acl-permissions> + </div> + </div> + </div> + </div> + + <div class="col-xs-24 pb15px mt35"> + <div class="pull-right"> + <a class="btn cnclBtn" ui-sref="main"> + CANCEL + </a> + <button class="btn nextBtn" + ng-disabled="buttonSpinners.show" + ng-click="goNext(datasetForm.$invalid)" scroll-to-error> + NEXT <img src="css/img/ajax-loader.gif" ng-if="buttonSpinners.show" /> + </button> + <button class="btn nextBtn" + ng-disabled="datasetForm.$invalid || buttonSpinners.saveShow" + ng-click="save(datasetForm.$invalid)" scroll-to-error> + SAVE <img src="css/img/ajax-loader.gif" ng-if="buttonSpinners.saveShow" /> + </button> + </div> + </div> + +</form> http://git-wip-us.apache.org/repos/asf/falcon/blob/76dc2e18/falcon-ui/app/html/snapshot/snapshotFormSummaryStepTpl.html ---------------------------------------------------------------------- diff --git a/falcon-ui/app/html/snapshot/snapshotFormSummaryStepTpl.html b/falcon-ui/app/html/snapshot/snapshotFormSummaryStepTpl.html new file mode 100644 index 0000000..8329aa2 --- /dev/null +++ b/falcon-ui/app/html/snapshot/snapshotFormSummaryStepTpl.html @@ -0,0 +1,157 @@ +<!-- +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<div id="formSummaryBox" class="col-xs-24"> + <h4>General</h4> + <div> + <label>Name</label>: + <span>{{snapshot.name}}</span> + </div> + <div> + <label>Type</label> : + <span>{{snapshot.type}}</span> + </div> + <div> + <label>Tags</label>: + <div ng-repeat="tag in snapshot.tags"><span>{{tag.key}}</span> - <span>{{tag.value}}</span></div> + </div> + + <div class="col-xs-12 plr0px mb15"> + <div> + <h4>Source</h4> + </div> + <div class="box"> + <h3>{{snapshot.source.cluster}}</h3> + <div> + <label class="locationBox">Source Directory</label>: + <span>{{snapshot.source.directoryPath}}</span> + </div> + <div> + <label>Delete Snapshot After</label>: + <span>{{snapshot.source.deleteFrequency.quantity}} {{snapshot.source.deleteFrequency.unit}}</span> + </div> + <div> + <label>Keep Last</label>: + <span>{{snapshot.source.retentionNumber}} snapshots</span> + </div> + </div> + </div> + + <div class="col-xs-12 mb15"> + <div> + <h4>Target</h4> + </div> + <div class="box"> + <h3>{{snapshot.target.cluster}}</h3> + <div> + <label class="locationBox">Target Directory</label>: + <span>{{snapshot.target.directoryPath}}</span> + </div> + <div> + <label>Delete Snapshot After</label>: + <span>{{snapshot.target.deleteFrequency.quantity}} {{snapshot.source.deleteFrequency.unit}}</span> + </div> + <div> + <label>Keep Last</label>: + <span>{{snapshot.target.retentionNumber}} snapshots</span> + </div> + </div> + </div> + + <div> + <h4 class="lightSubtitle">Run On</h4> + <div ng-if="snapshot.runOn === 'source'"><span>{{snapshot.source.cluster}}</span></div> + <div ng-if="snapshot.runOn === 'target'"><span>{{snapshot.target.cluster}}</span></div> + </div> + + <hr /> + + <div> + <h4 class="lightSubtitle">Run Duration</h4> + <div><label>Start on</label>: <span>{{snapshot.validity.start.date|date:'yyyy-MM-dd'}} {{snapshot.validity.start.time|date:'HH:mm'|date:'HH:mm'}}</span></div> + <div><label>End on</label>: <span>{{snapshot.validity.end.date|date:'yyyy-MM-dd'}} {{snapshot.validity.end.time|date:'HH:mm'}}</span></div> + </div> + + <div> + <h4 class="lightSubtitle">Frequency</h4> + <div><span>{{snapshot.frequency.quantity}} {{snapshot.frequency.unit}}</span></div> + </div> + + <div> + <h4 class="lightSubtitle">Timezone</h4> + <div><span>{{snapshot.validity.timezone}}</span></div> + </div> + + <div> + <h4 class="lightSubtitle">TDE Encryption</h4> + <span>{{snapshot.tdeEncryptionEnabled}}</span> + <div> + + <div> + <h4 class="lightSubtitle">Retry</h4> + <label>Policy</label>: <span>{{snapshot.retry.policy}}</span> + <label>delay</label>: <span>{{snapshot.retry.delay.quantity}} {{snapshot.retry.delay.unit}}</span> + <label>Attempts</label>: <span>{{snapshot.retry.attempts}}</span> + </div> + <hr /> + + <div> + <h4 class="lightSubtitle">Allocation</h4> + <div> + <label>Max Bandwidth</label>: + <span>{{snapshot.allocation.distcpMapBandwidth}} MB</span> + </div> + <div> + <label>Max Map Jobs</label>: + <span>{{snapshot.allocation.distcpMaxMaps}}</span> + </div> + </div> + + <div> + <h4 ng-if="snapshot.alerts.length > 0" class="lightSubtitle">Alerts</h4> + <span>{{ snapshot.alerts.join() }}</span> + </div> + + <hr /> + <h4 class="lightSubtitle">Access Control List</h4> + <div> + <label>Owner</label>: <span>{{snapshot.ACL.owner}}</span> + <label>Group</label>: <span>{{snapshot.ACL.group}}</span> + <label>Permissions</label>: <span>{{snapshot.ACL.permission}}</span> + </div> + + <div class="col-xs-24 mt35 pb15px plr0px"> + <button type="button" class="btn prevBtn" + ng-click="goBack()" + ng-disabled="buttonSpinners.backShow"> + Previous <img src="css/img/ajax-loader.gif" ng-if="buttonSpinners.backShow" /> + </button> + <div class="pull-right"> + <a class="btn cnclBtn" ui-sref="main"> + CANCEL + </a> + <button class="btn nextBtn" + ng-disabled="buttonSpinners.saveShow" + ng-click="save()"> + SAVE <img src="css/img/ajax-loader.gif" ng-if="buttonSpinners.saveShow" /> + </button> + </div> + </div> + +</div> http://git-wip-us.apache.org/repos/asf/falcon/blob/76dc2e18/falcon-ui/app/html/snapshot/snapshotFormTpl.html ---------------------------------------------------------------------- diff --git a/falcon-ui/app/html/snapshot/snapshotFormTpl.html b/falcon-ui/app/html/snapshot/snapshotFormTpl.html new file mode 100644 index 0000000..121e82e --- /dev/null +++ b/falcon-ui/app/html/snapshot/snapshotFormTpl.html @@ -0,0 +1,50 @@ +<!-- +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<div id="formBox" class="snapshotForm"> + <div class="col-xs-24"> + <div class="formBoxContainer detailsBox"> + <div class="row snapshotProgressBox" ng-class="{ general:isActive('forms.snapshot.general'), + summary:isActive('forms.snapshot.summary')}"> + <div class="progressBar col-xs-24"> + <div class="text-center" ng-class="{ + active:isActive('forms.snapshot.general'), + completed:isCompleted('forms.snapshot.general')}">General</div> + <div class="text-center" ng-class="{ + active:isActive('forms.snapshot.summary'), + completed:isCompleted('forms.snapshot.summary')}">Summary</div> + </div> + </div> + + <div class="row customContainer"> + <div class="col-xs-offset-1 col-xs-22"> + <fieldset ng-disabled="!editXmlDisabled"> + <div class="formViewContainer"> + <div class="col-xs-24"> + <label class="title"> + <span class="entypo cycle icon-lg entypo-align-sub"></span> NEW SNAPSHOT BASED MIRROR</label> + </div> + <div ui-view></div> + </div> + </fieldset> + </div> + </div> + </div> + </div> +</div> http://git-wip-us.apache.org/repos/asf/falcon/blob/76dc2e18/falcon-ui/app/html/snapshot/snapshotSummary.html ---------------------------------------------------------------------- diff --git a/falcon-ui/app/html/snapshot/snapshotSummary.html b/falcon-ui/app/html/snapshot/snapshotSummary.html new file mode 100644 index 0000000..5762680 --- /dev/null +++ b/falcon-ui/app/html/snapshot/snapshotSummary.html @@ -0,0 +1,133 @@ +<!-- +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<div id="formSummaryBox" class="summaryBox"> + <h4>General</h4> + <div> + <label>Name</label>: + <span>{{extension.name}}</span> + </div> + <div> + <label>Type</label> : + <span>{{extension.type}}</span> + </div> + <div> + <label>Tags</label>: + <div ng-repeat="tag in extension.tags"><span>{{tag.key}}</span> - <span>{{tag.value}}</span></div> + </div> + + <div> + <h4>Source</h4> + </div> + <div class="box"> + <h3>{{extension.source.cluster}}</h3> + <div> + <label class="locationBox">Source Directory</label>: + <span>{{extension.source.directoryPath}}</span> + </div> + <div> + <label>Delete Snapshot After</label>: + <span>{{extension.source.deleteFrequency.quantity}} {{extension.source.deleteFrequency.unit}}</span> + </div> + <div> + <label>Keep Last</label>: + <span>{{extension.source.retentionNumber}} extensions</span> + </div> + </div> + + <div> + <h4>Target</h4> + </div> + <div class="box"> + <h3>{{extension.target.cluster}}</h3> + <div> + <label class="locationBox">Target Directory</label>: + <span>{{extension.target.directoryPath}}</span> + </div> + <div> + <label>Delete Snapshot After</label>: + <span>{{extension.target.deleteFrequency.quantity}} {{extension.source.deleteFrequency.unit}}</span> + </div> + <div> + <label>Keep Last</label>: + <span>{{extension.target.retentionNumber}} extensions</span> + </div> + </div> + + <div> + <h4 class="lightSubtitle">Run On</h4> + <div ng-if="extension.runOn === 'source'"><span>{{extension.source.cluster}}</span></div> + <div ng-if="extension.runOn === 'target'"><span>{{extension.target.cluster}}</span></div> + </div> + + <hr class="col-xs-24" /> + + <div> + <h4 class="lightSubtitle">Run Duration</h4> + <div><label>Start on</label>: <span>{{extension.validity.start.date|date:'yyyy-MM-dd'}} {{extension.validity.start.time|date:'HH:mm'|date:'HH:mm'}}</span></div> + <div><label>End on</label>: <span>{{extension.validity.end.date|date:'yyyy-MM-dd'}} {{extension.validity.end.time|date:'HH:mm'}}</span></div> + </div> + + <div> + <h4 class="lightSubtitle">Frequency</h4> + <div><span>{{extension.frequency.quantity}} {{extension.frequency.unit}}</span></div> + </div> + + <div> + <h4 class="lightSubtitle">Timezone</h4> + <div><span>{{extension.validity.timezone}}</span></div> + </div> + + <div> + <h4 class="lightSubtitle">TDE Encryption</h4> + <span>{{extension.tdeEncryptionEnabled}}</span> + <div> + <div> + <h4 class="lightSubtitle">Retry</h4> + <label>Policy</label>: <span>{{extension.retry.policy}}</span> + <label>delay</label>: <span>{{extension.retry.delay.quantity}} {{extension.retry.delay.unit}}</span> + <label>Attempts</label>: <span>{{extension.retry.attempts}}</span> + </div> + <hr class="col-xs-24" /> + + <div> + <h4 class="lightSubtitle">Allocation</h4> + <div> + <label>Max Bandwidth</label>: + <span>{{extension.allocation.distcpMapBandwidth}} MB</span> + </div> + <div> + <label>Max Map Jobs</label>: + <span>{{extension.allocation.distcpMaxMaps}}</span> + </div> + </div> + + <div> + <h4 ng-if="extension.alerts.length > 0" class="lightSubtitle">Alerts</h4> + <span>{{ extension.alerts.join() }}</span> + </div> + + <hr class="col-xs-24" /> + <h4 class="lightSubtitle">Access Control List</h4> + <div> + <label>Owner</label>: <span>{{extension.ACL.owner}}</span> + <label>Group</label>: <span>{{extension.ACL.group}}</span> + <label>Permissions</label>: <span>{{extension.ACL.permission}}</span> + </div> +</div>
