1 define([], function () {
4 function NodeWrapperService(constants, RequestBuilderService, RestrictionsService, TypeWrapperService,
5 ListFilteringService, EventDispatcherService, FilterNodeWrapperService){
11 checkKeyDuplicity: checkKeyDuplicity,
16 'leaf-list': leafList,
28 comparePropToElemByName: comparePropToElemByName,
29 equalArrays: equalArrays,
30 equalListElems: equalListElems,
31 parseRestrictText: parseRestrictText,
33 checkListElemKeys: checkListElemKeys,
40 * Service for wrapping list element
44 function _listElem(node) {
47 node.listElemBuildRequest = function (builder, req) {
49 objToAdd = builder.createObj();
51 node.getChildren(null, null, constants.NODE_UI_DISPLAY).forEach(function (child) {
52 var childAdded = child.buildRequest(builder, objToAdd, node.module);
53 added = added || childAdded;
57 builder.insertObjToList(req, objToAdd);
63 node.fillListElement = function (name, data) {
66 node.getChildren(null, null, constants.NODE_UI_DISPLAY).forEach(function (child) {
67 var childFilled = child.fill(name, data);
68 filled = filled || childFilled;
74 node.isFilled = function () {
75 return node.getChildren(null, null, constants.NODE_UI_DISPLAY).some(function (child) {
76 return child.isFilled();
80 node.clear = function () {
81 var nodesToClear = node.getChildren(null, null, constants.NODE_UI_DISPLAY);
83 if (nodesToClear.length) {
84 nodesToClear.forEach(function (child) {
90 node.children.forEach(function (child) {
96 * Service for wrapping list yang element
101 node.doubleKeyIndexes = [];
102 node.actElemStructure = null;
103 node.actElemIndex = -1;
105 node.expanded = true;
107 node.filterNodes = [];
108 node.searchedPath = [];
109 node.referenceNode = null;
110 node.filteredListData = [];
111 node.currentFilter = 0;
113 node.toggleExpand = function () {
114 node.expanded = !node.expanded;
117 node.createStructure = function () {
118 if (node.actElemStructure === null) {
119 var copy = node.deepCopy(['augmentionGroups', 'augmentationId']);
121 node.actElemStructure = copy;
122 node.actElemStructure.getActElemIndex = node.getActElemIndex;
126 node.getActElemIndex = function () {
127 return node.actElemIndex;
130 node.addListElem = function () {
131 node.createStructure();
132 var newElemData = {};
133 node.listData.push(newElemData);
134 node.changeActElementData(node.listData.length - 1, true);
137 node.buildActElemData = function () {
141 if (node.actElemStructure) {
142 node.actElemStructure.listElemBuildRequest(RequestBuilderService, list, node.module);
143 result = list[0] ? list[0] : {};
148 node.changeActElementData = function (index, fromAdd) {
149 var storeData = node.buildActElemData();
150 node.expanded = true;
152 if (node.actElemIndex > -1) { // we are changing already existing data
153 if (node.filteredListData && node.filteredListData.length){
154 node.listData[node.listData.indexOf(node.filteredListData[node.actElemIndex])] = storeData;
155 node.filteredListData[node.actElemIndex] = storeData;
157 ListFilteringService.clearFilterData(node, true, false);
160 node.listData[node.actElemIndex] = storeData;
163 node.actElemIndex = index;
166 if (!(node.filteredListData && node.filteredListData.length)){
167 actData = node.listData[node.actElemIndex];
169 actData = node.listData[node.listData.indexOf(node.filteredListData[node.actElemIndex])];
172 node.actElemStructure.clear();
173 for (var prop in actData) {
174 node.actElemStructure.fillListElement(prop, actData[prop]);
177 EventDispatcherService.dispatch(constants.EV_LIST_CHANGED, node.actElemStructure);
180 node.removeListElem = function (elemIndex, fromFilter) {
183 elemIndex = node.listData.indexOf(node.filteredListData[elemIndex]);
186 node.listData.splice(elemIndex, 1);
187 node.actElemIndex = node.listData.length - 1;
190 ListFilteringService.clearFilterData(node, true, false);
193 if (node.actElemIndex === -1) {
194 node.actElemStructure = null;
196 var actData = node.listData[node.actElemIndex];
198 node.actElemStructure.clear();
199 for (var prop in actData) {
200 node.actElemStructure.fillListElement(prop, actData[prop]);
204 EventDispatcherService.dispatch(constants.EV_LIST_CHANGED, node.actElemStructure);
207 node.buildRequest = function (builder, req, module) {
209 // store entered data
210 var storeData = node.buildActElemData(),
211 labelWithModule = (module !== node.module ? node.module + ':' : '') + node.label;
213 if (node.actElemIndex > -1) {
214 if (node.filteredListData && node.filteredListData.length){
215 node.listData[node.listData.indexOf(node.filteredListData[node.actElemIndex])] = storeData;
216 node.filteredListData[node.actElemIndex] = storeData;
218 node.listData[node.actElemIndex] = storeData;
222 added = node.listData.filter(function (data) {
223 return $.isEmptyObject(data) === false;
226 var buildedDataCopy = node.listData.slice().map(function (item) {
228 for (var prop in item){
229 if (prop !== '$$hashKey'){
230 newItem[prop] = item[prop];
234 }).filter(function (item){
235 return Object.keys(item).length !== 0;
238 // check of listElems keyValues duplicity
239 if (node.filteredListData && node.filteredListData.length){
240 node.doubleKeyIndexes = checkKeyDuplicity(node.filteredListData, node.refKey);
242 node.doubleKeyIndexes = checkKeyDuplicity(node.listData, node.refKey);
246 builder.insertPropertyToObj(req, labelWithModule, buildedDataCopy);
252 node.fill = function (name, array) { // data is array
254 var match = comparePropToElemByName(name, node.label);
256 if (match && array.length) {
257 node.createStructure();
258 node.listData = array.slice();
259 node.actElemIndex = node.listData.length - 1;
260 for (var prop in node.listData[node.actElemIndex]) {
261 node.actElemStructure.fillListElement(prop, node.listData[node.actElemIndex][prop]);
265 return (match && array.length > 0);
268 node.clear = function () {
269 while (node.listData.length > 0) {
272 while (node.filteredListData.length > 0) {
273 node.filteredListData.pop();
276 node.actElemIndex = -1;
277 node.actElemStructure = null;
278 node.nodeType = constants.NODE_UI_DISPLAY;
281 node.isFilled = function () {
282 return node.listData.length > 0;
285 node.createListName = function (index) {
290 if (node.filteredListData && node.filteredListData.length){
291 currentList = node.filteredListData;
293 currentList = node.listData;
297 node.actElemStructure.refKey.forEach(function (key) {
298 if (index === node.getActElemIndex()) {
299 val = key.value !== '' ? key.label + ':' + key.value : '';
302 if (!($.isEmptyObject(currentList[index]))) {
303 if (currentList[index][key.label]) {
305 } else if (currentList[index][key.module + ':' + key.label]) {
306 prop = key.module + ':' + key.label;
308 val = prop ? key.label + ':' + currentList[index][prop] : prop;
312 name = name ? (name + (val ? (' ' + val) : '')) : (name + (val ? (' <' + val) : ''));
323 node.getNewFilterElement = function (){
324 return node.getChildrenForFilter().map(function (element){
325 FilterNodeWrapperService.init(element);
326 var copy = element.deepCopyForFilter();
328 FilterNodeWrapperService.wrapForFilter(copy);
334 // TODO: add service's description
335 function config(node) {
336 node.parent.isConfigStm = (node.label === 'true');
339 // TODO: add service's description
341 // do this only on list, not on listElem because deepCopy on list doesn't copy property keys to
342 // listElem => don't do this when button for add new list is clicked
343 if (node.parent.hasOwnProperty('refKey')) {
344 var keyLabels = node.label.split(' '),
345 keyNodes = node.parent.getChildren(null, null, constants.NODE_UI_DISPLAY).filter(function (child) {
346 return keyLabels.indexOf(child.label) > -1;
348 getRefKeyArray = function (keys){
349 var refKeyArray = [];
350 keyLabels.forEach(function (keyLabel){
351 var nk = keys.filter(function (k){
352 return keyLabel === k.label;
356 refKeyArray.push(nk[0]);
362 node.parent.refKey = getRefKeyArray(keyNodes);
367 * Service for wrapping leaf list yang element
370 function leafList(node) {
372 node.expanded = true;
374 node.toggleExpand = function () {
375 node.expanded = !node.expanded;
378 node.addListElem = function () {
382 node.value.push(newElement);
385 node.removeListElem = function (elem) {
386 node.value.splice(node.value.indexOf(elem), 1);
389 node.buildRequest = function (builder, req, module) {
391 labelWithModule = (module !== node.module ? node.module + ':' : '') + node.label;
393 for (var i = 0; i < node.value.length; i++) {
394 valueArray.push(node.value[i].value);
397 if (valueArray.length > 0) {
398 builder.insertPropertyToObj(req, labelWithModule, valueArray);
407 node.fill = function (name, array) {
408 var match = comparePropToElemByName(name, node.label),
413 for (var i = 0; i < array.length; i++) {
417 node.value.push(newLeafListItem);
424 node.clear = function () {
425 node.nodeType = constants.NODE_UI_DISPLAY;
429 node.isFilled = function () {
430 return node.value.length > 0;
435 * Service for wrapping choice yang element
438 function choice(node) {
440 node.expanded = true;
442 node.buildRequest = function (builder, req, module) {
446 added = node.choice.buildRequest(builder, req, module);
452 node.fill = function (name, data) {
454 nodesToFill = node.getChildren(null, null, constants.NODE_UI_DISPLAY);
456 nodesToFill.forEach(function (child) {
457 var childFilled = child.fill(name, data);
463 filled = filled || childFilled;
472 node.clear = function () {
473 node.nodeType = constants.NODE_UI_DISPLAY;
481 node.isFilled = function () {
482 return node.choice !== null;
487 * Service for wrapping case yang element
490 function caseYang(node) {
492 node.buildRequest = function (builder, req, module) {
495 node.getChildren(null, null, constants.NODE_UI_DISPLAY).forEach(function (child) {
496 var childAdded = child.buildRequest(builder, req, module);
497 added = added || childAdded;
503 node.fill = function (name, data) {
505 nodesToFill = node.getChildren(null, null, constants.NODE_UI_DISPLAY);
507 nodesToFill.forEach(function (child) {
508 var childFilled = child.fill(name, data);
509 filled = filled || childFilled;
515 node.clear = function () {
516 var nodesToClear = node.getChildren(null, null, constants.NODE_UI_DISPLAY);
518 nodesToClear.forEach(function (child) {
523 node.isFilled = function () {
524 return node.getChildren(null, null, constants.NODE_UI_DISPLAY).some(function (child) {
525 return child.isFilled();
531 * Service for wrapping output yang element
534 function output(node) {
535 node.expanded = true;
537 node.buildRequest = function (builder, req) {
541 node.fill = function (name, data) {
542 var match = comparePropToElemByName(name, node.label),
543 nodesToFill = node.getChildren(null, null, constants.NODE_UI_DISPLAY);
545 if (match && nodesToFill.length) {
546 nodesToFill.forEach(function (child) {
547 for (var prop in data) {
548 child.fill(prop, data[prop]);
551 node.expanded = match;
557 node.clear = function () {
558 var nodesToClear = node.getChildren(null, null, constants.NODE_UI_DISPLAY);
560 if (nodesToClear.length) {
561 nodesToClear.forEach(function (child) {
567 node.isFilled = function () {
568 return node.getChildren(null, null, constants.NODE_UI_DISPLAY).some(function (child) {
569 return child.isFilled();
575 // TODO: add service's description
576 function input(node) {
577 node.expanded = true;
579 node.buildRequest = function (builder, req, module) {
581 objToAdd = builder.createObj(),
582 builderNodes = node.getChildren(null, null, constants.NODE_UI_DISPLAY),
583 labelWithModule = (module !== node.module ? node.module + ':' : '') + node.label;
585 if (builderNodes.length) {
587 builderNodes.forEach(function (child) {
588 var childAdded = child.buildRequest(builder, objToAdd, node.module);
589 added = added || childAdded;
596 builder.insertPropertyToObj(req, labelWithModule, objToAdd);
602 node.fill = function (name, data) {
603 var match = comparePropToElemByName(name, node.label),
604 nodesToFill = node.getChildren(null, null, constants.NODE_UI_DISPLAY);
606 if (match && nodesToFill.length) {
607 nodesToFill.forEach(function (child) {
608 for (var prop in data) {
609 child.fill(prop, data[prop]);
612 node.expanded = match;
618 node.clear = function () {
619 var nodesToClear = node.getChildren(null, null, constants.NODE_UI_DISPLAY);
621 if (nodesToClear.length) {
622 nodesToClear.forEach(function (child) {
628 node.isFilled = function () {
629 return node.getChildren(null, null, constants.NODE_UI_DISPLAY).some(function (child) {
630 return child.isFilled();
637 * Service for wrapping rpc yang element
641 node.expanded = true;
642 node.buildRequest = function (builder, req, module) {
644 objToAdd = builder.createObj(),
645 builderNodes = node.getChildren(null, null, constants.NODE_UI_DISPLAY),
646 labelWithModule = (module !== node.module ? node.module + ':' : '') + node.label;
648 if (builderNodes.length) {
649 builderNodes.forEach(function (child) {
650 var childAdded = child.buildRequest(builder, objToAdd, node.module);
651 added = added || childAdded;
655 objToAdd = constants.NULL_DATA;
659 builder.insertPropertyToObj(req, labelWithModule, objToAdd);
665 node.fill = function (name, data) {
667 nodesToFill = node.getChildren(null, null, constants.NODE_UI_DISPLAY);
669 nodesToFill.forEach(function (child) {
670 var childFilled = child.fill(name, data);
671 filled = filled || childFilled;
674 node.expanded = filled;
679 node.clear = function () {
680 var nodesToClear = node.getChildren(null, null, constants.NODE_UI_DISPLAY);
682 if (nodesToClear.length) {
683 nodesToClear.forEach(function (child) {
689 node.isFilled = function () {
690 return node.getChildren(null, null, constants.NODE_UI_DISPLAY).some(function (child) {
691 return child.isFilled();
698 * Service for wrapping container yang element
701 function container(node) {
702 node.expanded = false;
704 node.toggleExpand = function () {
705 node.expanded = !node.expanded;
708 node.buildRequest = function (builder, req, module) {
710 objToAdd = builder.createObj(),
711 builderNodes = node.getChildren(null, null, constants.NODE_UI_DISPLAY),
712 labelWithModule = (module !== node.module ? node.module + ':' : '') + node.label;
714 if (builderNodes.length) {
715 builderNodes.forEach(function (child) {
716 var childAdded = child.buildRequest(builder, objToAdd, node.module);
717 added = added || childAdded;
723 if (added && (checkEmptyContainer(node.parent ? node.parent.type : 'blanktype', objToAdd) ||
724 checkPresence(node))) {
725 builder.insertPropertyToObj(req, labelWithModule, objToAdd);
730 // TODO: add function's description
731 function checkPresence(containerNode) {
732 return containerNode.children.some(function (ch) {
733 return ch.type === 'presence';
737 // TODO: add function's description
738 function checkEmptyContainer(type, obj) { // TODO: absolete after when statement is implemented
739 return !!(type === 'case' || !$.isEmptyObject(objToAdd));
743 node.fill = function (name, data) {
744 var match = comparePropToElemByName(name, node.label),
745 nodesToFill = node.getChildren(null, null, constants.NODE_UI_DISPLAY);
747 if (match && nodesToFill.length) {
748 nodesToFill.forEach(function (child) {
749 for (var prop in data) {
750 child.fill(prop, data[prop]);
754 node.expanded = match;
760 node.clear = function () {
761 var nodesToClear = node.getChildren(null, null, constants.NODE_UI_DISPLAY);
762 node.nodeType = constants.NODE_UI_DISPLAY;
764 if (nodesToClear.length) {
765 nodesToClear.forEach(function (child) {
771 node.isFilled = function () {
772 return node.getChildren(null, null, constants.NODE_UI_DISPLAY).some(function (child) {
773 return child.isFilled();
779 * Service for set patern restriction from yang element
782 function pattern(node) {
783 node.restrictions = [RestrictionsService.getReqexpValidationFnc(node.label)];
787 * Service for set range restriction from yang element
790 function range(node) {
791 node.restrictions = parseRestrictText(node.label);
795 * Service for set length restriction from yang element
798 function length(node) {
799 node.restrictions = parseRestrictText(node.label);
803 * Service for wrapping type yang element
806 function type(node) {
807 TypeWrapperService.wrapAll(node);
811 * Service for wrapping leaf yang element
814 function leaf(node) {
816 node.valueIsValid = true;
817 node.typeChild = node.getChildren('type')[0];
819 node.buildRequest = function (builder, req, module) {
820 var value = node.typeChild.getValue(),
821 labelWithModule = (module !== node.module ? node.module + ':' : '') + node.label;
824 EventDispatcherService.dispatch(constants.EV_FILL_PATH, node, value);
828 builder.insertPropertyToObj(req, labelWithModule, value);
835 node.fill = function (name, data) {
838 match = comparePropToElemByName(name, node.label);
840 node.value = data.toString();
841 if (node.typeChild) {
842 node.typeChild.fill(node.value);
848 node.clear = function () {
851 if (node.typeChild) {
852 node.typeChild.clear();
856 node.isFilled = function () {
857 var filled = node.typeChild.getValue() ? true : false;
861 node.checkValueType = function () {
862 node.valueIsValid = node.typeChild ? node.typeChild.check(node.value) : true;
865 node.isKey = function () {
866 return node.parent &&
867 node.parent.type === 'list' &&
868 node.parent.refKey && node.parent.refKey.indexOf(node) !== -1;
873 * Service for wrapping single node
876 function wrap(node) {
877 if (service.hasOwnProperty(node.type)) {
878 service[node.type](node);
883 * Main service for wrapping nodes
886 function wrapAll(node) {
888 node.children.forEach(function (child) {
889 service.wrapAll(child);
893 // TODO: add service's description
894 function checkKeyDuplicity(listData, refKey) {
895 return checkListElemKeys(listData, refKey);
898 // TODO: add function's description
899 function comparePropToElemByName(propName, elemName) {
901 // return propName === elemName; // TODO also check by namespace - redundancy?
903 // TODO also check by namespace - redundancy?
904 return (propName.indexOf(':') > -1 ? propName.split(':')[1] : propName) === elemName;
907 // TODO: add function's description
908 function equalArrays(arrA, arrB) {
909 var match = (arrA.length === arrB.length) && arrA.length > 0;
913 while (i < arrA.length && match) {
914 var valMatch = arrA[i] === arrB[i];
915 match = match && valMatch;
922 // TODO: add function's description
923 function equalListElems(listElemA, listElemB, refKey) {
924 var keyValuesA = getKeyArrayValues(listElemA, refKey),
925 keyValuesB = getKeyArrayValues(listElemB, refKey);
927 return equalArrays(keyValuesA, keyValuesB);
929 // TODO: add function's description
930 function getKeyValue(data, label, module) {
931 if (data && data.hasOwnProperty(label)) {
933 } else if (data && data.hasOwnProperty(module + ':' + label)) {
934 return data[module + ':' + label];
940 // TODO: add function's description
941 function getKeyArrayValues(data, refKey) {
942 return refKey.map(function (key) {
943 return getKeyValue(data, key.label, key.module);
944 }).filter(function (item) {
945 return item !== null;
950 // TODO: add function's description
951 function checkListElemKeys(listData, refKey) {
952 var doubleKeyIndexes = [],
955 listData.forEach(function (item, index) {
956 var duplitactes = checkedElems.filter(function (checked) {
957 var isDuplicate = equalListElems(item, checked.item, refKey);
958 if (isDuplicate && doubleKeyIndexes.indexOf(checked.index) === -1) {
959 doubleKeyIndexes.push(checked.index);
964 if (duplitactes.length) {
965 // item is already in checkedElems so we don't need to push it again
966 doubleKeyIndexes.push(index);
968 checkedElems.push({ index: index, item: item });
972 return doubleKeyIndexes;
975 // TODO: add function's description
976 function parseRestrictText(text) {
977 return text.split('|').map(function (elem) {
978 var subElems = elem.split('..');
979 return subElems.length === 1 ? RestrictionsService.getEqualsFnc(subElems[0]) :
980 RestrictionsService.getMinMaxFnc(subElems[0], subElems[1]);
984 // TODO: add function's description
985 function getTypes(node) {
988 var getTypesRecursive = function (node, types) {
991 node.getChildren('type').forEach(function (child) {
992 getTypesRecursive(child, types);
996 node.getChildren('type').forEach(function (child) {
997 // console.info('child', child);
998 getTypesRecursive(child, types);
1005 NodeWrapperService.$inject = ['constants', 'RequestBuilderService', 'RestrictionsService', 'TypeWrapperService',
1006 'ListFilteringService', 'EventDispatcherService', 'FilterNodeWrapperService'];
1008 return NodeWrapperService;