http://git-wip-us.apache.org/repos/asf/falcon/blob/76dc2e18/falcon-ui/app/html/feed/feedFormSummaryStepTpl.html ---------------------------------------------------------------------- diff --git a/falcon-ui/app/html/feed/feedFormSummaryStepTpl.html b/falcon-ui/app/html/feed/feedFormSummaryStepTpl.html index a8a4844..a77d310 100644 --- a/falcon-ui/app/html/feed/feedFormSummaryStepTpl.html +++ b/falcon-ui/app/html/feed/feedFormSummaryStepTpl.html @@ -17,147 +17,208 @@ * limitations under the License. */ --> -<div class="row" id="feedFormSummaryStep"> +<div class="row feedSummaryRow" id="feedSummaryStep"> <h4 class="col-sm-24"> General </h4> - <div class="col-sm-12"> - <label>Name</label>: {{feed.name}} + <div class="col-sm-24"> + <label>Feed Name</label>: <span>{{feed.name}}</span> </div> - <div class="col-sm-12"> - <label>Description</label>: {{optional(feed.description)}} + <div class="col-sm-24"> + <label>Description</label>:<span> {{optional(feed.description)}}</span> </div> - - <h4 class="col-sm-24"> - Tags - </h4> <div class="col-sm-24"> + <label>Tags</label>: <div ng-repeat="tag in feed.tags | filter:{key: '!!'}"> - {{tag.key}} = {{tag.value}} + <span>{{tag.key}} = {{tag.value}}</span> </div> - <div ng-show="!hasTags()">No tags selected</div> + <div ng-show="!hasTags()"><span>No tags selected</span></div> </div> - <h4 class="col-sm-24"> - Groups - </h4> <div class="col-sm-24"> + <label>Feed Groups</label>: {{feed.groups}} - <div ng-show="!feed.groups">No groups selected</div> + <div ng-show="!feed.groups"><span>No groups selected</span></div> </div> <h4 class="col-sm-24"> Access Control List </h4> - <div class="col-sm-8"> - <label>Owner</label>: {{optional(feed.ACL.owner)}} - </div> - <div class="col-sm-8"> - <label>Group</label>: {{optional(feed.ACL.group)}} - </div> - <div class="col-sm-8"> - <label>Permissions</label>: {{optional(feed.ACL.permission)}} + <div class="col-sm-24"> + <label>Owner</label>: <span>{{optional(feed.ACL.owner)}}</span> + <label>Group</label>: <span>{{optional(feed.ACL.group)}}</span> + <label>Permissions</label>:<span> {{optional(feed.ACL.permission)}}</span> </div> <h4 class="col-sm-24"> - Schema + Feed Schema </h4> - <div class="col-sm-12"> - <label>Location</label>: {{optional(feed.schema.location)}} - </div> - <div class="col-sm-12"> - <label>Provider</label>: {{optional(feed.schema.provider)}} + <div class="col-sm-24"> + <label>Location</label>: <span>{{optional(feed.schema.location)}}</span> + <label>Provider</label>: <span>{{optional(feed.schema.provider)}}</span> </div> <h4 class="col-sm-24"> Properties </h4> - <div class="col-sm-8"> - <label>Frequency</label>: <frequency value="feed.frequency" prefix="Every"/> + <div class="col-sm-24"> + <label>Frequency</label>:<span> <frequency value="feed.frequency" prefix="Every"/></span> </div> - <div class="col-sm-8"> - <label>Late Arrival</label>: <frequency value="feed.lateArrival.cutOff" prefix="Up to"/> + <div class="col-sm-24"> + <label>Late Arrival</label>:<span> <frequency value="feed.lateArrival.cutOff" prefix="Up to"/></span> </div> - <div class="col-sm-8"> - <label>Availability Flag</label>: {{optional(feed.availabilityFlag)}} + <div class="col-sm-24"> + <label>Availability Flag</label>: <span>{{optional(feed.availabilityFlag)}}</span> </div> - <div class="col-sm-8" ng-repeat="property in feed.properties"> - <label>{{property.key}}</label>: + <div class="col-sm-24" ng-repeat="property in feed.properties"> + <label>{{feedPropertiesLabels[property.key]}}</label>: <span ng-if="property.key !== 'timeout'">{{optional(property.value)}}</span> - <frequency ng-if="property.key === 'timeout'" value="property.value" prefix="at"/> + <span><frequency ng-if="property.key === 'timeout'" value="property.value" prefix="at"/></span> + </div> + + <div class="col-sm-24" ng-repeat="property in feed.customProperties | filter: {key: '!!'}"> + <label>{{feedPropertiesLabels[property.key]}}</label>: <span>{{property.value}}</span> </div> - <div class="col-sm-8" ng-repeat="property in feed.customProperties | filter: {key: '!!'}"> - <label>{{property.key}}</label>: {{property.value}} + <h4 class="col-sm-24">Default Storage Type:</h4> + <div class="col-sm-24"> + <label class="light" ng-show="feed.storage.fileSystem.locations">File System</label> + <label class="light" ng-show="feed.storage.catalog.catalogTable.uri">Catalog Storage</label> + </div> + + <h4 class="col-sm-24">Default Location:</h4> + <div class="col-sm-24" ng-repeat="location in feed.storage.fileSystem.locations" + ng-show="feed.storage.fileSystem.locations"> + <label>{{capitalize(location.type)}}</label>: + <span>{{optional(location.path)}}</span> + </div> + + <div class="col-sm-24" ng-show="feed.storage.catalog.catalogTable.uri"> + <label>Table uri</label>:<span>{{optional(feed.storage.catalog.catalogTable.uri)}}</span> </div> - <h4 class="col-sm-8" > - Default Storage Type: + <h4 class="col-sm-24" ng-if="(feed.clusters | filter:{type:'source'} | filter:emptyClusterName).length > 0"> + Source Cluster(s) </h4> - <div class="col-sm-8 light" ng-show="feed.storage.fileSystem.active">File System</div> - <div class="col-sm-8 light" ng-show="feed.storage.catalog.active">Catalog Storage</div> + <div ng-repeat="cluster in feed.clusters | filter:{type:'source'} | filter:emptyClusterName"> + <div class="col-sm-24"> + <label>Name</label>: <span>{{cluster.name}}</span> + </div> - <h4 class="col-sm-24" >Default Location:</h4> + <div class="col-sm-24"> + <label>Start</label>: <span>{{getDateTimeString(cluster.validity.start.date,cluster.validity.start.time)}}</span> + </div> + <div class="col-sm-24"> + <label>End</label>: <span>{{getDateTimeString(cluster.validity.end.date,cluster.validity.end.time)}}</span> + </div> + <div class="col-sm-24"> + <label>Timezone</label>: <span>{{feed.timezone}}</span> + </div> + <div class="col-sm-24"> + <label>Retention</label>: <span><frequency value="cluster.retention" prefix=""/></span> + </div> - <div ng-repeat="location in feed.storage.fileSystem.locations" ng-show="feed.storage.fileSystem.active"> - <label class="col-sm-24" >{{capitalize(location.type)}}</label> - <div class="col-sm-24">{{optional(location.path)}}</div> + <label class="col-sm-24" ng-show="cluster.storage.fileSystem.locations">Location</label> + <div class="col-sm-24" ng-repeat="location in cluster.storage.fileSystem.locations" + ng-show="cluster.storage.fileSystem.locations"> + <label>{{capitalize(location.type)}}</label>: <span>{{optional(location.path)}}</span> + </div> + <div class="col-sm-24" ng-show="cluster.storage.catalog.catalogTable.uri"> + <label>Table uri</label>: <span>{{optional(cluster.storage.catalog.catalogTable.uri)}}</span> + </div> </div> - <div ng-show="feed.storage.catalog.active"> - <label class="col-sm-24" >Table uri</label> - <div class="col-sm-24">{{optional(feed.storage.catalog.catalogTable.uri)}}</div> - </div> + <h4 class="col-sm-24" + ng-if="feed.enableFeedReplication && (feed.clusters | filter:{type:'target'} | filter:emptyClusterName).length > 0"> + Target Cluster(s) + </h4> + <div ng-repeat="cluster in feed.clusters | filter:{type:'target'} | filter:emptyClusterName" ng-if="feed.enableFeedReplication"> + <div class="col-sm-24"> + <label>Name</label>: <span>{{cluster.name}}</span> + </div> - <div ng-repeat="cluster in feed.clusters" > - <h4 class="col-sm-24" >{{capitalize(cluster.type)}} Cluster</h4> + <div class="col-sm-24"> + <label>Start</label>: <span>{{getDateTimeString(cluster.validity.start.date,cluster.validity.start.time)}}</span> + </div> + <div class="col-sm-24"> + <label>End</label>: <span>{{getDateTimeString(cluster.validity.end.date,cluster.validity.end.time)}}</span> + </div> + <div class="col-sm-24"> + <label>Timezone</label>: <span>{{feed.timezone}}</span> + </div> + <div class="col-sm-24"> + <label>Retention</label>: <span><frequency value="cluster.retention" prefix=""/></span> + </div> - <div class="col-sm-12"> - <label>Name</label>: {{cluster.name}} + <label class="col-sm-24" ng-show="cluster.storage.fileSystem.locations">Location</label> + <div class="col-sm-24" ng-repeat="location in cluster.storage.fileSystem.locations" + ng-show="cluster.storage.fileSystem.locations"> + <label>{{capitalize(location.type)}}</label>: <span>{{optional(location.path)}}</span> + </div> + <div class="col-sm-24" ng-show="cluster.storage.catalog.catalogTable.uri"> + <label>Table uri</label>: <span>{{optional(cluster.storage.catalog.catalogTable.uri)}}</span> </div> - <div class="clearfix hidden-md"></div> + </div> - <div class="col-sm-12"> - <label>Start</label>: {{cluster.validity.start.date|date:'yyyy-MM-dd'}} {{cluster.validity.start.time|date:'HH:mm'}} + <h4 class="col-sm-24" ng-if="feed.dataTransferType === 'import' || feed.dataTransferType === 'export'"> + Datasource + </h4> + <div class="col-sm-24 plr0px" ng-if="feed.dataTransferType === 'import'"> + <div class="col-sm-24"> + <label>Datasource Name</label>: <span>{{feed.import.source.name}}</span> </div> - <div class="col-sm-12"> - <label>End</label>: {{cluster.validity.end.date|date:'yyyy-MM-dd'}} {{cluster.validity.end.time|date:'HH:mm'}} + <div class="col-sm-24"> + <label>Table Name</label>: <span>{{feed.import.source.tableName}}</span> </div> <div class="col-sm-24"> - <label>Timezone</label>: {{feed.timezone}} + <label>Extract Type</label>: <span>{{feed.import.source.extract.type}}</span> </div> <div class="col-sm-24"> - <label>Retention</label>: <frequency value="cluster.retention" prefix="Archive in"/> + <label>Merge Type</label>: <span>{{feed.import.source.extract.mergepolicy}}</span> + </div> + <div class="col-sm-24"> + <label>Columns</label>: + <span ng-if="feed.import.source.columnsType === 'include'">{{feed.import.source.includesCSV}}</span> + <span ng-if="feed.import.source.columnsType === 'exclude'">{{feed.import.source.excludesCSV}}</span> + <span ng-if="feed.import.source.columnsType === 'all'">All</span> </div> </div> - <div class="clearfix hidden-md"></div> - <h4 class="col-sm-24" >Location</h4> - <div ng-repeat="location in cluster.storage.fileSystem.locations" ng-show="cluster.storage.fileSystem"> - <label class="col-sm-24" >{{capitalize(location.type)}}</label> - <div class="col-sm-24">{{optional(location.path)}}</div> - </div> - <div ng-show="cluster.storage.catalog.active"> - <label class="col-sm-24" >Table uri</label> - <div class="col-sm-24">{{optional(cluster.storage.catalog.catalogTable.uri)}}</div> + + <div class="col-sm-24 plr0px" ng-if="feed.dataTransferType === 'export'"> + <div class="col-sm-24"> + <label>Datasource Name</label>: <span>{{feed.export.target.name}}</span> + </div> + <div class="col-sm-24"> + <label>Table Name</label>: <span>{{feed.export.target.tableName}}</span> + </div> + <div class="col-sm-24"> + <label>Load Method</label>: <span>{{feed.export.target.load.type}}</span> + </div> + <div class="col-sm-24"> + <label>Columns</label>: + <span ng-if="feed.export.target.columnsType === 'include'">{{feed.export.target.includesCSV}}</span> + <span ng-if="feed.export.target.columnsType === 'exclude'">{{feed.export.target.excludesCSV}}</span> + <span ng-if="feed.export.target.columnsType === 'all'">All</span> + </div> </div> </div> -<div class="row"> - <div class="col-xs-24 mt20"> - <button id="feed.backToStep4" class="btn prevBtn" type="button" - ng-click="goBack('forms.feed.clusters')" - ng-disabled="buttonSpinners.backShow"> - Previous <img src="css/img/ajax-loader.gif" ng-if="buttonSpinners.backShow" /> - </button> - <button id="feed.step5" class="btn nextBtn pull-right" ng-click="saveEntity()"> - Save <img src="css/img/ajax-loader.gif" ng-if="buttonSpinners.show" /> - </button> - <a class="pull-right" ui-sref="main"> - Cancel +<div class="col-xs-24 mt35 pb15px pl0px"> + <button id="feed.backToStep4" 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="feed.step5" class="btn nextBtn" ng-click="saveEntity()" focus-if> + SAVE <img src="css/img/ajax-loader.gif" ng-if="buttonSpinners.saveShow" /> + </button> </div> -</div> \ No newline at end of file +</div>
http://git-wip-us.apache.org/repos/asf/falcon/blob/76dc2e18/falcon-ui/app/html/feed/feedFormTpl.html ---------------------------------------------------------------------- diff --git a/falcon-ui/app/html/feed/feedFormTpl.html b/falcon-ui/app/html/feed/feedFormTpl.html index ee30d54..c1a2952 100644 --- a/falcon-ui/app/html/feed/feedFormTpl.html +++ b/falcon-ui/app/html/feed/feedFormTpl.html @@ -17,91 +17,82 @@ * limitations under the License. */ --> -<div class="col-xs-22 col-xs-offset-1 feedForm" id="feedFormTmpl"> +<div id="formBox" class="feedForm"> <div class="col-xs-24"> - <div class="row dt"> - - <h3 id="feed.title" class="col-xs-24"> - <span class="entypo download icon-lg"></span> New Feed - </h3> - - <div ng-class="{'col-xs-12' : propsOpen, 'col-xs-20' : !propsOpen}"> - <div class="detailsBox"> - <div class="feedProgressBox" ng-class="{ - general:isActive('forms.feed.general'), - properties:isActive('forms.feed.properties'), - location:isActive('forms.feed.location'), - clusters:isActive('forms.feed.clusters'), - summary:isActive('forms.feed.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>Location</h6> - </span> - <span> - <div class="fou">4<span class="entypo check"></span></div> - <h6>Clusters</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-disabled="invalidXml && xmlPreview.edit" ng-click="toggleclick()" >Preview XML</button> + </div> + <br/> + <div> + <div class="formBoxContainer detailsBox"> + <div class="row feedProgressBox" ng-class="{ + general:isActive('forms.feed.general'), + summary:isActive('forms.feed.summary') + }"> + <div class="progressBar col-xs-24"> + <div class="text-center fir" ng-class="{ + active:isActive('forms.feed.general'), + completed:isCompleted('forms.feed.general')}">General</div> + <div class="text-center fif" ng-class="{ + active:isActive('forms.feed.summary'), + completed:isCompleted('forms.feed.summary')}">Summary</div> </div> - - <div class="row"> - <div class="col-xs-offset-1 col-xs-22"> - <fieldset ng-disabled="!editXmlDisabled"> - <div ui-view class="formViewContainer"></div> - </fieldset> - </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 download icon-lg entypo-align-sub"></span> NEW FEED</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 dt"> - - <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 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="feed.editXML" - 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> + <button type="button" + id="revertXMLBtn" + class="btn btn-default btn-xs" + ng-if="invalidXml" + ng-click="revertXml()"> + <div>Revert</div> + </button> </div> - - <div ng-show="propsOpen" class="col-sm-24"> - <div class="row"> - <div class="col-sm-22 col-sm-offset-1"> - <textarea ng-model="prettyXml" elastic class="form-control prettyXml" ng-disabled="editXmlDisabled"></textarea> - </div> - </div> - </div> + </div> + <div class="col-sm-24 showValidationStyle"> + <textarea ng-model="prettyXml" + elastic + class="form-control" + ng-disabled="editXmlDisabled" + ng-class="{fakeInvalid:invalidXml}"> + </textarea> + <!--{{xmlEditValidationError}}--> + </div> </div> </div> - </div> - </div> </div> </div> http://git-wip-us.apache.org/repos/asf/falcon/blob/76dc2e18/falcon-ui/app/html/feed/feedSummary.html ---------------------------------------------------------------------- diff --git a/falcon-ui/app/html/feed/feedSummary.html b/falcon-ui/app/html/feed/feedSummary.html index 760e810..1f0dcc6 100644 --- a/falcon-ui/app/html/feed/feedSummary.html +++ b/falcon-ui/app/html/feed/feedSummary.html @@ -34,9 +34,9 @@ </div> <div class="row"> - <h5 class="col-sm-24"> + <label class="col-sm-24"> Tags - </h5> + </label> </div> <div class="row"> @@ -48,14 +48,8 @@ </div> <div class="row"> - <h5 class="col-sm-24"> - Groups - </h5> - </div> - - <div class="row"> <div class="col-sm-24"> - {{feed.groups}} + <label>Groups</label>: {{feed.groups}} </div> </div> @@ -114,13 +108,13 @@ <div class="row"> <div class="col-sm-8" ng-repeat="property in feed.properties"> - <label>{{property.key}}</label>: + <label>{{feedPropertiesLabels[property.key]}}</label>: <span ng-if="property.key !== 'timeout'">{{property.value}}</span> <frequency ng-if="property.key === 'timeout'" value="property.value" prefix="at"/> </div> <div class="col-sm-8" ng-repeat="property in feed.customProperties | filter: {key: '!!'}"> - <label>{{property.key}}</label>: {{property.value}} + <label>{{feedPropertiesLabels[property.key]}}</label>: {{property.value}} </div> <h5 class="col-xs-24"> @@ -129,31 +123,29 @@ </div> <div class="row"> - <div class="col-sm-8 light" ng-show="feed.storage.fileSystem.active">File System</div> - <div class="col-sm-8 light" ng-show="feed.storage.catalog.active">Catalog Storage</div> + <div class="col-sm-8 light" ng-show="feed.storage.fileSystem.locations">File System</div> + <div class="col-sm-8 light" ng-show="feed.storage.catalog.catalogTable.uri">Catalog Storage</div> </div> <div class="row"> <h5 class="col-sm-24">Default Location:</h5> </div> - - <div ng-repeat="location in feed.storage.fileSystem.locations" ng-show="feed.storage.fileSystem.active"> - <div class="row"> - <label class="col-sm-24">{{capitalize(location.type)}}</label> - </div> - + <div ng-repeat="location in feed.storage.fileSystem.locations" ng-show="feed.storage.fileSystem.locations"> <div class="row"> - <div class="col-sm-24">{{location.path}}</div> + <div class="col-sm-24"> + <label>{{capitalize(location.type)}}</label>: + <span>{{location.path}}</span> + </div> </div> </div> - <div ng-show="feed.storage.catalog.active"> + <div ng-show="feed.storage.catalog.catalogTable.uri"> <div class="row"> - <label class="col-sm-24">Table uri</label> - </div> - <div class="row"> - <div class="col-sm-24">{{feed.storage.catalog.catalogTable.uri}}</div> + <div class="col-sm-24"> + <label>Table uri</label> + <span>{{feed.storage.catalog.catalogTable.uri}}</span> + </div> </div> </div> @@ -186,29 +178,74 @@ <div class="row"> <div class="col-sm-24"> <label>Retention</label>: - <frequency value="cluster.retention" prefix="Archive in"/> + <frequency value="cluster.retention" prefix=""/> </div> </div> - </div> - <div class="clearfix hidden-md"></div> - <div class="row"> - <h5 class="col-sm-24">Location</h5> - </div> - <div ng-repeat="location in cluster.storage.fileSystem.locations" ng-show="cluster.storage.fileSystem"> <div class="row"> - <label class="col-sm-24">{{capitalize(location.type)}}</label> + <label class="col-sm-24">Location</label> </div> - <div class="row"> - <div class="col-sm-24">{{location.path}}</div> + + <div ng-repeat="location in cluster.storage.fileSystem.locations" ng-show="cluster.storage.fileSystem.locations"> + <div class="row"> + <div class="col-sm-24"> + <label>{{capitalize(location.type)}}</label> + <span>{{location.path}}</span> + </div> + </div> + </div> + <div ng-show="cluster.storage.catalog.catalogTable.uri"> + <div class="row"> + <div class="col-sm-24"> + <label>Table uri</label> + <span>{{cluster.storage.catalog.catalogTable.uri}}</span> + </div> + </div> </div> </div> - <div ng-show="cluster.storage.catalog.active"> - <div class="row"> - <label class="col-sm-24">Table uri</label> + + <div class="row"> + <h4 class="col-sm-24" ng-if="feed.import || feed.export"> + Datasource + </h4> + <div class="col-sm-24 plr0px" ng-if="feed.import"> + <div class="col-sm-24"> + <label>Datasource Name</label>: <span>{{feed.import.source.name}}</span> + </div> + <div class="col-sm-24"> + <label>Table Name</label>: <span>{{feed.import.source.tableName}}</span> + </div> + <div class="col-sm-24"> + <label>Extract Type</label>: <span>{{feed.import.source.extract.type}}</span> + </div> + <div class="col-sm-24"> + <label>Merge Type</label>: <span>{{feed.import.source.extract.mergepolicy}}</span> + </div> + <div class="col-sm-24"> + <label>Columns</label>: + <span ng-if="feed.import.source.includesCSV">{{feed.import.source.includesCSV}}</span> + <span ng-if="feed.import.source.excludesCSV">{{feed.import.source.excludesCSV}}</span> + <span ng-if="!feed.import.source.includesCSV && !feed.import.source.excludesCSV">All</span> + </div> </div> - <div class="row"> - <div class="col-sm-24">{{cluster.storage.catalog.catalogTable.uri}}</div> + + <div class="col-sm-24 plr0px" ng-if="feed.export"> + <div class="col-sm-24"> + <label>Datasource Name</label>: <span>{{feed.export.target.name}}</span> + </div> + <div class="col-sm-24"> + <label>Table Name</label>: <span>{{feed.export.target.tableName}}</span> + </div> + <div class="col-sm-24"> + <label>Load Method</label>: <span>{{feed.export.target.load.type}}</span> + </div> + <div class="col-sm-24"> + <label>Columns</label>: + <span ng-if="feed.export.target.includesCSV">{{feed.export.target.includesCSV}}</span> + <span ng-if="feed.export.target.excludesCSV">{{feed.export.target.excludesCSV}}</span> + <span ng-if="!feed.export.target.includesCSV && !feed.export.target.excludesCSV">All</span> + </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/formsTpl.html ---------------------------------------------------------------------- diff --git a/falcon-ui/app/html/formsTpl.html b/falcon-ui/app/html/formsTpl.html index b8d50fb..bd63470 100644 --- a/falcon-ui/app/html/formsTpl.html +++ b/falcon-ui/app/html/formsTpl.html @@ -18,6 +18,6 @@ */ --> <div class="col-sm-24 formPage" ng-class="{showValidationStyle:validations.displayValidations.show}"> - <div ui-view> + <div class="col-sm-offset-2 col-sm-20" ui-view> </div> </div> http://git-wip-us.apache.org/repos/asf/falcon/blob/76dc2e18/falcon-ui/app/html/instanceDetails.html ---------------------------------------------------------------------- diff --git a/falcon-ui/app/html/instanceDetails.html b/falcon-ui/app/html/instanceDetails.html index b67c041..e22c717 100644 --- a/falcon-ui/app/html/instanceDetails.html +++ b/falcon-ui/app/html/instanceDetails.html @@ -17,29 +17,29 @@ * limitations under the License. */ --> -<div class="container" id="instanceDetails"> +<div class="container instanceDetails pt15px"> <div class="row"> <div class="col-sm-24"> <div class="detailsBox"> <div class="row"> <div class="col-sm-9"> - <h3 class="instance-title"> - <a href="javascript:void(0);" ng-click="backToEntity()">{{ instance.name }}</a> | {{ instance.instance }} + <h3 class="instance-title pl0px"> + <a href="javascript:void(0);" ng-click="backToEntity()">{{ instance.name }}</a> | <span>{{ instance.instance }}</span> </h3> </div> <div class="col-sm-3 instance-status"> <span class="text-success">STARTED</span><br/> - {{ instance.startTime | date :'MM/dd/yyyy HH:mm' }} + <span>{{ instance.startTime | date : dateFormat }}</span> </div> <div class="col-sm-5 border-left"> <h4 class="instance-title"> Status: <span ng-class="{ - 'blink-success': instance.status == 'RUNNING', - 'text-success': instance.status == 'SUCCEEDED', - 'blink-warning': instance.status == 'WAITING' || instance.status == 'UNKNOWN', - 'blink-danger': instance.status == 'SUSPENDED', - 'text-danger': instance.status == 'FAILED' || instance.status == 'KILLED', + 'blink-success': instance.status == 'RUNNING', + 'text-success': instance.status == 'SUCCEEDED', + 'blink-warning': instance.status == 'WAITING' || instance.status == 'UNKNOWN', + 'blink-danger': instance.status == 'SUSPENDED', + 'text-danger': instance.status == 'FAILED' || instance.status == 'KILLED', }">{{ instance.status }}</span> </h4> </div> @@ -49,11 +49,11 @@ <span class="entypo play"></span> <div>Resume</div> </div> <div class="btn btn-big btn-xs buttons-to-show" ng-click="reRunInstance()" - ng-disabled="!(instance.status === 'KILLED' || instance.status === 'SUCCEEDED' || instance.status === 'FAILED')"> - <span class="entypo play"></span> <div>Rerun</div> - </div> + ng-disabled="!(instance.status === 'KILLED' || instance.status === 'SUCCEEDED' || instance.status === 'FAILED')"> + <span class="entypo play"></span> <div>Rerun</div> + </div> <div class="btn btn-big btn-xs buttons-to-show" ng-click="suspendInstance()" ng-disabled="!(instance.status === 'RUNNING')"> - <span class="entypo paus"></span> <div>Suspend</div> + <span class="entypo paus"></span> <div>Pause</div> </div> <div class="btn btn-big btn-xs buttons-to-show" ng-click="killInstance()" ng-disabled="!(instance.status === 'SUSPENDED' || instance.status === 'RUNNING')"> <span class="entypo stop"></span> <div>Kill</div> http://git-wip-us.apache.org/repos/asf/falcon/blob/76dc2e18/falcon-ui/app/html/mainTpl.html ---------------------------------------------------------------------- diff --git a/falcon-ui/app/html/mainTpl.html b/falcon-ui/app/html/mainTpl.html index 890463f..963bfb0 100644 --- a/falcon-ui/app/html/mainTpl.html +++ b/falcon-ui/app/html/mainTpl.html @@ -17,59 +17,124 @@ * limitations under the License. */ --> +<div ng-show="!hasClusters" class="no-entity"> + <span> + No Cluster Entity Defined. Please contact your Administrator or perform the steps described in + <a target="_blank" href='https://docs.hortonworks.com/HDPDocuments/HDP2/HDP-2.4.2/bk_data_governance/content/using_gui_to_define_data_pipelines.html'> + Falcon Documentation</a> to create a Cluster. + </span> +</div> +<div class="col-sm-24"> + <div class="row searchResultContainer" ng-show="searchList.length > 0"> + <div class="col-sm-offset-2 col-sm-20 dashboardBox"> + <entities-search-list input="searchList" entity-details="entityDetails" clone="cloneEntity" tags="tags" + remove="deleteEntity" edit="editEntity" schedule="scheduleEntity" suspend="suspendEntity" + resume="resumeEntity" focus-search="focusSearch" pages="pages" go-page="goPage"/> + </div> + </div> -<div class="col-sm-offset-1 col-sm-22"> +</div> - <div class="row searchBoxContainer" id="searchBoxContainer"> - <div class="col-sm-4"></div> - <div class="col-sm-16"> +<!--<div class="col-xs-24" ng-hide="searchList.length > 0">--> + <!--<div class="row" ng-controller="chartCtrl">--> + <!--<div class="col-xs-20 chartCol">--> + <!--<div class="chartMenuBox">--> + <!--<div class="entityBox">--> + <!--<h5> Entity </h5>--> + <!--<div class="entityTypeButtons">--> + <!--<button class="btn"--> + <!--ng-click="chartOptions.entity = 'feed'; requestNewData()"--> + <!--ng-class="{active: chartOptions.entity === 'feed'}">--> + <!--Feeds--> + <!--</button>--> + <!--<button class="btn"--> + <!--ng-click="chartOptions.entity = 'process'; requestNewData()"--> + <!--ng-class="{active: chartOptions.entity === 'process'}">--> + <!--Processes--> + <!--</button>--> + <!--<button class="btn"--> + <!--ng-click="chartOptions.entity = 'dataset'; requestNewData()"--> + <!--ng-class="{active: chartOptions.entity === 'dataset'}">--> + <!--Dataset--> + <!--</button>--> + <!--</div>--> + <!--</div>--> + <!--<div class="timeBox">--> + <!--<h5>Time</h5>--> + <!--<label>--> + <!--<input type="radio" ng-model="chartOptions.mode" value="hourly" ng-change="requestNewData()">--> + <!--24 Hs--> + <!--</label>--> + <!--<label>--> + <!--<input type="radio" ng-model="chartOptions.mode" value="daily" ng-change="requestNewData()">--> + <!--14 Days--> + <!--</label>--> + <!--</div>--> + <!--<div class="dayBox">--> + <!--<h5>Day</h5>--> + <!--<input type="text"--> + <!--ng-change="requestNewData()"--> + <!--class="form-control dateInput"--> + <!--placeholder="mm/dd/yyyy"--> + <!--datepicker-popup="{{dateFormat}}"--> + <!--ng-model="chartOptions.day"--> + <!--is-open="opened"--> + <!--ng-click="openDatePicker($event)"--> + <!--ng-required="true"--> + <!--simple-date />--> + <!--<span class="entypo calendar dateInputIcon"--> + <!--ng-click="openDatePicker($event)">--> + <!--</span>--> + <!--</div>--> + <!--</div>--> + <!--<chart class="chart"--> + <!--input="graphData"--> + <!--t="30"--> + <!--mode="chartOptions.mode"--> + <!--ng-class="{daily: chartOptions.mode === 'daily'}"--> + <!--details="details">--> + <!--</chart>--> - <img src="css/img/ajax-loader.gif" class="glyphicon search-loading-icon" ng-show="loading"/> - <i class="glyphicon glyphicon-search search-icon" ng-hide="loading"></i> + <!--</div>--> + <!--<div class="col-xs-4 chartSideBar" ng-show="chartSidebarModel">--> - <tags-input ng-model="tags" min-length="1" add-on-space="true" add-from-autocomplete-only="true" - on-tag-added="displayResults()" on-tag-removed="displayResults()" placeholder="Search"> - <auto-complete source="loadTags($query)" min-length="0"></auto-complete> - </tags-input> + <!--<h3> {{ chartSidebarDate.firstLeg }} </h3>--> + <!--<h4> {{ chartSidebarDate.secondLeg }}--> + <!--<span ng-if="chartOptions.mode === 'hourly'"> {{ chartSidebarDate.timeLeg }} </span>--> + <!--</h4>--> - <i id="nsPopover" class="glyphicon glyphicon-question-sign" ng-class="tags.length > 0 ? 'question-icon' : 'remove-icon'" - ns-popover - ns-popover-template="menu" - ns-popover-trigger="click" - ns-popover-theme="ns-popover-tooltip-theme" - ns-popover-timeout="5" - ns-popover-placement="bottom|right"></i> - <script type="text/ng-template" id="menu"> - <div class="triangle"></div> - <!--<div class="ns-popover-tooltip">--> - <!--<h5>Hey there! Want some search tips?</h5>--> - <!--The <strong>first word</strong> you type will be taken as the <strong>Name</strong> of the entity.--> - <!--<br/>--> - <!--You can search <strong>*</strong> for getting all the entities.--> - <!--<br/>--> - <!--The <strong>second and following</strong> words will be taken as <strong> Tags</strong>.--> - <!--<br/>--> - <!--For filtering by type, write <strong>type=feed|process|mirror</strong>--> - <!--</div>--> - <div class="ns-popover-tooltip"> - <h5>Hey there! Want some search tips?</h5> - You can type <strong>*</strong> and select <strong>Name: *</strong> from the autocomplete for getting all the entities. - </div> - </script> - <i class="glyphicon glyphicon-remove remove-icon" ng-if="tags.length > 0" ng-click="clearTags()"></i> + <!--<hr />--> - </div> - <div class="col-sm-4"></div> - </div> + <!--<h5 class="text-success"> Succeed </h5>--> + <!--<table class="table">--> + <!--<tr ng-repeat="item in chartSidebarModel.topSuccessfulEntities | orderBy:'-numberOfSuccessfulEntities'">--> + <!--<td> {{item.name}} </td>--> + <!--<td><span> {{item.numberOfSuccessfulEntities}} </span></td>--> + <!--</tr>--> + <!--</table>--> - <div class="col-sm-24 dashboardBox" ng-show="searchList.length > 0" id="dashboardBox"> - <div class="row"> - <div class="col-sm-24"> - <entities-search-list input="searchList" entity-details="entityDetails" clone="cloneEntity" tags="tags" - remove="deleteEntity" edit="editEntity" schedule="scheduleEntity" suspend="suspendEntity" - resume="resumeEntity" focus-search="focusSearch" pages="pages" go-page="goPage"/> - </div> - </div> - </div> + <!--<hr />--> + + <!--<h5 class="text-danger"> Failed </h5>--> + <!--<table class="table">--> + <!--<tr ng-repeat="item in chartSidebarModel.topFailedEntities | orderBy:'-numberOfFailedEntities'">--> + <!--<td> {{item.name}} </td>--> + <!--<td><span> {{item.numberOfFailedEntities}} </span></td>--> + <!--</tr>--> + <!--</table>--> + + <!--<hr />--> + + <!--<h5> Data Copied </h5>--> + <!--<table class="table">--> + <!--<tr ng-repeat="item in chartSidebarModel.topDataCopiedEntities | orderBy:'-dataCopied'">--> + <!--<td> {{item.name}} </td>--> + <!--<td><span> {{item.dataCopied}} </span></td>--> + <!--</tr>--> + <!--</table>--> + + <!--</div>--> + + <!--</div>--> +<!--</div>--> -</div> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/falcon/blob/76dc2e18/falcon-ui/app/html/process/processFormAdvancedStepTpl.html ---------------------------------------------------------------------- diff --git a/falcon-ui/app/html/process/processFormAdvancedStepTpl.html b/falcon-ui/app/html/process/processFormAdvancedStepTpl.html new file mode 100644 index 0000000..ce5119d --- /dev/null +++ b/falcon-ui/app/html/process/processFormAdvancedStepTpl.html @@ -0,0 +1,183 @@ +<!-- +/** + * 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="processForm" class="mt10" novalidate id="processFormAdvancedStep"> + <div class="col-xs-24"><label>Retry Policy</label></div> + <div class="col-xs-24 plr0px"> + <div class="col-xs-4 plr0px"> + <div class="col-xs-24"> + <label class="light" tooltip="process.properties.retryPolicy" tooltip-position="up"> + Type + </label> + </div> + <div class="col-xs-24"> + <select ng-model="process.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> + <div class="col-xs-offset-1 col-xs-5 plr0px"> + <div class="col-xs-24"> + <label class="light">Delay Up to</label> + </div> + <div class="col-xs-24 inlineInputsGroup"> + <input type="text" class="form-control" + ng-model="process.retry.delay.quantity" validation-message="{{validations.messages.number}}" + id="delayQuantity" ng-keydown="validations.acceptOnlyNumber($event)" + ng-disabled = "process.retry.policy === 'final'" + ng-required="true" + ng-pattern="validations.patterns.twoDigits"/> + + <select ng-model="process.retry.delay.unit" ng-required="true" ng-disabled = "process.retry.policy === 'final'" validation-message="{{validations.messages.option}}"> + <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> + <div class="col-xs-4 plr0px"> + <div class="col-xs-24"> + <label class="light">Attempts</label> + </div> + <div class="col-xs-24"> + <input type="text" class="form-control" validation-message="{{validations.messages.number}}" + ng-model="process.retry.attempts" ng-keydown="validations.acceptOnlyNumber($event)" + id="attemptsField" + ng-required="true" + ng-disabled = "process.retry.policy === 'final'" + ng-pattern="validations.patterns.twoDigits"/> + </div> + </div> + </div> + + <div class="col-xs-24"><label>Performance & Ordering</label></div> + <div class="col-xs-24 plr0px"> + <div class="col-xs-4 plr0px"> + <div class="col-xs-24"> + <label class="light">Max Parallel Instances</label> + </div> + <div class="col-xs-24"> + <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] track by $index">{{value}}</option> + </select> + </div> + </div> + <div class="col-xs-offset-1 col-xs-4 plr0px"> + <div class="col-xs-24"> + <label class="light" tooltip="process.properties.order">Order</label> + </div> + <div class="col-xs-24"> + <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'] track by $index">{{value}}</option> + </select> + </div> + </div> + </div> + + <div class="col-xs-24"> + <label>Properties</label> + </div> + <div ng-repeat="property in process.properties track by $index" class="col-xs-24 plr0px"> + <div class="col-xs-6 dynamic-table-spacer"> + <input type="text" class="form-control" ng-model="property.name" + ng-pattern="validations.patterns.propertyName" + validation-optional-message="{{validations.messages.name}}" + ng-disabled="xmlPreview.edit" + ng-required="property.value" placeholder="name" /> + </div> + <div class="col-xs-6 dynamic-table-spacer"> + <input type="text" class="form-control" ng-model="property.value" + validation-optional-message="{{validations.messages.value}}" + ng-disabled="xmlPreview.edit" + ng-required="property.name" placeholder="value" /> + </div> + <div class="dynamic-table-spacer"> + <button type="button" class="btn btn-default btn-xs" ng-click="removeProperty($index)" ng-if="!$first || !$last" + ng-disabled="xmlPreview.edit"> + <span class="entypo minus"></span> delete + </button> + <button type="button" class="btn btn-default btn-xs" ng-click="addProperty()" + ng-disabled="xmlPreview.edit" ng-if="$last"> + <span class="entypo plus"></span> ADD + </button> + </div> + </div> + + + <div class="col-xs-24"><label class="mt15">Access Control List</label></div> + <div class="col-xs-24 plr0px"> + <div class="col-xs-4"> + <label class="light">Owner<mandatory-field></mandatory-field></label> + <input type="text" + name="aclOwnerInput" + ng-model="process.ACL.owner" + ng-pattern="validations.patterns.unixId" + ng-required="true" + class="form-control" + validation-message="{{validations.messages.acl.owner}}"/> + </div> + <div class="col-xs-4"> + <label class="light">Group<mandatory-field></mandatory-field></label> + <input type="text" + name="aclGroupInput" + ng-model="process.ACL.group" + ng-pattern="validations.patterns.unixId" + ng-required="true" + class="form-control" + validation-message="{{validations.messages.acl.group}}" /> + </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="process.ACL.permission"></acl-permissions> + </div> + </div> + </div> + + <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 id="nextButton" class="btn nextBtn" + ng-disabled="buttonSpinners.show" + ng-click="goNext(processForm.$invalid)" scroll-to-error> + NEXT <img src="css/img/ajax-loader.gif" ng-if="buttonSpinners.show" /> + </button> + <button class="btn advancedSaveBtn" + ng-disabled="processForm.$invalid || buttonSpinners.saveShow" + ng-click="saveEntity()" 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/process/processFormClustersStepTpl.html ---------------------------------------------------------------------- diff --git a/falcon-ui/app/html/process/processFormClustersStepTpl.html b/falcon-ui/app/html/process/processFormClustersStepTpl.html index 21bf4bf..8f58504 100644 --- a/falcon-ui/app/html/process/processFormClustersStepTpl.html +++ b/falcon-ui/app/html/process/processFormClustersStepTpl.html @@ -17,95 +17,91 @@ * limitations under the License. */ --> -<form name="processForm" class="mt10" novalidate id="processFormClusterStep"> - <div class="col-xs-offset-1 col-xs-22"> +<form name="processForm" novalidate> + <div class="col-xs-24"> <div ng-repeat="cluster in process.clusters" class="row"> <div class="col-xs-24 detailsBox processCluster"> - - <h5>Cluster</h5> - <div class="row"> - <div class="col-xs-24"> - <label class="light">Name</label> - <select ng-model="cluster.name" ng-class="{firstSelectClusterStep: $index === 0}" + <div class="col-xs-24"><label class="mt15" tooltip="process.cluster">CLUSTER</label></div> + <div class="col-xs-24"> + <label class="light">Cluster Name<mandatory-field></mandatory-field></label> + <select ng-model="cluster.name" ng-class="{firstSelectClusterStep: $index === 0}" ng-required="true" class="form-control padding0" validation-message="{{validations.messages.cluster}}"> - <option value="" disabled selected style='display:none;'>-Select cluster-</option> - <option ng-repeat="clusterItem in clusterList">{{clusterItem.name}}</option> - </select> - </div> + <option value="" disabled selected style='display:none;'>-Select cluster-</option> + <option ng-repeat="clusterItem in clusterList">{{clusterItem.name}}</option> + </select> </div> - <div class="clearfix"></div> - <label class="col-xs-24"> Validity </label> - <div class="col-xs-24 validityBox"> - <div class="startDateBox"> - <label>Start + <div class="col-xs-24"><label class="mt15">VALIDITY</label></div> + <div class="col-xs-24"><label class="mt15 light">Time Zone : <span>{{process.timezone}}</span></label></div> + <div class="col-xs-24 validityBox plr0px"> + <div class="col-xs-24 plr0px"> + <div class="col-xs-4 startDateBox"> + <label class="light">Start<mandatory-field></mandatory-field></label> <input type="text" name="startDateInput" class="form-control dateInput" - placeholder="mm/dd/yyyy" + placeholder="{{dateFormat | lowercase}}" datepicker-popup="{{dateFormat}}" ng-model="cluster.validity.start.date" is-open="cluster.validity.start.opened" ng-click="openDatePicker($event, cluster.validity.start)" + ng-change="constructDate()" ng-required="true" simple-date> - </label> - <label class="col-xs-24 custom-danger validationMessageGral" - ng-if="!cluster.validity.start.date"> - {{validations.messages.date.empty}} - </label> - </div> - <div class="startTimeBox"> - <label>Time - <timepicker + + </div> + <div class="col-xs-6 startTimeBox"> + <label class="light">Time<mandatory-field></mandatory-field></label> + <timepicker ng-change="constructDate()" ng-model="cluster.validity.start.time" hour-step="1" minute-step="1" show-meridian="true"> </timepicker> - </label> + </div> </div> - <div class="endDateBox"> - <label>End + <label class="col-xs-24 custom-danger validationMessageGral" + ng-if="!cluster.validity.start.date"> + {{validations.messages.date.empty}} + </label> + <div class="col-xs-24 plr0px"> + <div class="col-xs-4 endDateBox"> + <label class="light">End<mandatory-field></mandatory-field></label> <input type="text" name="endDateInput" class="form-control dateInput" - placeholder="mm/dd/yyyy" + placeholder="{{dateFormat | lowercase}}" datepicker-popup="{{dateFormat}}" ng-model="cluster.validity.end.date" is-open="cluster.validity.end.opened" ng-click="openDatePicker($event, cluster.validity.end)" + ng-change="constructDate()" ng-required="true" min-date="cluster.validity.start.date" simple-date> - </label> - <label class="col-xs-24 custom-danger validationMessageGral" - ng-if="!cluster.validity.end.date"> - {{validations.messages.date.empty}} - </label> - </div> - <div class="endTimeBox"> - <label>Time - <timepicker + </div> + <div class="col-xs-6 endTimeBox"> + <label class="light">Time<mandatory-field></mandatory-field></label> + <timepicker ng-change="constructDate()" ng-model="cluster.validity.end.time" hour-step="1" minute-step="1" show-meridian="true"> </timepicker> - </label> + </div> </div> - - <div class="col-xs-24 mt10"> + <label class="col-xs-24 custom-danger validationMessageGral" + ng-if="!cluster.validity.end.date"> + {{validations.messages.date.empty}} + </label> + </div> + <div class="col-xs-24 mt10"> <button type="button" class="btn btn-default pull-right btn-xs" ng-click="removeCluster($index)" ng-if="!$first"> <span class="entypo minus"></span> delete </button> - </div> </div> - - - </div> </div> </div> @@ -114,20 +110,23 @@ <span class="entypo plus"></span> add cluster </button> </div> - <div class="col-xs-24 mt20"> + + <div class="col-xs-24 pb15px mt35"> <button class="btn prevBtn" type="button" - ng-click="goBack('forms.process.properties')" + ng-click="goBack()" ng-disabled="buttonSpinners.backShow"> - Previous <img src="css/img/ajax-loader.gif" ng-if="buttonSpinners.backShow" /> - </button> - <button class="btn nextBtn pull-right" - ng-disabled="buttonSpinners.show" - ng-click="goNext(processForm.$invalid, 'forms.process.io')" > - Next <img src="css/img/ajax-loader.gif" ng-if="buttonSpinners.show" /> + PREVIOUS <img src="css/img/ajax-loader.gif" ng-if="buttonSpinners.backShow" /> </button> - <a class="pull-right" ui-sref="main"> - Cancel - </a> + <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)" 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/processFormGeneralStepTpl.html ---------------------------------------------------------------------- diff --git a/falcon-ui/app/html/process/processFormGeneralStepTpl.html b/falcon-ui/app/html/process/processFormGeneralStepTpl.html index cc21854..6665bb7 100644 --- a/falcon-ui/app/html/process/processFormGeneralStepTpl.html +++ b/falcon-ui/app/html/process/processFormGeneralStepTpl.html @@ -19,152 +19,522 @@ --> <form name="processForm" class="mt10" novalidate id="processFormGeneralStep"> + <div class="col-xs-24"> + <label class="light" tooltip="process.name">Process Name<mandatory-field></mandatory-field></label> + </div> + + <div class="col-xs-6"> + <input type="text" class="form-control" ng-keydown="validations.acceptNoSpaces($event)" + check-name="{type:'process', check:!editingMode}" ng-class="{fakeInvalid:!validations.nameAvailable}" + ng-disabled="editingMode" id="entityNameField" ng-model="process.name" + ng-required="true" ng-maxlength="100" ng-pattern="validations.patterns.name"/> + </div> + + <div class="col-xs-24"> + <label class="light">Tags</label> + </div> + + <div id="tagsSection" class="col-xs-12"> + <div ng-repeat="tag in process.tags track by $index"> + <div class="row dynamic-table-spacer"> + <div class="col-xs-8"> + <input type="text" class="form-control" ng-model="tag.key" placeholder="key" + validation-optional-message="{{validations.messages.key}}" + ng-pattern="validations.patterns.alpha" ng-required="tag.value"/> + </div> + <div class="col-xs-8"> + <input type="text" class="form-control" ng-model="tag.value" placeholder="value" + validation-optional-message="{{validations.messages.value}}" + ng-pattern="validations.patterns.alpha" ng-required="tag.key"/> + </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 + </button> + </div> + </div> + </div> + </div> + + <div class="col-xs-24"> + <label>Details</label> + </div> + + <div class="col-xs-5 plr0px"> + <div class="col-xs-24"> + <label class="light" tooltip="process.workflow.engine">Engine<mandatory-field></mandatory-field></label> + <select ng-model="process.workflow.engine" + class="form-control padding0" + ng-required="true" + validation-message="{{validations.messages.engine}}"> + <option value="" disabled selected style='display:none;'>-Select engine-</option> + <option value="spark">Spark</option> + <option value="oozie">Oozie</option> + <option value="pig">Pig</option> + <option value="hive">Hive</option> + </select> + </div> + + <div class="col-xs-24" ng-show="process.workflow.engine !== 'spark'"> + <label class="light" tooltip="process.workflow.name">Workflow Name<mandatory-field></mandatory-field></label> + <input type="text" class="form-control" + id="workflowNameField" + ng-model="process.workflow.name" + ng-required="process.workflow.engine !== 'spark'" + ng-maxlength="100" + ng-pattern="validations.patterns.workflowName" + validation-optional-message="{{validations.messages.name}}" /> + </div> + + <div class="col-xs-24"> + <label class="light" tooltip="process.workflow.path">Workflow Path<mandatory-field></mandatory-field></label> + <input type="text" class="form-control" + id="pathField" + ng-model="process.workflow.path" + ng-required="true" + ng-maxlength="200" + validation-message="{{validations.messages.path}}" + ng-pattern="validations.patterns.path"/> + </div> + + <div class="col-xs-24"> + <label class="light">Cluster<mandatory-field></mandatory-field></label> + <div ng-repeat="cluster in process.clusters track by $index"> + <select ng-model="cluster.name" + ng-required="true" + ng-change="getSourceDefinition(cluster.name)" + class="form-control padding0" + validation-message="{{validations.messages.cluster}}"> + <option value="" disabled selected style='display:none;'>-Select cluster-</option> + <option ng-repeat="clusterItem in clusterList track by $index">{{clusterItem.name}}</option> + </select> + </div> + </div> + </div> + <div class="col-xs-offset-1 col-xs-6 plr0px" ng-show="process.workflow.engine==='spark'"> + <div class="col-xs-24"> + <label class="light" tooltip="process.workflow.spark.name">Name<mandatory-field></mandatory-field></label> + <input type="text" class="form-control" + ng-model="process.workflow.spark.name" + ng-required="process.workflow.engine==='spark'" + ng-maxlength="100" + ng-pattern="validations.patterns.name" + validation-optional-message="{{validations.messages.name}}" /> + </div> + + <div class="col-xs-24"> + <label class="light" tooltip="process.workflow.spark.application">Application<mandatory-field></mandatory-field></label> + <input type="text" class="form-control" + ng-model="process.workflow.spark.jar" + ng-required="process.workflow.engine==='spark'" /> + </div> + + <div class="col-xs-24"> + <label class="light" tooltip="process.workflow.spark.class">Main Class</label> + <input type="text" class="form-control" + ng-model="process.workflow.spark.class" + ng-required="process.workflow.engine==='spark' && !isPython" ng-disabled='isPython'/> + </div> + + <div class="col-xs-12"> + <label class="light" tooltip="process.workflow.spark.master">Runs On</label> + <select ng-model="process.workflow.spark.master" + class="form-control padding0" + ng-required="process.workflow.engine==='spark'"> + <option value="" disabled selected style='display:none;'>-Select Runs On-</option> + <option value="yarn">Yarn</option> + <option value="local">Local</option> + </select> + </div> + + <div class="col-xs-12 plr0px" ng-if="process.workflow.spark.master === 'yarn'"> + <div class="col-xs-24"> + <label class="light" tooltip="process.workflow.spark.mode">Mode<mandatory-field></mandatory-field></label> + </div> + <div class="col-xs-24 pt3px"> + <input type="radio" name="sparkMode" value="cluster" ng-model="process.workflow.spark.mode" /> + Cluster + <input type="radio" name="sparkMode" value="client" ng-model="process.workflow.spark.mode" /> + Client + </div> + </div> + <div class="col-xs-24"> - <label class="light">Name</label> - <input type="text" class="form-control" ng-keydown="validations.acceptNoSpaces($event)" - check-name="{type:'process', check:cloningMode}" ng-class="{fakeInvalid:!validations.nameAvailable}" - ng-disabled="!cloningMode" id="entityNameField" ng-model="process.name" - ng-required="true" ng-maxlength="100" ng-pattern="validations.patterns.name"/> + <label class="light">Spark Options</label> + <input type="text" class="form-control" ng-model="process.workflow.spark.sparkOptions"/> </div> <div class="col-xs-24"> - <label class="light">Tags</label> + <label class="light">Spark Arguments</label> + <input type="text" class="form-control" ng-model="process.workflow.spark.arg"/> </div> + </div> + + <div class="col-xs-offset-1 col-xs-5 plr0px"> + <div><label>INPUT(S)</label></div> - <div id="tagsSection" class="col-xs-24"> - <div ng-repeat="tag in process.tags"> - <div class="row dynamic-table-spacer"> - <div class="col-xs-10"> - <input type="text" class="form-control" ng-model="tag.key" placeholder="key" - validation-optional-message="{{validations.messages.key}}" - ng-pattern="validations.patterns.alpha" ng-required="tag.value"/> + <div ng-repeat="input in process.inputs track by $index"> + <div class="col-xs-24 detailsBox processCluster"> + <div class="row"> + <div class="col-xs-24"> + <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="39" + ng-pattern="validations.patterns.inputName"/> </div> - <div class="col-xs-11"> - <input type="text" class="form-control" placeholder="value" - validation-optional-message="{{validations.messages.value}}" - ng-model="tag.value" ng-pattern="validations.patterns.alpha" ng-required="tag.key"/> + </div> + + <div class="row"> + <div class="col-xs-24"> + <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}}"> + <option value="" disabled selected style='display:none;'>-Select feed-</option> + <option ng-repeat="feedItem in feedsList track by $index">{{feedItem.name}}</option> + </select> </div> - <div class="col-xs-3"> - <button type="button" class="btn btn-default btn-xs" ng-click="removeTag($index)" ng-if="$index>0"> + </div> + + <div><label>INSTANCE</label></div> + <div class="row"> + <div class="col-xs-12"> + <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="39"/> + </div> + <div class="col-xs-12"> + <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" + ng-required="true" + ng-maxlength="100" + on-blur="validateStartEndDate"/> + <label ng-show="invalidEndDate" class="custom-danger nameValidationMessage">End should be equal or greater than Start</label> + </div> + </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> - <div class="col-xs-24 mt10 mb10"> - <button type="button" class="btn btn-default btn-xs" ng-click="addTag()"> - <span class="entypo plus"></span> add tag - </button> + + <button type="button" class="btn btn-default btn-xs mt10 mb10 addInputButton" ng-click="addInput()"> + <span class="entypo plus"></span> ADD + </button> + </div> + + <div class="col-xs-offset-1 col-xs-5 plr0px"> + <div><label>OUTPUT(S)</label></div> + <div ng-repeat="output in process.outputs track by $index"> + <div class="col-xs-24 detailsBox processCluster"> + <div class="row"> + <div class="col-xs-24"> + <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="39" + ng-pattern="validations.patterns.id"/> + </div> + </div> + <div class="row"> + <div class="col-xs-24"> + <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> + <option ng-repeat="feedItem in feedsList track by $index">{{feedItem.name}}</option> + </select> + </div> + </div> + <div><label class="mt15">INSTANCE</label></div> + <div class="row"> + <div class="col-xs-24"> + <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="39"/> + </div> + </div> + <div class="row mt10"> + <button type="button" class="btn btn-default pull-right btn-xs" ng-click="removeOutput($index)"> + <span class="entypo minus"></span> delete + </button> + </div> + </div> </div> - <h4 class="col-xs-24">Workflow</h4> + <button type="button" class="btn btn-default btn-xs mb10 mt10" ng-click="addOutput()"> + <span class="entypo plus"></span> ADD + </button> + </div> <div class="col-xs-24"> - <div class="light">Name</div> - <input type="text" class="form-control" validation-optional-message="{{validations.messages.name}}" - id="workflowNameField" - ng-model="process.workflow.name" - ng-maxlength="100" - ng-pattern="validations.patterns.name"/> + <label>Run Duration<mandatory-field></mandatory-field></label> </div> - - <div id="engineSection" class="col-xs-24"> - <label class="light">Engine</label> - <div class="row"> - <div class="col-xs-4"> - <input - type="radio" id="oozieEngineRadio" - ng-change="selectWorkflow()" - ng-model="process.workflow.engine" - value="oozie" /> Oozie + <div class="col-xs-24" ng-repeat="cluster in process.clusters track by $index" class="validityBox"> + <div class="col-xs-24 plr0px validityBox"> + <div class="col-xs-24 plr0px"> + <label class="light">Start</label> </div> - <div class="col-xs-4"> - <input type="radio" id="pigEngineRadio" - ng-change="selectWorkflow()" - ng-model="process.workflow.engine" - value="pig" /> Pig + <div class="plr0px col-xs-2 startDateBox"> + <input type="text" + name="startDateInput" + class="form-control dateInput" + placeholder="{{dateFormat | lowercase}}" + ng-model="cluster.validity.start.date" + simple-date-picker /> </div> - <div class="col-xs-4"> - <input type="radio" id="hiveEngineRadio" - ng-change="selectWorkflow()" - ng-model="process.workflow.engine" - value="hive" /> Hive + <div class="col-xs-3 startTimeBox"> + <timepicker ng-change="constructDate()" + ng-model="cluster.validity.start.time" + hour-step="1" + minute-step="1" + show-meridian="true"> + </timepicker> + </div> + <label class="col-xs-24 custom-danger validationMessageGral" + ng-if="!cluster.validity.start.date"> + {{validations.messages.date.empty}} + </label> + </div> + <div class="col-xs-24 plr0px validityBox"> + <div class="col-xs-24 plr0px"> + <label class="light">End</label> + </div> + <div class="plr0px col-xs-2 endDateBox"> + <input type="text" + name="startDateInput" + class="form-control dateInput" + placeholder="{{dateFormat | lowercase}}" + ng-model="cluster.validity.end.date" + simple-date-picker /> </div> + <div class="col-xs-3 endTimeBox"> + <timepicker ng-change="constructDate()" + ng-model="cluster.validity.end.time" + hour-step="1" + minute-step="1" + show-meridian="true"> + </timepicker> + </div> + <label class="col-xs-24 custom-danger validationMessageGral" + ng-if="!cluster.validity.end.date"> + {{validations.messages.date.empty}} + </label> + </div> + </div> - <select id="engineVersionField" - ng-model="process.workflow.version" - ng-show="process.workflow.engine"> + <div class="col-xs-24"> + <label>Frequency</label> + </div> - <option value="" disabled selected style='display:none;'>-Select {{process.workflow.engine}} version-</option> + <div class="col-xs-12 plr0px"> + <div class="col-xs-24"> + <label class="light">Repeat Every<mandatory-field></mandatory-field></label> + </div> + <div class="col-xs-24 inlineInputsGroup"> + <input type="text" class="form-control" validation-message="{{validations.messages.number}}" name="frequencyQuantity" + ng-model="process.frequency.quantity" ng-keydown="validations.acceptOnlyNumber($event)" + ng-keyup="checkMininumFrequency(process.frequency.quantity,process.frequency.unit, processForm.frequencyQuantity)" + id="frequencyQuantity" + ng-required="true" + ng-pattern="validations.patterns.twoDigits"/> - <option ng-repeat="version in versions" - id="{{process.workflow.engine}}Version{{$index}}" - value="{{version}}" - ng-selected="process.workflow.version === version"> - {{version}} - </option> + <select ng-model="process.frequency.unit" ng-required="true" + ng-change="checkMininumFrequency(process.frequency.quantity,process.frequency.unit, processForm.frequencyQuantity)" + validation-message="{{validations.messages.number}}"> + <option selected value="minutes">minutes</option> + <option value="hours">hours</option> + <option value="days">days</option> + <option value="months">months</option> </select> - + <div class="col-xs-24 custom-danger" ng-if="!isFrequencyValid">{{validations.messages.frequency.minimum}}</div> + </div> + <div class="col-xs-24"> + <label class="light" tooltip="process.properties.timezone">Timezone<mandatory-field></mandatory-field></label> + </div> + <div class="col-xs-18"> + <time-zone-select ng-model="process.timezone" id="timeZoneSelect" required="true"> + </time-zone-select> </div> </div> - <div class="col-xs-24"> - <label class="light">Path</label> - <input type="text" class="form-control" - id="pathField" - ng-model="process.workflow.path" - ng-required="true" - ng-maxlength="200" - validation-optional-message="{{validations.messages.path}}" - ng-pattern="validations.patterns.osPath"/> - </div> - - <div class="aclBox col-xs-24"> - <h4>Access Control List</h4> - <div> - <label>Owner - <input type="text" - name="aclOwnerInput" - ng-model="process.ACL.owner" - ng-pattern="validations.patterns.unixId" - ng-required="true" - class="form-control" - validation-message="{{validations.messages.acl.owner}}"/> - </label> + + <div class="col-xs-24 advancedOption" ng-click="expandOptions = !expandOptions" id="processAdvancedOption"> + <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>Retry Policy</label></div> + <div class="col-xs-24 plr0px"> + <div class="col-xs-4 plr0px"> + <div class="col-xs-24"> + <label class="light" tooltip="process.properties.retryPolicy" tooltip-position="up"> + Type + </label> + </div> + <div class="col-xs-24"> + <select ng-model="process.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> + <div class="col-xs-offset-1 col-xs-5 plr0px"> + <div class="col-xs-24"> + <label class="light">Delay Up to</label> + </div> + <div class="col-xs-24 inlineInputsGroup"> + <input type="text" class="form-control" + ng-model="process.retry.delay.quantity" validation-message="{{validations.messages.number}}" + id="delayQuantity" ng-keydown="validations.acceptOnlyNumber($event)" + ng-disabled = "process.retry.policy === 'final'" + ng-required="true" + ng-pattern="validations.patterns.twoDigits"/> + + <select ng-model="process.retry.delay.unit" ng-required="true" ng-disabled = "process.retry.policy === 'final'" validation-message="{{validations.messages.option}}"> + <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> + <div class="col-xs-4 plr0px"> + <div class="col-xs-24"> + <label class="light">Attempts</label> + </div> + <div class="col-xs-24"> + <input type="text" class="form-control" validation-message="{{validations.messages.number}}" + ng-model="process.retry.attempts" ng-keydown="validations.acceptOnlyNumber($event)" + id="attemptsField" + ng-required="true" + ng-disabled = "process.retry.policy === 'final'" + ng-pattern="validations.patterns.twoDigits"/> + </div> + </div> </div> - <div> - <label>Group - <input type="text" - name="aclGroupInput" - ng-model="process.ACL.group" - ng-pattern="validations.patterns.unixId" - ng-required="true" - class="form-control" - validation-message="{{validations.messages.acl.group}}" /> - </label> + + <div class="col-xs-24"><label>Performance & Ordering</label></div> + <div class="col-xs-24 plr0px"> + <div class="col-xs-4 plr0px"> + <div class="col-xs-24"> + <label class="light">Max Parallel Instances</label> + </div> + <div class="col-xs-24"> + <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] track by $index">{{value}}</option> + </select> + </div> + </div> + <div class="col-xs-offset-1 col-xs-4 plr0px"> + <div class="col-xs-24"> + <label class="light" tooltip="process.properties.order">Order</label> + </div> + <div class="col-xs-24"> + <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'] track by $index">{{value}}</option> + </select> + </div> + </div> </div> - <div> - <label>Permissions - <input type="text" - name="aclPermissionsInput" - ng-model="process.ACL.permission" - ng-pattern="validations.patterns.unixPermissions" - ng-required="true" - class="form-control" - validation-message="{{validations.messages.acl.permission}}" /> - </label> + + <div class="col-xs-24"> + <label>Properties</label> + </div> + <div ng-repeat="property in process.properties track by $index" class="col-xs-24 plr0px"> + <div class="col-xs-6 dynamic-table-spacer"> + <input type="text" class="form-control" ng-model="property.name" + ng-pattern="validations.patterns.propertyName" + validation-optional-message="{{validations.messages.name}}" + ng-disabled="xmlPreview.edit" + ng-required="property.value" placeholder="name" /> + </div> + <div class="col-xs-6 dynamic-table-spacer"> + <input type="text" class="form-control" ng-model="property.value" + validation-optional-message="{{validations.messages.value}}" + ng-disabled="xmlPreview.edit" + ng-required="property.name" placeholder="value" /> + </div> + <div class="dynamic-table-spacer"> + <button type="button" class="btn btn-default btn-xs" ng-click="removeProperty($index)" ng-if="!$first || !$last" + ng-disabled="xmlPreview.edit"> + <span class="entypo minus"></span> delete + </button> + <button type="button" class="btn btn-default btn-xs" ng-click="addProperty()" + ng-disabled="xmlPreview.edit" ng-if="$last"> + <span class="entypo plus"></span> ADD + </button> + </div> + </div> + + + <div class="col-xs-24"><label class="mt15">Access Control List</label></div> + <div class="col-xs-24 plr0px"> + <div class="col-xs-4"> + <label class="light">Owner<mandatory-field></mandatory-field></label> + <input type="text" + name="aclOwnerInput" + ng-model="process.ACL.owner" + ng-pattern="validations.patterns.unixId" + ng-required="true" + class="form-control" + validation-message="{{validations.messages.acl.owner}}"/> + </div> + <div class="col-xs-4"> + <label class="light">Group<mandatory-field></mandatory-field></label> + <input type="text" + name="aclGroupInput" + ng-model="process.ACL.group" + ng-pattern="validations.patterns.unixId" + ng-required="true" + class="form-control" + validation-message="{{validations.messages.acl.group}}" /> + </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="process.ACL.permission"></acl-permissions> + </div> + </div> </div> </div> - <div class="col-xs-24 mt20"> - <button id="nextButton" class="btn nextBtn pull-right" - ng-disabled="buttonSpinners.show" - ng-click="goNext(processForm.$invalid, 'forms.process.properties')" > - Next <img src="css/img/ajax-loader.gif" ng-if="buttonSpinners.show" /> - </button> - <a class="pull-right" ui-sref="main"> - Cancel - </a> + <div class="col-xs-24 pb15px mt35"> + <div class="pull-right"> + <a class="btn cnclBtn" ui-sref="main"> + CANCEL + </a> + <button id="nextButton" class="btn nextBtn" + ng-disabled="buttonSpinners.show" + ng-click="goNext(processForm.$invalid)" scroll-to-error> + NEXT <img src="css/img/ajax-loader.gif" ng-if="buttonSpinners.show" /> + </button> + <button class="btn nextBtn" + ng-disabled="processForm.$invalid || buttonSpinners.saveShow" + ng-click="saveEntity(processForm.$invalid)" scroll-to-error> + SAVE <img src="css/img/ajax-loader.gif" ng-if="buttonSpinners.saveShow" /> + </button> + </div> </div> -</form> \ No newline at end of file +</form>
