diff options
Diffstat (limited to 'catalog-ui/app/scripts/directives/utils')
23 files changed, 1599 insertions, 0 deletions
diff --git a/catalog-ui/app/scripts/directives/utils/expand-collapse-menu-box/expand-collaps-menu-box.ts b/catalog-ui/app/scripts/directives/utils/expand-collapse-menu-box/expand-collaps-menu-box.ts new file mode 100644 index 0000000000..9756ff9e49 --- /dev/null +++ b/catalog-ui/app/scripts/directives/utils/expand-collapse-menu-box/expand-collaps-menu-box.ts @@ -0,0 +1,66 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ +/// <reference path="../../../references"/> +module Sdc.Directives { + 'use strict'; + export interface IExpandCollapseMenuBoxDirectiveScope extends ng.IScope { + menuItemsGroup: Utils.MenuItemGroup; + menuTitle: string; + parentScope: ng.IScope; + onMenuItemClick(menuItem: Utils.MenuItem):void; + } + + export class ExpandCollapseMenuBoxDirective implements ng.IDirective { + + constructor(private $templateCache:ng.ITemplateCacheService) { + } + + scope = { + menuTitle: '@', + menuItemsGroup: '=', + parentScope: '=' + }; + + public replace = false; + public restrict = 'AE'; + public transclude = true; + + template = ():string => { + return this.$templateCache.get('/app/scripts/directives/utils/expand-collapse-menu-box/expand-collapse-menu-box.html'); + }; + + link = (scope:IExpandCollapseMenuBoxDirectiveScope, $elem:any) => { + scope.onMenuItemClick = (menuItem: Utils.MenuItem):void => { + let onSuccess = ():void => { + scope.menuItemsGroup.selectedIndex = scope.menuItemsGroup.menuItems.indexOf(menuItem); + }; + let onFailed = ():void => {}; + scope.parentScope[menuItem.action](menuItem.state).then(onSuccess, onFailed); + } + }; + + public static factory = ($templateCache:ng.ITemplateCacheService)=> { + return new ExpandCollapseMenuBoxDirective($templateCache); + }; + + } + + ExpandCollapseMenuBoxDirective.factory.$inject = ['$templateCache']; +} diff --git a/catalog-ui/app/scripts/directives/utils/expand-collapse-menu-box/expand-collapse-menu-box.html b/catalog-ui/app/scripts/directives/utils/expand-collapse-menu-box/expand-collapse-menu-box.html new file mode 100644 index 0000000000..bbd7e59e7c --- /dev/null +++ b/catalog-ui/app/scripts/directives/utils/expand-collapse-menu-box/expand-collapse-menu-box.html @@ -0,0 +1,15 @@ +<div class="expand-collapse-menu-box"> + <expand-collapse expanded-selector=".w-sdc-designer-sidebar-section-content" class="expand-collapse-menu-box-title"> + <div class="expand-collapse-menu-box-title-icon"></div> + <span class="w-sdc-designer-sidebar-section-title-text" data-ng-bind="menuTitle" tooltips tooltip-content="{{menuTitle}}"></span> + </expand-collapse> + + <div class="w-sdc-designer-sidebar-section-content" > + <div class="i-sdc-designer-sidebar-section-content-item expand-collapse-menu-box-item" + ng-class="{'selected': $index == menuItemsGroup.selectedIndex}" ng-repeat="(key, menuItem) in menuItemsGroup.menuItems track by $index"> + <div class="expand-collapse-menu-box-item-text" ng-click="onMenuItemClick(menuItem)" ng-class="{'disabled': menuItem.isDisabled }" data-tests-id="{{menuItem.text}}step" >{{menuItem.text}}</div> + </div> + </div> + +</div> + diff --git a/catalog-ui/app/scripts/directives/utils/expand-collapse-menu-box/expand-collapse-menu-box.less b/catalog-ui/app/scripts/directives/utils/expand-collapse-menu-box/expand-collapse-menu-box.less new file mode 100644 index 0000000000..d8ceeaea71 --- /dev/null +++ b/catalog-ui/app/scripts/directives/utils/expand-collapse-menu-box/expand-collapse-menu-box.less @@ -0,0 +1,55 @@ +.expand-collapse-menu-box { + line-height: 20px; + padding: 13px 0px 5px 10px; + background-color: @func_color_r; + margin: 3px 3px 5px 0px; + + + .expand-collapse-menu-box-title { + .f-type._18_m; + color: @main_color_m; + font-weight: bold; + .hand; + .w-sdc-designer-sidebar-section-title-text{ + max-width: 185px; + overflow: hidden; + text-overflow: ellipsis; + display: inline-block; + white-space: nowrap; + } + + &.expanded { + .expand-collapse-menu-box-title-icon { + transform: rotate(180deg); + } + } + } + .expand-collapse-menu-box-title-icon { + .hand; + .sprite-new; + .arrow-up; + margin-right: 6px; + transition: .3s all; + position: relative; + + } + .w-sdc-designer-sidebar-section-content { + overflow: hidden; + padding-top: 13px; + .expand-collapse-menu-box-item { + .hand; + padding-left: 14px; + margin: 0px 0px 10px 10px; + font-family: @font-omnes-medium; + color: @main_color_m; + + line-height: 18px; + &.selected { + padding-left: 10px; + font-weight: bold; + border-left: 4px solid @main_color_a; + } + + } + } +} diff --git a/catalog-ui/app/scripts/directives/utils/expand-collapse/expand-collapse.html b/catalog-ui/app/scripts/directives/utils/expand-collapse/expand-collapse.html new file mode 100644 index 0000000000..a2358ea2b7 --- /dev/null +++ b/catalog-ui/app/scripts/directives/utils/expand-collapse/expand-collapse.html @@ -0,0 +1 @@ +<ng-transclude></ng-transclude> diff --git a/catalog-ui/app/scripts/directives/utils/expand-collapse/expand-collapse.less b/catalog-ui/app/scripts/directives/utils/expand-collapse/expand-collapse.less new file mode 100644 index 0000000000..d0d8fa3251 --- /dev/null +++ b/catalog-ui/app/scripts/directives/utils/expand-collapse/expand-collapse.less @@ -0,0 +1,10 @@ +.ellipsis-directive-more-less { + .a_9; + .bold; + .hand; + float: right; + margin-right: 10px; + line-height: 23px; + text-decoration: underline; + text-align: left; +} diff --git a/catalog-ui/app/scripts/directives/utils/expand-collapse/expand-collapse.ts b/catalog-ui/app/scripts/directives/utils/expand-collapse/expand-collapse.ts new file mode 100644 index 0000000000..b294da6c13 --- /dev/null +++ b/catalog-ui/app/scripts/directives/utils/expand-collapse/expand-collapse.ts @@ -0,0 +1,136 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ +/// <reference path="../../../references"/> +module Sdc.Directives { + 'use strict'; + export interface IExpandCollapseScope extends ng.IScope { + toggle(): void; + collapsed: boolean; + expandedSelector: string; + content:string; + isCloseOnInit:boolean; + loadDataFunction: Function; + isLoadingData: boolean; + } + + export class ExpandCollapseDirective implements ng.IDirective { + + constructor(private $templateCache:ng.ITemplateCacheService) { + } + + scope = { + expandedSelector: '@', + loadDataFunction: '&?', + isCloseOnInit: '=?' + }; + + public replace = false; + public restrict = 'AE'; + public transclude = true; + + template = ():string => { + return this.$templateCache.get('/app/scripts/directives/utils/expand-collapse/expand-collapse.html'); + }; + + link = (scope:IExpandCollapseScope, $elem:any) => { + scope.collapsed = false; + scope.isLoadingData = false; + $elem.addClass('expanded'); + + + if(scope.isCloseOnInit) { + window.setTimeout(function () { + toggle(); + },0); + } + + $elem.click(function(){ + toggle(); + }); + + let expand = ():void => { + $elem.addClass('expanded'); + scope.collapsed = false; + + let element = $(scope.expandedSelector)[0]; + let prevWidth = element.style.height; + element.style.height = 'auto'; + let endWidth = getComputedStyle(element).height; + element.style.height = prevWidth; + element.offsetHeight; // force repaint + element.style.transition = 'height .3s ease-in-out'; + element.style.height = endWidth; + element.hidden = false; + element.addEventListener('transitionend', function transitionEnd(event) { + if (event['propertyName'] == 'height') { + element.style.transition = ''; + element.style.height = 'auto'; + element.removeEventListener('transitionend', transitionEnd, false); + } + }, false) + }; + + let collapse = ():void => { + $elem.removeClass('expanded'); + scope.collapsed = true; + + let element = $(scope.expandedSelector)[0]; + element.style.height = getComputedStyle(element).height; + element.style.transition = 'height .5s ease-in-out'; + element.offsetHeight; // force repaint + element.style.height = '0px'; + element.hidden = true; + }; + + let toggle = ():void => { + if (scope.collapsed === true){ + if(scope.loadDataFunction) { + scope.isLoadingData = true; + let onSuccess = () => { + window.setTimeout(function () { + expand(); + scope.isLoadingData = false; + },0); + }; + scope.loadDataFunction().then(onSuccess); + } + else { + if(scope.isLoadingData === false) { + expand(); + } + } + + } else { + if(scope.isLoadingData === false) { + collapse(); + } + } + } + + }; + + public static factory = ($templateCache:ng.ITemplateCacheService)=> { + return new ExpandCollapseDirective($templateCache); + }; + + } + + ExpandCollapseDirective.factory.$inject = ['$templateCache']; +} diff --git a/catalog-ui/app/scripts/directives/utils/page-selector/page-selector.html b/catalog-ui/app/scripts/directives/utils/page-selector/page-selector.html new file mode 100644 index 0000000000..4fbea447e2 --- /dev/null +++ b/catalog-ui/app/scripts/directives/utils/page-selector/page-selector.html @@ -0,0 +1,9 @@ +<div class="i-sdc-left-sidebar-page-nav"> + <ul data-ng-class="{'expanded': expanded===true}"> + <li data-ng-repeat="item in list | filter:exceptSelectedComparator" + data-ng-click="expanded=false" + class="sidebar-page-nav-item" + ui-sref="{{item.url}}">{{item.name}}</li> + </ul> + <div class="sidebar-page-nav-item-selected" data-ng-click="openCollapse()">{{selected}}<span data-ng-class="{'expanded': expanded===true}"></span></div> +</div> diff --git a/catalog-ui/app/scripts/directives/utils/page-selector/page-selector.less b/catalog-ui/app/scripts/directives/utils/page-selector/page-selector.less new file mode 100644 index 0000000000..da70218263 --- /dev/null +++ b/catalog-ui/app/scripts/directives/utils/page-selector/page-selector.less @@ -0,0 +1,51 @@ +.i-sdc-left-sidebar-page-nav { + + height: 64px; + + .sidebar-page-nav-item-selected, + .sidebar-page-nav-item { + .i_11; + background-color: #e0e5e9; + width: 100%; + height: 64px; + border-bottom: solid 1px #cccccc; + line-height: 64px; + text-align: center; + cursor: pointer; + vertical-align: middle; + list-style: none; + padding: 0; + margin: 0; + } + + .sidebar-page-nav-item-selected { + z-index: 1010; + position: absolute; + top: 0px; + } + + .sidebar-page-nav-item-selected span { + .sprite; + .sprite.table-arrow; + position: absolute; + top: 28px; + margin-left: 10px; + + &.expanded { + .sprite; + .sprite.table-arrow.opened; + top: 30px; + } + } + + ul { + position: absolute; + top: 0px; + padding: 0; + width: 100%; + z-index: 99; + visibility: hidden; //Need this and not display none, so I can use the function: getComputedStyle + .box-shadow(0px 4px 2px -2px rgba(0, 0, 0, 0.36)); + } + +} diff --git a/catalog-ui/app/scripts/directives/utils/page-selector/page-selector.ts b/catalog-ui/app/scripts/directives/utils/page-selector/page-selector.ts new file mode 100644 index 0000000000..c185fe1c15 --- /dev/null +++ b/catalog-ui/app/scripts/directives/utils/page-selector/page-selector.ts @@ -0,0 +1,106 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ +/// <reference path="../../../references"/> +module Sdc.Directives { + 'use strict'; + + class ListItem { + name; + url; + } + + export interface IPageSelectorScope extends ng.IScope { + selected:string; + expanded: boolean; + list:Array<ListItem>; + exceptSelectedComparator(actual, expected):boolean; + openCollapse(); + } + + export class PageSelectorDirective implements ng.IDirective { + + constructor(private $templateCache:ng.ITemplateCacheService) { + } + + scope = { + list: '=', + selected: '@', + }; + + public replace = true; + public restrict = 'E'; + public transclude = false; + + private ulElement:HTMLElement; + private itemHeight:number = 64; + + private getUlHeight = ():number => { + let tmp:string = getComputedStyle(this.ulElement).height; + //console.log("tmp: " + tmp); + let ulHeight:number = parseInt(tmp.substr(0,tmp.length-2)); + //console.log("ulHeight: " + ulHeight); + return ulHeight; + }; + + template = ():string => { + return this.$templateCache.get('/app/scripts/directives/utils/page-selector/page-selector.html'); + }; + + link = (scope:IPageSelectorScope, $elem:any) => { + scope.expanded=false; + + window.setTimeout(() => { + this.ulElement = angular.element(".i-sdc-left-sidebar-page-nav ul")[0]; + console.log("this.ulElement: " + this.ulElement); + console.log("this.itemHeight: " + this.itemHeight); + this.ulElement.style.top = (this.itemHeight - this.getUlHeight() - 5) + 'px'; + this.ulElement.style.visibility = 'visible'; + },10); + + this.ulElement = angular.element(".i-sdc-left-sidebar-page-nav ul")[0]; + + scope.exceptSelectedComparator = (actual) => { + if (actual.name===scope.selected) { + return false; + } + return true; + }; + + scope.openCollapse = ():void => { + scope.expanded=!scope.expanded; + if (scope.expanded===true) { + this.ulElement.style.transition = 'top 0.4s ease-out'; + this.ulElement.style.top = this.itemHeight + 'px'; + } else { + this.ulElement.style.transition = 'top 0.4s ease-in'; + this.ulElement.style.top = (this.itemHeight - this.getUlHeight() - 5) + 'px'; + } + }; + + }; + + public static factory = ($templateCache:ng.ITemplateCacheService)=> { + return new PageSelectorDirective($templateCache); + }; + + } + + PageSelectorDirective.factory.$inject = ['$templateCache']; +} diff --git a/catalog-ui/app/scripts/directives/utils/sdc-keyboard-events/sdc-keyboard-events.ts b/catalog-ui/app/scripts/directives/utils/sdc-keyboard-events/sdc-keyboard-events.ts new file mode 100644 index 0000000000..9e61caa812 --- /dev/null +++ b/catalog-ui/app/scripts/directives/utils/sdc-keyboard-events/sdc-keyboard-events.ts @@ -0,0 +1,106 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ +/// <reference path="../../../references"/> +module Sdc.Directives { + 'use strict'; + + export interface ISdcKeyboardEventsScope extends ng.IScope { + keyEnter:Function; + keyShift:Function; + keyCtrl:Function; + keyEscape:Function; + keySpace:Function; + } + + export class SdcKeyboardEventsDirective implements ng.IDirective { + + constructor() { + } + + scope = { + keyEnter: '=', + keyShift: '=', + keyCtrl: '=', + keyEscape: '=', + keySpace: '=' + }; + + public replace = false; + public restrict = 'A'; + public transclude = false; + + link = (scope:ISdcKeyboardEventsScope, element:ng.IAugmentedJQuery, attrs:angular.IAttributes) => { + + element.bind("keydown keypress", function (event) { + //console.log(event.which); + switch (event.which) { + case 13: // enter key + scope.$apply(function (){ + if (scope.keyEnter) { + scope.keyEnter(); + event.preventDefault(); + } + }); + break; + case 16: // shift key + scope.$apply(function (){ + if (scope.keyShift) { + scope.keyShift(); + event.preventDefault(); + } + }); + break; + case 17: // ctrl key + scope.$apply(function (){ + if (scope.keyCtrl) { + scope.keyCtrl(); + event.preventDefault(); + } + }); + break; + case 27: // escape key + scope.$apply(function (){ + if (scope.keyEscape) { + scope.keyEscape(); + event.preventDefault(); + } + }); + break; + case 32: // space key + scope.$apply(function (){ + if (scope.keySpace) { + scope.keySpace(); + event.preventDefault(); + } + }); + break; + } + }); + + }; + + public static factory = ()=> { + return new SdcKeyboardEventsDirective(); + }; + + } + + SdcKeyboardEventsDirective.factory.$inject = []; +} diff --git a/catalog-ui/app/scripts/directives/utils/sdc-tags/sdc-tags.html b/catalog-ui/app/scripts/directives/utils/sdc-tags/sdc-tags.html new file mode 100644 index 0000000000..fb1ada69c3 --- /dev/null +++ b/catalog-ui/app/scripts/directives/utils/sdc-tags/sdc-tags.html @@ -0,0 +1,27 @@ +<div class="tags-box" > + <input type="text" + name="{{elementName}}" + class="new-tag-input" + data-ng-class="{'view-mode':sdcDisabled}" + data-ng-change="validateName()" + data-ng-model="newTag" + data-ng-maxlength="50" + data-ng-pattern="pattern" + data-tests-id="i-sdc-tag-input" + maxlength="50" + sdc-keyboard-events + key-enter="addTag" + + /> + <perfect-scrollbar class="perfect-scrollbar tags-wrapper" data-ng-class="{'view-mode':sdcDisabled}" include-padding="true"> + <div data-tests-id="i-sdc-tags-wrapper" > + <div class="group-tag" data-ng-show="specialTag"> + <sdc-tag data-hide-tooltip="true" data-hide-delete="true" + data-tag-data="{tag: specialTag, id: specialTag }"></sdc-tag> + </div> + <div class="group-tag" ng-repeat="tag in tags track by $index"> + <sdc-tag ng-if="tag != specialTag" data-on-delete="deleteTag(tag)" sdc-disable="sdcDisabled" data-hide-delete="sdcDisabled" data-hide-tooltip="true" data-tag-data="{tag: tag, id: tag }"></sdc-tag> + </div> + </div> + </perfect-scrollbar> +</div> diff --git a/catalog-ui/app/scripts/directives/utils/sdc-tags/sdc-tags.less b/catalog-ui/app/scripts/directives/utils/sdc-tags/sdc-tags.less new file mode 100644 index 0000000000..942196e663 --- /dev/null +++ b/catalog-ui/app/scripts/directives/utils/sdc-tags/sdc-tags.less @@ -0,0 +1,61 @@ +.tags-box { + + height: 297px; + .bg_c; + + .perfect-scrollbar { + height: 265px; + } + + .new-tag-input { + display: block; + + -webkit-border-bottom-left-radius: 0 !important; + -moz-border-radius-bottomleft: 0 !important; + -khtml-border-bottom-left-radius: 0 !important; + border-bottom-left-radius: 0 !important; + + -webkit-border-bottom-right-radius: 0 !important; + -moz-border-radius-bottomright: 0 !important; + -khtml-border-bottom-right-radius: 0 !important; + border-bottom-right-radius: 0 !important; + + border: solid 1px #d8d8d8; + width: 100%; + height: 30px; + line-height: 30px; + padding: 2px 10px; + outline: none; + } + + .tags-wrapper { + padding: 10px; + .border-radius-bottom-left(2px); + .border-radius-bottom-right(2px); + border: solid 1px #d8d8d8; + border-top: none; + + .group-tag { + display: inline-block; + + .sdc-tag { + border: solid 1px @main_color_n; + background-color: @main_color_p; + min-width: auto; + .tag { + margin-right: 10px; + } + } + } + &.view-mode .group-tag { + opacity: 1; + background-color: #f8f8f8 !important; + .sdc-tag { + background: none; + border-color: @main_color_o; + } + } + } + +} + diff --git a/catalog-ui/app/scripts/directives/utils/sdc-tags/sdc-tags.ts b/catalog-ui/app/scripts/directives/utils/sdc-tags/sdc-tags.ts new file mode 100644 index 0000000000..3f4147c920 --- /dev/null +++ b/catalog-ui/app/scripts/directives/utils/sdc-tags/sdc-tags.ts @@ -0,0 +1,97 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ +/// <reference path="../../../references"/> +module Sdc.Directives { + 'use strict'; + + export interface ISdcTagsScope extends ng.IScope { + tags:Array<string>; + specialTag:string; + newTag:string; + formElement:ng.IFormController; + elementName:string; + pattern:any; + sdcDisabled:boolean; + maxTags:number; + deleteTag(tag:string):void; + addTag(tag:string):void; + validateName():void; + } + + export class SdcTagsDirective implements ng.IDirective { + + constructor(private $templateCache:ng.ITemplateCacheService) { + } + + scope = { + tags: '=', + specialTag: '=', + pattern: '=', + sdcDisabled: '=', + formElement: '=', + elementName: '@', + maxTags: '@' + }; + + public replace = false; + public restrict = 'E'; + public transclude = false; + + template = ():string => { + return this.$templateCache.get('/app/scripts/directives/utils/sdc-tags/sdc-tags.html'); + }; + + link = (scope:ISdcTagsScope, element:ng.INgModelController) => { + + scope.deleteTag = (tag:string):void => { + scope.tags.splice(scope.tags.indexOf(tag),1); + }; + + scope.addTag = ():void => { + let valid = scope.formElement[scope.elementName].$valid; + if (valid && + scope.tags.length<scope.maxTags && + scope.newTag && + scope.newTag!=='' && + scope.tags.indexOf(scope.newTag)===-1 && + scope.newTag!==scope.specialTag) { + scope.tags.push(scope.newTag); + scope.newTag=''; + } + }; + + scope.validateName = ():void => { + if (scope.tags.indexOf(scope.newTag)>-1) { + scope.formElement[scope.elementName].$setValidity('nameExist', false); + }else{ + scope.formElement[scope.elementName].$setValidity('nameExist', true); + } + } + + }; + + public static factory = ($templateCache:ng.ITemplateCacheService)=> { + return new SdcTagsDirective($templateCache); + }; + + } + + SdcTagsDirective.factory.$inject = ['$templateCache']; +} diff --git a/catalog-ui/app/scripts/directives/utils/sdc_error_tooltip/sdc_error_tooltip.html b/catalog-ui/app/scripts/directives/utils/sdc_error_tooltip/sdc_error_tooltip.html new file mode 100644 index 0000000000..376381b8af --- /dev/null +++ b/catalog-ui/app/scripts/directives/utils/sdc_error_tooltip/sdc_error_tooltip.html @@ -0,0 +1,6 @@ +<div class="i-sdc-form-item-error-message" style="display: none;"> + <span class="i-sdc-form-item-error-icon-open"></span> + <ng-transclude> + + </ng-transclude> +</div> diff --git a/catalog-ui/app/scripts/directives/utils/sdc_error_tooltip/sdc_error_tooltip.ts b/catalog-ui/app/scripts/directives/utils/sdc_error_tooltip/sdc_error_tooltip.ts new file mode 100644 index 0000000000..dc30ea7f41 --- /dev/null +++ b/catalog-ui/app/scripts/directives/utils/sdc_error_tooltip/sdc_error_tooltip.ts @@ -0,0 +1,109 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ +/// <reference path="../../../references"/> +module Sdc.Directives { + 'use strict'; + + export interface ISdcErrorTooltipScope extends ng.IScope { + alignToSelector: string; + topMargin: string; + } + + export class SdcErrorTooltipDirective implements ng.IDirective { + + constructor(private $templateCache:ng.ITemplateCacheService) { + } + + scope = { + alignToSelector: '@', // Jquery selector to align to + topMargin: '@' // The margin from the top, in case there is label or not the top margin is different. + }; + + public replace = false; + public restrict = 'E'; + public transclude = true; + + template = ():string => { + return this.$templateCache.get('/app/scripts/directives/utils/sdc_error_tooltip/sdc_error_tooltip.html'); + }; + + link = (scope:ISdcErrorTooltipScope, $elem:any) => { + let _self = this; + + $elem.addClass("i-sdc-form-item-error-icon"); + + // Calculate the position of the elements after they loaded to the dom. + window.setTimeout(function(){ + _self.calculatePosition(scope, $elem); + },100); + + $elem.bind('mouseover', function(){ + $(".i-sdc-form-item-error-message",$elem).css("display", "block"); + }); + + $elem.bind('mouseleave', function(){ + $(".i-sdc-form-item-error-message",$elem).css("display", "none"); + }); + + } + + private calculatePosition(scope:ISdcErrorTooltipScope, $elem:any):void { + let leftMargin = 13; + let topMargin = scope.topMargin? parseInt(scope.topMargin) : 10; + + if (scope.alignToSelector) { + // Set the position of the error, in case user add align-to-selector attribute + let jObj = $(scope.alignToSelector); + if (jObj.length > 0) { + let height1 = jObj.outerHeight(); + $elem.css('left', jObj.position().left + jObj.outerWidth() + leftMargin); + //$elem.css('top', jObj.position().top + topMargin + (height1 / 2)); + $elem.css('top', jObj.position().top + (height1 / 2) - 5); // Label margin is: 2 + } + } else { + // Set the position of the error, according to the input element. + let inputElm = $elem.siblings('input'); + let textareaElm = $elem.siblings('textarea'); + let selectElm = $elem.siblings('select'); + if (inputElm.length > 0) { + $elem.css('left', inputElm.outerWidth() + leftMargin); + $elem.css('top', inputElm.position().top + topMargin); + } else if (textareaElm.length > 0) { + $elem.css('left', textareaElm.outerWidth() + leftMargin); + let height2 = textareaElm.outerHeight(); + let elmHeight2 = $elem.outerHeight(); + //let top = textareaElm.position().top; + $elem.css('bottom', (height2 - (elmHeight2 / 2)) / 2); + } else if (selectElm.length > 0) { + $elem.css('left', selectElm.outerWidth() + leftMargin); + $elem.css('top', selectElm.position().top + topMargin); + } + } + } + + public static factory = ($templateCache:ng.ITemplateCacheService)=> { + return new SdcErrorTooltipDirective($templateCache); + }; + + } + + SdcErrorTooltipDirective.factory.$inject = ['$templateCache']; + +} diff --git a/catalog-ui/app/scripts/directives/utils/sdc_messages/sdc-message.ts b/catalog-ui/app/scripts/directives/utils/sdc_messages/sdc-message.ts new file mode 100644 index 0000000000..d41ef1ce04 --- /dev/null +++ b/catalog-ui/app/scripts/directives/utils/sdc_messages/sdc-message.ts @@ -0,0 +1,179 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ +/// <reference path="../../../references"/> +module Sdc.Directives { + 'use strict'; + export interface ISdcMessageScope extends ng.IScope { + sdcTranslate: string; + sdcTranslateValues:string; + sdcAlign:string; + } + + export class SdcMessageDirective implements ng.IDirective { + + constructor(private $animate:any, private $filter:any, private $parse:any) { + } + + scope = { + field: '=', + required: '@', + pattern: '@', + sdcTranslate: '@', + sdcTranslateValues: '@', + sdcAlign: '@' + }; + + public terminal = true; + public restrict = 'A'; + public transclude = 'element'; + public require = '^^sdcMessages'; + + link = (scope:ISdcMessageScope, $element:any, $attrs:any,sdcMessagesCtrl:any, $transclude:any) => { + let self = this; + + let commentNode = $element[0]; + + let records; + let staticExp = $attrs.sdcMessage || $attrs.when; + let dynamicExp = $attrs.sdcMessageExp || $attrs.whenExp; + let assignRecords = function(items) { + records = items + ? (angular.isArray(items) + ? items + : items.split(/[\s,]+/)) + : null; + sdcMessagesCtrl.reRender(); + }; + + if (dynamicExp) { + assignRecords(scope.$eval(dynamicExp)); + scope.$watchCollection(dynamicExp, assignRecords); + } else { + assignRecords(staticExp); + } + + let currentElement, messageCtrl; + sdcMessagesCtrl.register(commentNode, messageCtrl = { + test: function (name) { + return self.contains(records, name); + }, + attach: function () { + if (!currentElement) { + $transclude(scope, function (elm) { + + self.$animate.enter(elm, null, $element); + currentElement = elm; + + elm.addClass("i-sdc-form-item-error-message"); + + //$compile + let text; + if (scope.sdcTranslate) { + text = self.$filter('translate')(scope.sdcTranslate, scope.sdcTranslateValues); + } else { + //TODO: Need to handle this + //let t = elm.html(); + //let t = angular.element("<span>" + elm.html() + "</span>"); + //text = self.$parse(t); + } + + //scope.sdcTranslateValues + elm.html(text); + + elm.prepend("<span class='error'></span>"); + + // Adding OK to close the message + //let okElm = $('<span />').attr('class', 'ok').html('OK'); + //okElm.click(function(e){ + // messageCtrl.detach(); + //}); + //elm.append(okElm); + + // Handle the position + if (scope.sdcAlign){ + let choosenElm = $(scope.sdcAlign); + if (choosenElm.length > 0) { + let height1 = choosenElm.outerHeight(); + let elmHeight1 = elm.outerHeight(); + elm.css('left', choosenElm.outerWidth()); + elm.css('bottom', (height1 - (elmHeight1 / 2)) / 2); + } + } else { + // Set the position of the error, according to the input element. + let inputElm = elm.parent().siblings('input'); + let textareaElm = elm.parent().siblings('textarea'); + let selectElm = elm.parent().siblings('select'); + if (inputElm.length > 0) { + elm.css('left', inputElm.outerWidth()); + elm.css('top', inputElm.position().top); + } else if (textareaElm.length > 0) { + elm.css('left', textareaElm.outerWidth()); + let height = textareaElm.outerHeight(); + let elmHeight = elm.outerHeight(); + //let top = textareaElm.position().top; + elm.css('bottom', (height - (elmHeight / 2)) / 2); + } else if (selectElm.length > 0) { + elm.css('left', selectElm.outerWidth()); + elm.css('top', selectElm.position().top); + } + } + + // Each time we attach this node to a message we get a new id that we can match + // when we are destroying the node later. + let $$attachId = currentElement.$$attachId = sdcMessagesCtrl.getAttachId(); + + // in the event that the parent element is destroyed + // by any other structural directive then it's time + // to deregister the message from the controller + currentElement.on('$destroy', function () { + if (currentElement && currentElement.$$attachId === $$attachId) { + sdcMessagesCtrl.deregister(commentNode); + messageCtrl.detach(); + } + }); + }); + } + }, + detach: function () { + if (currentElement) { + let elm = currentElement; + currentElement = null; + self.$animate.leave(elm); + } + } + }); + } + + contains = (collection, key):any => { + if (collection) { + return angular.isArray(collection) + ? collection.indexOf(key) >= 0 + : collection.hasOwnProperty(key); + } + } + + public static factory = ($animate:any, $filter:any, $parse:any)=> { + return new SdcMessageDirective($animate, $filter, $parse); + }; + + } + + SdcMessageDirective.factory.$inject = ['$animate', '$filter', '$parse']; +} diff --git a/catalog-ui/app/scripts/directives/utils/sdc_messages/sdc-messages.less b/catalog-ui/app/scripts/directives/utils/sdc_messages/sdc-messages.less new file mode 100644 index 0000000000..d8dfdbb73b --- /dev/null +++ b/catalog-ui/app/scripts/directives/utils/sdc_messages/sdc-messages.less @@ -0,0 +1,10 @@ +.ellipsis-directive-more-less { + .a_9; + .bold; + .hand; + float: right; + margin-right: 17px; + line-height: 23px; + text-decoration: underline; + text-align: left; +} diff --git a/catalog-ui/app/scripts/directives/utils/sdc_messages/sdc-messages.ts b/catalog-ui/app/scripts/directives/utils/sdc_messages/sdc-messages.ts new file mode 100644 index 0000000000..f8b435b1fa --- /dev/null +++ b/catalog-ui/app/scripts/directives/utils/sdc_messages/sdc-messages.ts @@ -0,0 +1,245 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ +/// <reference path="../../../references"/> +module Sdc.Directives { + 'use strict'; + export interface ISdcMessagesScope extends ng.IScope { + sdcMessages: any; + editForm:ng.IFormController; + } + + export class SdcMessagesDirective implements ng.IDirective { + + constructor() {} + + scope = { + sdcMessages: '=' + }; + + public restrict = 'AE'; + public require = 'sdcMessages'; + public controller = SdcMessagesController; + + /*template = ():string => { + return this.$templateCache.get('/app/scripts/directives/utils/sdc-messages/sdc-messages.html'); + }; + + public static factory = ($templateCache:ng.ITemplateCacheService)=> { + return new SdcMessagesDirective($templateCache); + };*/ + + public static factory = ()=> { + return new SdcMessagesDirective(); + } + + } + + export class SdcMessagesController { + + messages:any; + getAttachId:Function; + render:any; + reRender:Function; + register:Function; + deregister:Function; + head:any; + + static '$inject' = [ + '$element', + '$scope', + '$attrs', + '$animate' + ]; + + constructor(private $element:JQuery, + private $scope:ISdcMessagesScope, + private $attrs:ng.IAttributes, + private $animate:any + ) { + + this.init(); + + } + + init=():void => { + let self = this; + + let ACTIVE_CLASS:string = 'ng-active'; + let INACTIVE_CLASS:string = 'ng-inactive'; + + let ctrl = this; + let latestKey = 0; + let nextAttachId = 0; + + this.getAttachId = function getAttachId() { return nextAttachId++; }; + + let messages = this.messages = {}; + let renderLater, cachedCollection; + + this.render = function(collection) { + collection = collection || {}; + + renderLater = false; + cachedCollection = collection; + + // this is true if the attribute is empty or if the attribute value is truthy + let multiple = self.isAttrTruthy(self.$scope, self.$attrs['sdcMessagesMultiple']) || self.isAttrTruthy(self.$scope, self.$attrs['multiple']); + + let unmatchedMessages = []; + let matchedKeys = {}; + let messageItem = ctrl.head; + let messageFound = false; + let totalMessages = 0; + + // we use != instead of !== to allow for both undefined and null values + while (messageItem != null) { + totalMessages++; + let messageCtrl = messageItem.message; + + let messageUsed = false; + if (!messageFound) { + _.each(collection, function(value, key) { + if (!messageUsed && self.truthy(value) && messageCtrl.test(key)) { + // this is to prevent the same error name from showing up twice + if (matchedKeys[key]) return; + matchedKeys[key] = true; + + messageUsed = true; + messageCtrl.attach(); + } + }); + } + + if (messageUsed) { + // unless we want to display multiple messages then we should + // set a flag here to avoid displaying the next message in the list + messageFound = !multiple; + } else { + unmatchedMessages.push(messageCtrl); + } + + messageItem = messageItem.next; + } + + _.each(unmatchedMessages, function(messageCtrl) { + messageCtrl.detach(); + }); + + unmatchedMessages.length !== totalMessages + ? ctrl.$animate.setClass(self.$element, ACTIVE_CLASS, INACTIVE_CLASS) + : ctrl.$animate.setClass(self.$element, INACTIVE_CLASS, ACTIVE_CLASS); + }; + + self.$scope.$watchCollection('sdcMessages' || self.$attrs['for'], function(newVal:any, oldVal:any){ + ctrl.render(newVal); + }); + + this.reRender = function() { + if (!renderLater) { + renderLater = true; + self.$scope.$evalAsync(function() { + if (renderLater) { + cachedCollection && ctrl.render(cachedCollection); + } + }); + } + }; + + this.register = function(comment, messageCtrl) { + let nextKey = latestKey.toString(); + messages[nextKey] = { + message: messageCtrl + }; + insertMessageNode(self.$element[0], comment, nextKey); + comment.$$sdcMessageNode = nextKey; + latestKey++; + + ctrl.reRender(); + }; + + this.deregister = function(comment) { + let key = comment.$$sdcMessageNode; + delete comment.$$sdcMessageNode; + removeMessageNode(self.$element[0], comment, key); + delete messages[key]; + ctrl.reRender(); + }; + + function findPreviousMessage(parent, comment) { + let prevNode = comment; + let parentLookup = []; + while (prevNode && prevNode !== parent) { + let prevKey = prevNode.$$sdcMessageNode; + if (prevKey && prevKey.length) { + return messages[prevKey]; + } + + // dive deeper into the DOM and examine its children for any sdcMessage + // comments that may be in an element that appears deeper in the list + if (prevNode.childNodes.length && parentLookup.indexOf(prevNode) == -1) { + parentLookup.push(prevNode); + prevNode = prevNode.childNodes[prevNode.childNodes.length - 1]; + } else { + prevNode = prevNode.previousSibling || prevNode.parentNode; + } + } + } + + function insertMessageNode(parent, comment, key) { + let messageNode = messages[key]; + if (!ctrl.head) { + ctrl.head = messageNode; + } else { + let match = findPreviousMessage(parent, comment); + if (match) { + messageNode.next = match.next; + match.next = messageNode; + } else { + messageNode.next = ctrl.head; + ctrl.head = messageNode; + } + } + } + + function removeMessageNode(parent, comment, key) { + let messageNode = messages[key]; + + let match = findPreviousMessage(parent, comment); + if (match) { + match.next = messageNode.next; + } else { + ctrl.head = messageNode.next; + } + } + } + + isAttrTruthy = (scope, attr):any => { + return (angular.isString(attr) && attr.length === 0) || //empty attribute + this.truthy(scope.$eval(attr)); + } + + truthy = (val):any => { + return angular.isString(val) ? val.length : !!val; + } + + } + + SdcMessagesDirective.factory.$inject = ['$templateCache','$animate']; +} diff --git a/catalog-ui/app/scripts/directives/utils/sdc_messages/sdc_messages.html b/catalog-ui/app/scripts/directives/utils/sdc_messages/sdc_messages.html new file mode 100644 index 0000000000..09b1cad4d2 --- /dev/null +++ b/catalog-ui/app/scripts/directives/utils/sdc_messages/sdc_messages.html @@ -0,0 +1 @@ +<span>aaa</span> diff --git a/catalog-ui/app/scripts/directives/utils/smart-tooltip/smart-tooltip.ts b/catalog-ui/app/scripts/directives/utils/smart-tooltip/smart-tooltip.ts new file mode 100644 index 0000000000..49a57245e7 --- /dev/null +++ b/catalog-ui/app/scripts/directives/utils/smart-tooltip/smart-tooltip.ts @@ -0,0 +1,85 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ +/// <reference path="../../../references"/> +module Sdc.Directives { + 'use strict'; + + export interface ISmartTooltipScope extends ng.IScope { + sdcSmartToolip; + } + + export class SmartTooltipDirective implements ng.IDirective { + + constructor(private $templateCache:ng.ITemplateCacheService, + private $compile:ng.ICompileService) { + } + + public replace = false; + public restrict = 'A'; + public transclude = false; + + public link = (scope:ISmartTooltipScope, $elem:ng.IAugmentedJQuery, $attrs:angular.IAttributes) => { + + if ($elem[0].hasAttribute('style')===false){ + $elem[0].setAttribute("style", "overflow: hidden; white-space: nowrap; text-overflow: ellipsis;"); + } else { + let styles = $elem.attr('style'); + $elem[0].setAttribute("style", styles + ";overflow: hidden; white-space: nowrap; text-overflow: ellipsis;"); + } + + $elem.bind('mouseenter', () => { + if($elem[0].offsetWidth < $elem[0].scrollWidth && !$elem.attr('tooltips')){ + $attrs.$set('tooltips', 'tooltips'); + if ($attrs['sdcSmartTooltip'] && $attrs['sdcSmartTooltip'].length>0){ + $elem.attr('tooltip-content', $attrs['sdcSmartTooltip']); + } else { + $attrs.$set('tooltip-content', $elem.text()); + } + + //One possible problem arises when the ngIf is placed on the root element of the template. + //ngIf removes the node and places a comment in it's place. Then it watches over the expression and adds/removes the actual HTML element as necessary. + //The problem seems to be that if it is placed on the root element of the template, then a single comment is what is left from the + //whole template (even if only temporarily), which gets ignored (I am not sure if this is browser-specific behaviour), resulting in an empty template. + + // Remove ng-if attribute and its value (if we reach here, we pass ng-if (ng-if===true), so we can remove it). + $elem.removeAttr('ng-if'); + $elem.removeAttr('data-ng-if'); + + // Remove me (the directive from the element) + let template = $elem[0].outerHTML; + template = template.replace('sdc-smart-tooltip=""',''); + template = template.replace('sdc-smart-tooltip="' + $elem.text() + '"',''); + //console.log(template); + + let el = this.$compile(template)(scope); + console.log(el); + $elem.replaceWith(el); + } + }); + }; + + public static factory = ($templateCache:ng.ITemplateCacheService, $compile:ng.ICompileService)=> { + return new SmartTooltipDirective($templateCache, $compile); + }; + + } + + SmartTooltipDirective.factory.$inject = ['$templateCache', '$compile']; +} diff --git a/catalog-ui/app/scripts/directives/utils/wizard_steps/sdc-wizard-steps.html b/catalog-ui/app/scripts/directives/utils/wizard_steps/sdc-wizard-steps.html new file mode 100644 index 0000000000..0c9b97a58c --- /dev/null +++ b/catalog-ui/app/scripts/directives/utils/wizard_steps/sdc-wizard-steps.html @@ -0,0 +1,16 @@ +<ul class="sdc-wizard-step"> + <li class="step" data-ng-repeat="step in steps track by $index"> + <div class="step-wrapper"> + <button class="step-index" + data-ng-click="controllerStepClicked(step.name)" + data-ng-class="{'selected': step.selected===true, 'valid': step.valid===true, 'disabled': !step.enabled || step.enabled===false}"> + {{$index+1}} + </button> + <span class="step-name" + data-ng-class="{'selected': step.selected===true, 'valid': step.valid===true, 'disabled': !step.enabled || step.enabled===false}">{{step.name}} + </span> + </div> + <div class="step-seperator"></div> + </li> +</ul> + diff --git a/catalog-ui/app/scripts/directives/utils/wizard_steps/sdc-wizard-steps.less b/catalog-ui/app/scripts/directives/utils/wizard_steps/sdc-wizard-steps.less new file mode 100644 index 0000000000..8b777923a0 --- /dev/null +++ b/catalog-ui/app/scripts/directives/utils/wizard_steps/sdc-wizard-steps.less @@ -0,0 +1,69 @@ +@circle-radius: 18px; +@gap: 70px; +@gap-width: 2px; +@valid-width: 2px; + +ul.sdc-wizard-step { + padding: 0; + margin: 0; + + li.step { + position: relative; + list-style: none; + + .step-wrapper { + line-height: @circle-radius*2; + height: @circle-radius*2; + margin-bottom: @gap; + + button.step-index { + ._w-sdc-wizard-step-btn(@circle-radius); + z-index: 99; + display: inline-block; + + &.valid { + display: inline-block; + } + + } + + span.step-name { + .b_7; + line-height: @circle-radius; + display: inline-block; + word-wrap: break-word; + width: calc(~"100%" - @circle-radius*2 + 4); + vertical-align: middle; + padding-left: 10px; + white-space: normal; + + &.selected { + .a_7; + font-weight: bold; + } + + &.disabled { + border: none; + background-color: transparent; + } + + } + } + + .step-seperator { + border-right: @gap-width solid @color_n; + height: @gap + @circle-radius*2; + position: absolute; + top: @circle-radius*2-@circle-radius; + left: @circle-radius - @gap-width/2; + } + + } + + li.step:last-child { + .step-seperator { + display: none; + } + } + +} diff --git a/catalog-ui/app/scripts/directives/utils/wizard_steps/sdc-wizard-steps.ts b/catalog-ui/app/scripts/directives/utils/wizard_steps/sdc-wizard-steps.ts new file mode 100644 index 0000000000..9cad36ab78 --- /dev/null +++ b/catalog-ui/app/scripts/directives/utils/wizard_steps/sdc-wizard-steps.ts @@ -0,0 +1,139 @@ +/*- + * ============LICENSE_START======================================================= + * SDC + * ================================================================================ + * Copyright (C) 2017 AT&T Intellectual Property. All rights reserved. + * ================================================================================ + * Licensed 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. + * ============LICENSE_END========================================================= + */ +/// <reference path="../../../references"/> +module Sdc.Directives { + + 'use strict'; + + export interface IWizardStep { + name: string; + selected?: boolean; + valid?:boolean; + enabled?:boolean; + callback: Function; + } + + export interface ISdcWizardStepScope extends ng.IScope { + steps:Array<IWizardStep>; + control:any; + internalControl:any; + + stepClicked(stepName:string):void; + controllerStepClicked(stepName:string):void; + + setStepValidity(stepName:string, valid:boolean):void; + controllerSetStepValidity(step:IWizardStep, valid:boolean):void; + } + + export interface SdcWizardStepMethods { + unSelectAllSteps():void; + selectStep(step:IWizardStep):void; + } + + export class SdcWizardStepDirective implements ng.IDirective { + + constructor(private $templateCache:ng.ITemplateCacheService) { + } + + scope = { + steps: '=', + control: '=' + }; + + public replace = false; + public restrict = 'E'; + public transclude = true; + public controller = SdcWizardStepDirectiveController; + + template = ():string => { + return this.$templateCache.get('/app/scripts/directives/utils/wizard_steps/sdc-wizard-steps.html'); + }; + + link = (scope:ISdcWizardStepScope, $elem:JQuery, attr:any, controller:SdcWizardStepDirectiveController) => { + scope.internalControl = scope.control || {}; + scope.internalControl.stepClicked = (step:string):void => { + scope.controllerStepClicked(step); + }; + + scope.internalControl.setStepValidity = (step:IWizardStep, valid:boolean):void => { + scope.controllerSetStepValidity(step, valid); + }; + } + + public static factory = ($templateCache:ng.ITemplateCacheService)=> { + return new SdcWizardStepDirective($templateCache); + }; + + } + + SdcWizardStepDirective.factory.$inject = ['$templateCache']; + + export class SdcWizardStepDirectiveController { + static $inject = ['$element', '$scope']; + + methods:SdcWizardStepMethods = <SdcWizardStepMethods>{}; + + constructor(public $element: JQuery, + public $scope: ISdcWizardStepScope) { + + this.initMethods(); + this.initScope(); + } + + private initScope = ():void => { + + this.$scope.controllerStepClicked = (stepName:string):void => { + let selectedStep:IWizardStep = <IWizardStep>_.find(this.$scope.steps, function (item) { + return item.name === stepName; + }); + + if (selectedStep && selectedStep.enabled===true){ + let result:boolean = selectedStep.callback(); + if (result===true){ + this.methods.unSelectAllSteps(); + this.methods.selectStep(selectedStep); + } + } + }; + + this.$scope.controllerSetStepValidity = (step:IWizardStep, valid:boolean):void => { + step.valid=valid; + }; + + }; + + private initMethods = ():void => { + + this.methods.unSelectAllSteps = ():void => { + this.$scope.steps.forEach(function (step) { + step.selected = false; + }); + } + + this.methods.selectStep = (step:IWizardStep):void => { + if (step.enabled===true){ + step.selected=true; + } + } + }; + + } + +} |