Commit ed5e5321 authored by lepdou's avatar lepdou

portal service unit test

parent 6a7477c2
......@@ -28,9 +28,11 @@ public class ItemDTO{
}
public ItemDTO(String key, String value) {
public ItemDTO(String key, String value, String comment, int lineNum) {
this.key = key;
this.value = value;
this.comment = comment;
this.lineNum = lineNum;
}
public String getComment() {
......
......@@ -49,15 +49,21 @@ public class AdminServiceAPI {
@Service
public static class NamespaceAPI extends API {
public List<NamespaceDTO> findGroupsByAppAndCluster(String appId, Env env,
public List<NamespaceDTO> findNamespaceByCluster(String appId, Env env,
String clusterName) {
if (StringUtils.isContainEmpty(appId, clusterName)) {
return null;
}
return Arrays.asList(restTemplate.getForObject(
NamespaceDTO[] namespaceDTOs = restTemplate.getForObject(
getAdminServiceHost(env) + String.format("apps/%s/clusters/%s/namespaces", appId, clusterName),
NamespaceDTO[].class));
NamespaceDTO[].class);
if (namespaceDTOs == null){
return Collections.emptyList();
}else {
return Arrays.asList(namespaceDTOs);
}
}
public NamespaceDTO loadNamespace(String appId, Env env,
......@@ -79,10 +85,16 @@ public class AdminServiceAPI {
return Collections.emptyList();
}
return Arrays.asList(restTemplate.getForObject(getAdminServiceHost(env) + String
ItemDTO[] itemDTOs = restTemplate.getForObject(getAdminServiceHost(env) + String
.format("apps/%s/clusters/%s/namespaces/%s/items", appId,
clusterName, namespace),
ItemDTO[].class));
ItemDTO[].class);
if (itemDTOs == null) {
return Collections.emptyList();
} else {
return Arrays.asList(itemDTOs);
}
}
public void updateItems(String appId, Env env, String clusterName, String namespace,
......@@ -106,9 +118,14 @@ public class AdminServiceAPI {
return null;
}
return Arrays
.asList(restTemplate.getForObject(getAdminServiceHost(env) + String.format("apps/%s/clusters", appId),
ClusterDTO[].class));
ClusterDTO[] clusterDTOs = restTemplate.getForObject(getAdminServiceHost(env) + String.format("apps/%s/clusters", appId),
ClusterDTO[].class);
if (clusterDTOs == null){
return Collections.emptyList();
}else {
return Arrays.asList(clusterDTOs);
}
}
}
......
......@@ -33,7 +33,7 @@ public class ConfigService {
private Logger logger = LoggerFactory.getLogger(ConfigService.class);
@Autowired
private AdminServiceAPI.NamespaceAPI groupAPI;
private AdminServiceAPI.NamespaceAPI namespaceAPI;
@Autowired
private AdminServiceAPI.ItemAPI itemAPI;
@Autowired
......@@ -54,7 +54,7 @@ public class ConfigService {
*/
public List<NamespaceVO> findNampspaces(String appId, Env env, String clusterName) {
List<NamespaceDTO> namespaces = groupAPI.findGroupsByAppAndCluster(appId, env, clusterName);
List<NamespaceDTO> namespaces = namespaceAPI.findNamespaceByCluster(appId, env, clusterName);
if (namespaces == null || namespaces.size() == 0) {
return Collections.emptyList();
}
......@@ -99,7 +99,7 @@ public class ConfigService {
}
}
//not createRelease config items
//not Release config items
List<ItemDTO> items = itemAPI.findItems(appId, env, clusterName, namespaceName);
int modifiedItemCnt = 0;
for (ItemDTO itemDTO : items) {
......
......@@ -147,11 +147,12 @@ public class PropertyResolver implements ConfigTextResolver {
}
private boolean isCommentItem(ItemDTO item) {
return item != null && "".equals(item.getKey()) && item.getComment().startsWith("#");
return item != null && "".equals(item.getKey())
&& (item.getComment().startsWith("#") || item.getComment().startsWith("!"));
}
private boolean isCommentItem(String line) {
return line != null && line.startsWith("#");
return line != null && (line.startsWith("#") || line.startsWith("!"));
}
private boolean isBlankItem(ItemDTO item) {
......@@ -196,13 +197,9 @@ public class PropertyResolver implements ConfigTextResolver {
}
private ItemDTO buildNormalItem(Long id, Long namespaceId, String key, String value, String comment, int lineNum) {
ItemDTO item = new ItemDTO();
ItemDTO item = new ItemDTO(key, value, comment, lineNum);
item.setId(id);
item.setNamespaceId(namespaceId);
item.setKey(key);
item.setValue(value);
item.setComment(comment);
item.setLineNum(lineNum);
return item;
}
}
ddd
<!doctype html>
<html ng-app="create_app">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<!-- styles -->
<link rel="stylesheet" type="text/css" href="vendor/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="vendor/angular/angular-toastr-1.4.1.min.css">
<link rel="stylesheet" type="text/css" media='all' href="vendor/angular/loading-bar.min.css">
<link rel="stylesheet" type="text/css" href="styles/common-style.css">
<title>apollo</title>
</head>
<body>
<div ng-include="'views/common/nav.html'"></div>
<div class="container-fluid apollo-container">
<div class="row">
<div class="col-lg-12 text-center">
<h1>welcome to apollo!~~</h1>
<img src="img/dolphin.jpg" style="width: 100px; height: 130px;"/>
<a class="btn btn-primary btn-lg" href="views/create-app.html" role="button">create app</a>
</div>
</div>
</div>
<div ng-include="'views/common/footer.html'"></div>
<!--angular-->
<script src="vendor/angular/angular.min.js"></script>
<script src="vendor/angular/angular-route.min.js"></script>
<script src="vendor/angular/angular-resource.min.js"></script>
<script src="vendor/angular/angular-toastr-1.4.1.tpls.min.js"></script>
<script src="vendor/angular/loading-bar.min.js"></script>
<!-- jquery.js -->
<script src="vendor/jquery.js" type="text/javascript"></script>
<!-- bootstrap.js -->
<script src="vendor/bootstrap/js/bootstrap.min.js" type="text/javascript"></script>
<script type="application/javascript" src="scripts/app.js"></script>
<script type="application/javascript" src="scripts/services/AppService.js"></script>
<script type="application/javascript" src="scripts/controller/CreateAppController.js"></script>
</body>
</html>
......@@ -11,6 +11,11 @@ a{
cursor: pointer;
}
.apollo-container{
min-height: 550px;
}
.footer {
height: 100px;
width: 100%;
......@@ -72,6 +77,13 @@ table th {
height: 500px;
overflow: scroll;
}
#editor {
position: relative;
width: 500px;
height: 400px;
}
.namespace-view-table{
max-height: 700px;
overflow: scroll;
......
This source diff could not be displayed because it is too large. You can view the blob instead.
/**
* angular-strap
* @version v2.2.2 - 2015-05-15
* @link http://mgcrea.github.io/angular-strap
* @author Olivier Louvignes <olivier@mg-crea.com> (https://github.com/mgcrea)
* @license MIT License, http://www.opensource.org/licenses/MIT
*/
!function (t, e, n) {
'use strict';
angular.module('mgcrea.ngStrap.alert').run(['$templateCache', function (t) {
t.put('alert/alert.tpl.html', '<div class="alert" ng-class="[type ? \'alert-\' + type : null]"><button type="button" class="close" ng-if="dismissable" ng-click="$hide()">&times;</button> <strong ng-bind="title"></strong>&nbsp;<span ng-bind-html="content"></span></div>')
}]), angular.module('mgcrea.ngStrap.aside').run(['$templateCache', function (t) {
t.put('aside/aside.tpl.html', '<div class="aside" tabindex="-1" role="dialog"><div class="aside-dialog"><div class="aside-content"><div class="aside-header" ng-show="title"><button type="button" class="close" ng-click="$hide()">&times;</button><h4 class="aside-title" ng-bind="title"></h4></div><div class="aside-body" ng-bind="content"></div><div class="aside-footer"><button type="button" class="btn btn-default" ng-click="$hide()">Close</button></div></div></div></div>')
}]), angular.module('mgcrea.ngStrap.datepicker').run(['$templateCache', function (t) {
t.put('datepicker/datepicker.tpl.html', '<div class="dropdown-menu datepicker" ng-class="\'datepicker-mode-\' + $mode" style="max-width: 320px"><table style="table-layout: fixed; height: 100%; width: 100%"><thead><tr class="text-center"><th><button tabindex="-1" type="button" class="btn btn-default pull-left" ng-click="$selectPane(-1)"><i class="{{$iconLeft}}"></i></button></th><th colspan="{{ rows[0].length - 2 }}"><button tabindex="-1" type="button" class="btn btn-default btn-block text-strong" ng-click="$toggleMode()"><strong style="text-transform: capitalize" ng-bind="title"></strong></button></th><th><button tabindex="-1" type="button" class="btn btn-default pull-right" ng-click="$selectPane(+1)"><i class="{{$iconRight}}"></i></button></th></tr><tr ng-show="showLabels" ng-bind-html="labels"></tr></thead><tbody><tr ng-repeat="(i, row) in rows" height="{{ 100 / rows.length }}%"><td class="text-center" ng-repeat="(j, el) in row"><button tabindex="-1" type="button" class="btn btn-default" style="width: 100%" ng-class="{\'btn-primary\': el.selected, \'btn-info btn-today\': el.isToday && !el.selected}" ng-click="$select(el.date)" ng-disabled="el.disabled"><span ng-class="{\'text-muted\': el.muted}" ng-bind="el.label"></span></button></td></tr></tbody></table></div>')
}]), angular.module('mgcrea.ngStrap.dropdown').run(['$templateCache', function (t) {
t.put('dropdown/dropdown.tpl.html', '<ul tabindex="-1" class="dropdown-menu" role="menu"><li role="presentation" ng-class="{divider: item.divider}" ng-repeat="item in content"><a role="menuitem" tabindex="-1" ng-href="{{item.href}}" ng-if="!item.divider && item.href" target="{{item.target || \'\'}}" ng-bind="item.text"></a> <a role="menuitem" tabindex="-1" href="javascript:void(0)" ng-if="!item.divider && item.click" ng-click="$eval(item.click);$hide()" ng-bind="item.text"></a></li></ul>')
}]), angular.module('mgcrea.ngStrap.modal').run(['$templateCache', function (t) {
t.put('modal/modal.tpl.html', '<div class="modal" tabindex="-1" role="dialog" aria-hidden="true"><div class="modal-dialog"><div class="modal-content"><div class="modal-header" ng-show="title"><button type="button" class="close" aria-label="Close" ng-click="$hide()"><span aria-hidden="true">&times;</span></button><h4 class="modal-title" ng-bind="title"></h4></div><div class="modal-body" ng-bind="content"></div><div class="modal-footer"><button type="button" class="btn btn-default" ng-click="$hide()">Close</button></div></div></div></div>')
}]), angular.module('mgcrea.ngStrap.popover').run(['$templateCache', function (t) {
t.put('popover/popover.tpl.html', '<div class="popover"><div class="arrow"></div><h3 class="popover-title" ng-bind="title" ng-show="title"></h3><div class="popover-content" ng-bind="content"></div></div>')
}]), angular.module('mgcrea.ngStrap.select').run(['$templateCache', function (t) {
t.put('select/select.tpl.html', '<ul tabindex="-1" class="select dropdown-menu" ng-show="$isVisible()" role="select"><li ng-if="$showAllNoneButtons"><div class="btn-group" style="margin-bottom: 5px; margin-left: 5px"><button type="button" class="btn btn-default btn-xs" ng-click="$selectAll()">{{$allText}}</button> <button type="button" class="btn btn-default btn-xs" ng-click="$selectNone()">{{$noneText}}</button></div></li><li role="presentation" ng-repeat="match in $matches" ng-class="{active: $isActive($index)}"><a style="cursor: default" role="menuitem" tabindex="-1" ng-click="$select($index, $event)"><i class="{{$iconCheckmark}} pull-right" ng-if="$isMultiple && $isActive($index)"></i> <span ng-bind="match.label"></span></a></li></ul>')
}]), angular.module('mgcrea.ngStrap.timepicker').run(['$templateCache', function (t) {
t.put('timepicker/timepicker.tpl.html', '<div class="dropdown-menu timepicker" style="min-width: 0px;width: auto"><table height="100%"><thead><tr class="text-center"><th><button tabindex="-1" type="button" class="btn btn-default pull-left" ng-click="$arrowAction(-1, 0)"><i class="{{ $iconUp }}"></i></button></th><th>&nbsp;</th><th><button tabindex="-1" type="button" class="btn btn-default pull-left" ng-click="$arrowAction(-1, 1)"><i class="{{ $iconUp }}"></i></button></th><th>&nbsp;</th><th><button ng-if="showSeconds" tabindex="-1" type="button" class="btn btn-default pull-left" ng-click="$arrowAction(-1, 2)"><i class="{{ $iconUp }}"></i></button></th></tr></thead><tbody><tr ng-repeat="(i, row) in rows"><td class="text-center"><button tabindex="-1" style="width: 100%" type="button" class="btn btn-default" ng-class="{\'btn-primary\': row[0].selected}" ng-click="$select(row[0].date, 0)" ng-disabled="row[0].disabled"><span ng-class="{\'text-muted\': row[0].muted}" ng-bind="row[0].label"></span></button></td><td><span ng-bind="i == midIndex ? timeSeparator : \' \'"></span></td><td class="text-center"><button tabindex="-1" ng-if="row[1].date" style="width: 100%" type="button" class="btn btn-default" ng-class="{\'btn-primary\': row[1].selected}" ng-click="$select(row[1].date, 1)" ng-disabled="row[1].disabled"><span ng-class="{\'text-muted\': row[1].muted}" ng-bind="row[1].label"></span></button></td><td><span ng-bind="i == midIndex ? timeSeparator : \' \'"></span></td><td class="text-center"><button tabindex="-1" ng-if="showSeconds && row[2].date" style="width: 100%" type="button" class="btn btn-default" ng-class="{\'btn-primary\': row[2].selected}" ng-click="$select(row[2].date, 2)" ng-disabled="row[2].disabled"><span ng-class="{\'text-muted\': row[2].muted}" ng-bind="row[2].label"></span></button></td><td ng-if="showAM">&nbsp;</td><td ng-if="showAM"><button tabindex="-1" ng-show="i == midIndex - !isAM * 1" style="width: 100%" type="button" ng-class="{\'btn-primary\': !!isAM}" class="btn btn-default" ng-click="$switchMeridian()" ng-disabled="el.disabled">AM</button> <button tabindex="-1" ng-show="i == midIndex + 1 - !isAM * 1" style="width: 100%" type="button" ng-class="{\'btn-primary\': !isAM}" class="btn btn-default" ng-click="$switchMeridian()" ng-disabled="el.disabled">PM</button></td></tr></tbody><tfoot><tr class="text-center"><th><button tabindex="-1" type="button" class="btn btn-default pull-left" ng-click="$arrowAction(1, 0)"><i class="{{ $iconDown }}"></i></button></th><th>&nbsp;</th><th><button tabindex="-1" type="button" class="btn btn-default pull-left" ng-click="$arrowAction(1, 1)"><i class="{{ $iconDown }}"></i></button></th><th>&nbsp;</th><th><button ng-if="showSeconds" tabindex="-1" type="button" class="btn btn-default pull-left" ng-click="$arrowAction(1, 2)"><i class="{{ $iconDown }}"></i></button></th></tr></tfoot></table></div>')
}]), angular.module('mgcrea.ngStrap.tab').run(['$templateCache', function (t) {
t.put('tab/tab.tpl.html', '<ul class="nav" ng-class="$navClass" role="tablist"><li role="presentation" ng-repeat="$pane in $panes track by $index" ng-class="[ $index == $panes.$active ? $activeClass : \'\', $pane.disabled ? \'disabled\' : \'\' ]"><a role="tab" data-toggle="tab" ng-click="!$pane.disabled && $setActive($index)" data-index="{{ $index }}" ng-bind-html="$pane.title" aria-controls="$pane.title"></a></li></ul><div ng-transclude class="tab-content"></div>')
}]), angular.module('mgcrea.ngStrap.tooltip').run(['$templateCache', function (t) {
t.put('tooltip/tooltip.tpl.html', '<div class="tooltip in" ng-show="title"><div class="tooltip-arrow"></div><div class="tooltip-inner" ng-bind="title"></div></div>')
}]), angular.module('mgcrea.ngStrap.typeahead').run(['$templateCache', function (t) {
t.put('typeahead/typeahead.tpl.html', '<ul tabindex="-1" class="typeahead dropdown-menu" ng-show="$isVisible()" role="select"><li role="presentation" ng-repeat="match in $matches" ng-class="{active: $index == $activeIndex}"><a role="menuitem" tabindex="-1" ng-click="$select($index, $event)" ng-bind="match.label"></a></li></ul>')
}])
}(window, document);
"use strict";
angular.module("lr.upload", ["lr.upload.formdata", "lr.upload.iframe", "lr.upload.directives"]), angular.module("lr.upload.directives", []), angular.module("lr.upload.directives").directive("uploadButton", ["upload", function (a) {
return {
restrict: "EA",
scope: {
data: "=?data",
url: "@",
id: "@",
param: "@",
method: "@",
onUpload: "&",
onSuccess: "&",
onError: "&",
onComplete: "&"
},
link: function (b, c, d) {
var e = angular.element(c), f = angular.element('<input id="' + b.id + '" type="file" />');
if (e.append(f), f.on("change", function () {
var c = angular.element(this);
if (!c[0].files || 0 !== c[0].files.length) {
var e = {
url: b.url,
method: b.method || "POST",
forceIFrameUpload: b.$eval(d.forceIframeUpload) || !1,
data: b.data || {}
};
e.data[b.param || "file"] = c, b.$apply(function () {
b.onUpload({files: c[0].files})
}), a(e).then(function (a) {
b.onSuccess({response: a}), b.onComplete({response: a})
}, function (a) {
b.onError({response: a}), b.onComplete({response: a})
})
}
}), "required" in d && d.$observe("required", function (a) {
var d = "" === a ? !0 : b.$eval(a);
f.attr("required", d), c.toggleClass("ng-valid", !d), c.toggleClass("ng-invalid ng-invalid-required", d)
}), "accept" in d && d.$observe("accept", function (a) {
f.attr("accept", a)
}), a.support.formData) {
var g = function () {
f.attr("multiple", !(!b.$eval(d.multiple) || b.$eval(d.forceIframeUpload)))
};
d.$observe("multiple", g), d.$observe("forceIframeUpload", g)
}
}
}
}]), angular.module("lr.upload.formdata", []).factory("formDataTransform", function () {
return function (a) {
var b = new FormData;
return angular.forEach(a, function (a, c) {
if (angular.isElement(a)) {
var d = [];
angular.forEach(a, function (a) {
angular.forEach(a.files, function (a) {
d.push(a)
}), a.value = ""
}), 0 !== d.length && (d.length > 1 ? angular.forEach(d, function (a, d) {
b.append(c + "[" + d + "]", a)
}) : b.append(c, d[0]))
} else b.append(c, a)
}), b
}
}).factory("formDataUpload", ["$http", "formDataTransform", function (a, b) {
return function (c) {
return c.transformRequest = b, c.method = c.method || "POST", c.headers = angular.extend(c.headers || {}, {"Content-Type": void 0}), a(c)
}
}]), angular.module("lr.upload.iframe", []).factory("iFrameUpload", ["$q", "$http", "$document", "$rootScope", function (a, b, c, d) {
function e(a, b) {
if (a.indexOf)return a.indexOf(b);
for (var c = 0; c < a.length; c++)if (b === a[c])return c;
return -1
}
function f(f) {
var g = [], h = a.defer(), i = h.promise;
angular.forEach(f.data || {}, function (a, b) {
angular.isElement(a) && (delete f.data[b], a.attr("name", b), g.push(a))
});
var j = /\?/.test(f.url) ? "&" : "?";
"DELETE" === f.method ? (f.url = f.url + j + "_method=DELETE", f.method = "POST") : "PUT" === f.method ? (f.url = f.url + j + "_method=PUT", f.method = "POST") : "PATCH" === f.method && (f.url = f.url + j + "_method=PATCH", f.method = "POST");
var k = angular.element(c[0].body), l = d.$new(), m = "iframe-transport-" + l.$id;
l.$destroy();
var n = angular.element("<form></form>");
n.attr("target", m), n.attr("action", f.url), n.attr("method", f.method || "POST"), n.css("display", "none"), g.length && (n.attr("enctype", "multipart/form-data"), n.attr("encoding", "multipart/form-data"));
var o = angular.element('<iframe name="' + m + '" src="javascript:false;"></iframe>');
return o.on("load", function () {
function a(a, b) {
var c = [];
return angular.isFunction(b) ? b(a, c) : (angular.forEach(b, function (b) {
a = b(a, c)
}), a)
}
function c() {
var a = e(b.pendingRequests, f);
-1 !== a && (b.pendingRequests.splice(a, 1), f.$iframeTransportForm.remove(), delete f.$iframeTransportForm)
}
o.off("load").on("load", function () {
var c;
try {
var d = this.contentWindow ? this.contentWindow.document : this.contentDocument;
if (c = angular.element(d.body).text(), !c.length)throw new Error
} catch (e) {
}
n.append(angular.element('<iframe src="javascript:false;"></iframe>'));
try {
c = a(c, b.defaults.transformResponse)
} catch (e) {
}
h.resolve({data: c, status: 200, headers: [], config: f})
}), angular.forEach(f.data, function (a, b) {
var c = angular.element('<input type="hidden" />');
c.attr("name", b), c.val(a), n.append(c)
}), angular.forEach(g, function (a) {
var b = a.clone(!0);
a.after(b), n.append(a)
}), f.$iframeTransportForm = n, b.pendingRequests.push(f), n[0].submit(), i.then(c, c)
}), n.append(o), k.append(n), i
}
return f
}]), angular.module("lr.upload").factory("upload", ["$window", "formDataUpload", "iFrameUpload", function (a, b, c) {
function d(a) {
return e.formData && !a.forceIFrameUpload ? b(a) : c(a)
}
var e = {
fileInput: !(new RegExp("(Android (1\\.[0156]|2\\.[01]))|(Windows Phone (OS 7|8\\.0))|(XBLWP)|(ZuneWP)|(WPDesktop)|(w(eb)?OSBrowser)|(webOS)|(Kindle/(1\\.0|2\\.[05]|3\\.0))").test(a.navigator.userAgent) || angular.element('<input type="file">').prop("disabled")),
fileUpload: !(!a.XMLHttpRequestUpload || !a.FileReader),
formData: !!a.FormData
};
return d.support = e, d
}]);
/*! ngTable v1.0.0-beta.9 by Vitalii Savchuk(esvit666@gmail.com) - https://github.com/esvit/ng-table - New BSD License */
!function(a,b){"use strict";return"function"==typeof define&&define.amd?void define(["angular"],function(a){return b(a)}):b(a)}(window.angular||null,function(a){"use strict";return function(){a.module("ngTable",[])}(),function(){a.module("ngTable").value("ngTableDefaults",{params:{},settings:{}})}(),function(){function b(b){function c(b,c){var f=b.charAt(0).toUpperCase()+b.substring(1),g={};return g["on"+f]=d(b),g["publish"+f]=e(b),a.extend(c,g)}function d(c){return function(d){var e=a.identity,g=b;if(2===arguments.length?a.isFunction(arguments[1].$new)?g=arguments[1]:e=arguments[1]:arguments.length>2&&(g=arguments[1],e=arguments[2]),a.isObject(e)){var h=e;e=function(a){return a===h}}return g.$on("ngTable:"+c,function(a,b){if(!b.isNullInstance){var c=f(arguments,2),g=[b].concat(c);e.apply(this,g)&&d.apply(this,g)}})}}function e(a){return function(){var c=["ngTable:"+a].concat(Array.prototype.slice.call(arguments));b.$broadcast.apply(b,c)}}function f(a,b){return Array.prototype.slice.call(a,null==b?1:b)}var g={};return g=c("afterCreated",g),g=c("afterReloadData",g),g=c("datasetChanged",g),g=c("pagesChanged",g)}a.module("ngTable").factory("ngTableEventsChannel",b),b.$inject=["$rootScope"]}(),function(){function b(){function b(){c()}function c(){f=g}function d(b){var c=a.extend({},f,b);c.aliasUrls=a.extend({},f.aliasUrls,b.aliasUrls),f=c}function e(){function b(b,c){return a.isObject(b)&&(b=b.id),-1!==b.indexOf("/")?b:e.getUrlForAlias(b,c)}function c(a){return f.aliasUrls[a]||f.defaultBaseUrl+a+f.defaultExt}var d,e={config:d,getTemplateUrl:b,getUrlForAlias:c};return Object.defineProperty(e,"config",{get:function(){return d=d||a.copy(f)},enumerable:!0}),e}var f,g={defaultBaseUrl:"ng-table/filters/",defaultExt:".html",aliasUrls:{}};this.$get=e,this.resetConfigs=c,this.setConfig=d,b(),e.$inject=[]}a.module("ngTable").provider("ngTableFilterConfig",b),b.$inject=[]}(),function(){function b(){function b(b){function d(d){var e=d.settings().filterOptions;return a.isFunction(e.filterFn)?e.filterFn:b(e.filterFilterName||c.filterFilterName)}function e(){return b(c.sortingFilterName)}function f(a,b){if(!b.hasFilter())return a;var c=b.filter(!0),e=Object.keys(c),f=e.reduce(function(a,b){return a=j(a,c[b],b)},{}),g=d(b);return g.call(b,a,f,b.settings().filterOptions.filterComparator)}function g(a,b){var c=a.slice((b.page()-1)*b.count(),b.page()*b.count());return b.total(a.length),c}function h(a,b){var c=b.orderBy(),d=e(b);return c.length?d(a,c):a}function i(b,c){if(null==b)return[];var d=a.extend({},k,c.settings().dataOptions),e=d.applyFilter?f(b,c):b,i=d.applySort?h(e,c):e;return d.applyPaging?g(i,c):i}function j(a,b,c){var d=c.split("."),e=a,f=d[d.length-1],g=e,h=d.slice(0,d.length-1);return h.forEach(function(a){g.hasOwnProperty(a)||(g[a]={}),g=g[a]}),g[f]=b,e}var k={applyFilter:!0,applySort:!0,applyPaging:!0};return i.applyPaging=g,i.getFilterFn=d,i.getOrderByFn=e,i}var c=this;c.$get=b,c.filterFilterName="filter",c.sortingFilterName="orderBy",b.$inject=["$filter"]}a.module("ngTable").provider("ngTableDefaultGetData",b),b.$inject=[]}(),function(){function b(a){function b(b){return function(){var c=a.defer(),d=b.apply(this,[c].concat(Array.prototype.slice.call(arguments)));return d||(d=c.promise),d}}return b}a.module("ngTable").factory("ngTableGetDataBcShim",b),b.$inject=["$q"]}(),function(){a.module("ngTable").factory("ngTableColumn",[function(){function b(b,d,f){var g=Object.create(b),h=c();for(var i in h)void 0===g[i]&&(g[i]=h[i]),a.isFunction(g[i])||!function(a){var c=function d(){return 1!==arguments.length||e(arguments[0])?b[a]:void d.assign(null,arguments[0])};c.assign=function(c,d){b[a]=d},g[a]=c}(i),function(c){var h=g[c];g[c]=function(){if(1!==arguments.length||e(arguments[0])){var c=arguments[0]||d,i=Object.create(c);return a.extend(i,{$column:g,$columns:f}),h.call(b,i)}h.assign(null,arguments[0])},h.assign&&(g[c].assign=h.assign)}(i);return g}function c(){return{"class":d(""),filter:d(!1),groupable:d(!1),filterData:a.noop,headerTemplateURL:d(!1),headerTitle:d(""),sortable:d(!1),show:d(!0),title:d(""),titleAlt:d("")}}function d(a){var b=a,c=function d(){return 1!==arguments.length||e(arguments[0])?b:void d.assign(null,arguments[0])};return c.assign=function(a,c){b=c},c}function e(b){return null!=b&&a.isFunction(b.$new)}return{buildColumn:b}}])}(),function(){a.module("ngTable").factory("NgTableParams",["$q","$log","$filter","ngTableDefaults","ngTableGetDataBcShim","ngTableDefaultGetData","ngTableEventsChannel",function(b,c,d,e,f,g,h){var i=function(a){return!isNaN(parseFloat(a))&&isFinite(a)},j=function(d,j){function k(b){var c=D.groupOptions&&D.groupOptions.defaultSort;if(a.isFunction(b))return null==b.sortDirection&&(b.sortDirection=c),b;if(a.isString(b)){var d={};return d[b]=c,d}if(a.isObject(b)){for(var e in b)null==b[e]&&(b[e]=c);return b}return b}function l(a){var b=[];for(var c in a)b.push(("asc"===a[c]?"+":"-")+c);return b}function m(){var b={params:C};return a.isFunction(C.group)&&(b.groupSortDirection=C.group.sortDirection),b}function n(){var b=C.filter&&C.filter.$,c=t&&t.params.filter&&t.params.filter.$;return!a.equals(b,c)}function o(){D.filterOptions.filterDelay===z.filterDelay&&D.total<=D.filterOptions.filterDelayThreshold&&D.getData===B.getData&&(D.filterOptions.filterDelay=0)}function p(){var a=D.getDataFnAdaptor(D.getData);return b.when(a.call(D,v))}function q(){var a=D.getGroupsFnAdaptor(D.getGroups);return b.when(a.call(D,v))}function r(a){var c=D.interceptors||[];return c.reduce(function(a,c){var d=c.response&&c.response.bind(c)||b.when,e=c.responseError&&c.responseError.bind(c)||b.reject;return a.then(function(a){return d(a,v)},function(a){return e(a,v)})},a())}function s(){function c(a){return g(a.settings().dataset,a)}function d(c){var d,f=c.group(),h=void 0;if(a.isFunction(f))d=f,h=f.sortDirection;else{var i=Object.keys(f)[0];h=f[i],d=function(a){return e(a,i)}}var j=c.settings(),k=j.dataOptions;j.dataOptions={applyPaging:!1};var m=j.getDataFnAdaptor(j.getData),n=b.when(m.call(j,c));return n.then(function(b){var e={};a.forEach(b,function(a){var b=d(a);e[b]=e[b]||{data:[],$hideRows:!j.groupOptions.isExpanded,value:b},e[b].data.push(a)});var f=[];for(var i in e)f.push(e[i]);if(h){var k=g.getOrderByFn(),m=l({value:h});f=k(f,m)}return g.applyPaging(f,c)})["finally"](function(){j.dataOptions=k})}function e(a,b){return"string"==typeof b&&(b=b.split(".")),void 0===a?void 0:0===b.length?a:null===a?void 0:e(a[b[0]],b.slice(1))}return{getDataFnAdaptor:a.identity,getGroupsFnAdaptor:a.identity,getData:c,getGroups:d}}"boolean"==typeof d&&(this.isNullInstance=!0);var t,u,v=this,w=!1,x=[],y=function(){D.debugMode&&c.debug&&c.debug.apply(c,arguments)},z={filterComparator:void 0,filterDelay:500,filterDelayThreshold:1e4,filterFilterName:void 0,filterFn:void 0,filterLayout:"stack"},A={defaultSort:"asc",isExpanded:!0},B=s();this.data=[],this.parameters=function(b,c){if(c=c||!1,a.isDefined(b)){for(var d in b){var e=b[d];if(c&&d.indexOf("[")>=0){for(var f=d.split(/\[(.*)\]/).reverse(),g="",h=0,j=f.length;j>h;h++){var l=f[h];if(""!==l){var m=e;e={},e[g=l]=i(m)?parseFloat(m):m}}"sorting"===g&&(C[g]={}),C[g]=a.extend(C[g]||{},e[g])}else C[d]="group"===d?k(b[d]):i(b[d])?parseFloat(b[d]):b[d]}return y("ngTable: set parameters",C),this}return C},this.settings=function(b){if(a.isDefined(b)){b.filterOptions&&(b.filterOptions=a.extend({},D.filterOptions,b.filterOptions)),b.groupOptions&&(b.groupOptions=a.extend({},D.groupOptions,b.groupOptions)),a.isArray(b.dataset)&&(b.total=b.dataset.length),b.getData&&b.getData.length>1&&(b.getDataFnAdaptor=f),b.getGroups&&b.getGroups.length>2&&(b.getGroupsFnAdaptor=f);var c=D.dataset;D=a.extend(D,b),a.isArray(b.dataset)&&o();var d=b.hasOwnProperty("dataset")&&b.dataset!=c;if(d){w&&this.page(1),w=!1;var e=function(){h.publishDatasetChanged(v,b.dataset,c)};x?x.push(e):e()}return y("ngTable: set settings",D),this}return D},this.page=function(b){return a.isDefined(b)?this.parameters({page:b}):C.page},this.total=function(b){return a.isDefined(b)?this.settings({total:b}):D.total},this.count=function(b){return a.isDefined(b)?this.parameters({count:b,page:1}):C.count},this.filter=function(b){if(a.isDefined(b)&&a.isObject(b))return this.parameters({filter:b,page:1});if(b===!0){for(var c=Object.keys(C.filter),d={},e=0;e<c.length;e++){var f=C.filter[c[e]];null!=f&&""!==f&&(d[c[e]]=f)}return d}return C.filter},this.group=function(b,c){if(!a.isDefined(b))return C.group;var d={page:1};if(a.isFunction(b)&&a.isDefined(c))b.sortDirection=c,d.group=b;else if(a.isDefined(b)&&a.isDefined(c)){var e={};e[b]=c,d.group=e}else d.group=b;return this.parameters(d),this},this.sorting=function(b){if(2==arguments.length){var c={};return c[b]=arguments[1],this.parameters({sorting:c}),this}return a.isDefined(b)?this.parameters({sorting:b}):C.sorting},this.isSortBy=function(b,c){return void 0!==c?a.isDefined(C.sorting[b])&&C.sorting[b]==c:a.isDefined(C.sorting[b])},this.orderBy=function(){return l(C.sorting)},this.generatePagesArray=function(a,b,c,d){arguments.length||(a=this.page(),b=this.total(),c=this.count());var e,f,g,h,i;if(d=d&&6>d?6:d,i=[],h=Math.ceil(b/c),h>1){i.push({type:"prev",number:Math.max(1,a-1),active:a>1}),i.push({type:"first",number:1,active:a>1,current:1===a}),f=Math.round((D.paginationMaxBlocks-D.paginationMinBlocks)/2),g=Math.max(2,a-f),e=Math.min(h-1,a+2*f-(a-g)),g=Math.max(2,g-(2*f-(e-g)));for(var j=g;e>=j;)i.push(j===g&&2!==j||j===e&&j!==h-1?{type:"more",active:!1}:{type:"page",number:j,active:a!==j,current:a===j}),j++;i.push({type:"last",number:h,active:a!==h,current:a===h}),i.push({type:"next",number:Math.min(h,a+1),active:h>a})}return i},this.isDataReloadRequired=function(){return!w||!a.equals(m(),t)||n()},this.hasFilter=function(){return Object.keys(this.filter(!0)).length>0},this.hasGroup=function(b,c){return null==b?a.isFunction(C.group)||Object.keys(C.group).length>0:a.isFunction(b)?null==c?C.group===b:C.group===b&&b.sortDirection===c:null==c?-1!==Object.keys(C.group).indexOf(b):C.group[b]===c},this.hasFilterChanges=function(){var b=t&&t.params.filter;return!a.equals(C.filter,b)||n()},this.url=function(b){function c(a,c){b?e.push(c+"="+encodeURIComponent(a)):e[c]=encodeURIComponent(a)}function d(b,c){return"group"===c?!0:a.isDefined(b)&&""!==b}b=b||!1;var e=b?[]:{};for(var f in C)if(C.hasOwnProperty(f)){var g=C[f],h=encodeURIComponent(f);if("object"==typeof g){for(var i in g)if(d(g[i],f)){var j=h+"["+encodeURIComponent(i)+"]";c(g[i],j)}}else!a.isFunction(g)&&d(g,f)&&c(g,h)}return e},this.reload=function(){var c=this,d=null;D.$loading=!0,t=a.copy(m()),w=!0,d=r(c.hasGroup()?q:p),y("ngTable: reload data");var e=c.data;return d.then(function(a){return D.$loading=!1,u=null,c.data=a,h.publishAfterReloadData(c,a,e),c.reloadPages(),D.$scope&&D.$scope.$emit("ngTableAfterReloadData"),a})["catch"](function(a){return u=t,b.reject(a)})},this.hasErrorState=function(){return!(!u||!a.equals(u,m()))},this.reloadPages=function(){var b;return function(){var c=b,d=v.generatePagesArray(v.page(),v.total(),v.count());a.equals(c,d)||(b=d,h.publishPagesChanged(this,d,c))}}();var C={page:1,count:10,filter:{},sorting:{},group:{}};a.extend(C,e.params);var D={$scope:null,$loading:!1,dataset:null,total:0,defaultSort:"desc",filterOptions:a.copy(z),groupOptions:a.copy(A),counts:[10,25,50,100],interceptors:[],paginationMaxBlocks:11,paginationMinBlocks:5,sortingIndicator:"span"};return this.settings(B),this.settings(e.settings),this.settings(j),this.parameters(d,!0),h.publishAfterCreated(this),a.forEach(x,function(a){a()}),x=null,this};return j}]),a.module("ngTable").factory("ngTableParams",["NgTableParams",function(a){return a}])}(),function(){a.module("ngTable").controller("ngTableController",["$scope","NgTableParams","$timeout","$parse","$compile","$attrs","$element","ngTableColumn","ngTableEventsChannel",function(b,c,d,e,f,g,h,i,j){function k(a){if(a&&!b.params.hasErrorState()){b.params.settings().$scope=b;var c=b.params,d=c.settings().filterOptions;if(c.hasFilterChanges()){var e=function(){c.page(1),c.reload()};d.filterDelay?r(e,d.filterDelay):e()}else c.reload()}}function l(){g.showFilter?b.$parent.$watch(g.showFilter,function(a){b.show_filter=a}):b.$watch(o,function(a){b.show_filter=a}),g.disableFilter&&b.$parent.$watch(g.disableFilter,function(a){b.$filterRow.disabled=a})}function m(){if(b.$groupRow={},g.showGroup){var a=e(g.showGroup);b.$parent.$watch(a,function(a){b.$groupRow.show=a}),a.assign&&b.$watch("$groupRow.show",function(c){a.assign(b.$parent,c)})}else b.$watch("params.hasGroup()",function(a){b.$groupRow.show=a})}function n(){return(b.$columns||[]).filter(function(a){return a.show(b)})}function o(){return b.$columns?p(b.$columns,function(a){return a.show(b)&&a.filter(b)}):!1}function p(a,b){for(var c=!1,d=0;d<a.length;d++){var e=a[d];if(b(e)){c=!0;break}}return c}function q(){function a(a,c){var d=n();a.hasGroup()?(b.$groups=c||[],b.$groups.visibleColumnCount=d.length):(b.$data=c||[],b.$data.visibleColumnCount=d.length)}function c(a,c){b.pages=c}function d(a){return b.params===a}j.onAfterReloadData(a,b,d),j.onPagesChanged(c,b,d)}b.$filterRow={},b.$loading=!1,b.hasOwnProperty("params")||(b.params=new c(!0)),b.params.settings().$scope=b;var r=function(){var a=0;return function(b,c){d.cancel(a),a=d(b,c)}}();b.$watch("params",function(a,b){a!==b&&a&&a.reload()},!1),b.$watch("params.isDataReloadRequired()",k),this.compileDirectiveTemplates=function(){if(!h.hasClass("ng-table")){b.templates={header:g.templateHeader?g.templateHeader:"ng-table/header.html",pagination:g.templatePagination?g.templatePagination:"ng-table/pager.html"},h.addClass("ng-table");var c=null,d=!1;a.forEach(h.children(),function(a){"THEAD"===a.tagName&&(d=!0)}),d||(c=a.element(document.createElement("thead")).attr("ng-include","templates.header"),h.prepend(c));var e=a.element(document.createElement("div")).attr({"ng-table-pagination":"params","template-url":"templates.pagination"});h.after(e),c&&f(c)(b),f(e)(b)}},this.loadFilterData=function(c){a.forEach(c,function(c){var d;if(d=c.filterData(b),!d)return void delete c.filterData;if(a.isObject(d)&&(a.isObject(d.promise)||a.isFunction(d.then))){var e=a.isFunction(d.then)?d:d.promise;return delete c.filterData,e.then(function(b){a.isArray(b)||a.isFunction(b)||a.isObject(b)||(b=[]),c.data=b})}return c.data=d})},this.buildColumns=function(a){var c=[];return(a||[]).forEach(function(a){c.push(i.buildColumn(a,b,c))}),c},this.parseNgTableDynamicExpr=function(a){if(!a||a.indexOf(" with ")>-1){var b=a.split(/\s+with\s+/);return{tableParams:b[0],columns:b[1]}}throw new Error("Parse error (expected example: ng-table-dynamic='tableParams with cols')")},this.setupBindingsToInternalScope=function(c){var d=e(c);b.$watch(d,function(c){a.isUndefined(c)||(b.paramsModel=d,b.params=c)},!1),l(),m()},q()}])}(),function(){a.module("ngTable").directive("ngTable",["$q","$parse",function(b,c){return{restrict:"A",priority:1001,scope:!0,controller:"ngTableController",compile:function(b){var d,e,f=[],g=0,h=[];return a.forEach(b.find("tr"),function(b){h.push(a.element(b))}),d=h.filter(function(a){return!a.hasClass("ng-table-group")})[0],e=h.filter(function(a){return a.hasClass("ng-table-group")})[0],d?(a.forEach(d.find("td"),function(b){var d=a.element(b);if(!d.attr("ignore-cell")||"true"!==d.attr("ignore-cell")){var h=function(a){return d.attr("x-data-"+a)||d.attr("data-"+a)||d.attr(a)},i=function(a,b){d.attr("x-data-"+a)?d.attr("x-data-"+a,b):d.attr("data"+a)?d.attr("data"+a,b):d.attr(a,b)},j=function(a){var b=h(a);if(!b)return void 0;var d,e=function(a){return void 0!==d?d:c(b)(a)};return e.assign=function(a,e){var f=c(b);f.assign?f.assign(a.$parent,e):d=e},e},k=h("title-alt")||h("title");k&&d.attr("data-title-text","{{"+k+"}}"),f.push({id:g++,title:j("title"),titleAlt:j("title-alt"),headerTitle:j("header-title"),sortable:j("sortable"),"class":j("header-class"),filter:j("filter"),groupable:j("groupable"),headerTemplateURL:j("header"),filterData:j("filter-data"),show:d.attr("ng-if")?j("ng-if"):void 0}),(e||d.attr("ng-if"))&&i("ng-if","$columns["+(f.length-1)+"].show(this)")}}),function(a,b,c,d){a.$columns=f=d.buildColumns(f),d.setupBindingsToInternalScope(c.ngTable),d.loadFilterData(f),d.compileDirectiveTemplates()}):void 0}}}])}(),function(){a.module("ngTable").directive("ngTableDynamic",[function(){return{restrict:"A",priority:1001,scope:!0,controller:"ngTableController",compile:function(b){var c;return a.forEach(b.find("tr"),function(b){b=a.element(b),b.hasClass("ng-table-group")||c||(c=b)}),c?(a.forEach(c.find("td"),function(b){var c=a.element(b),d=function(a){return c.attr("x-data-"+a)||c.attr("data-"+a)||c.attr(a)},e=d("title");e||c.attr("data-title-text","{{$columns[$index].titleAlt(this) || $columns[$index].title(this)}}");var f=c.attr("ng-if");f||c.attr("ng-if","$columns[$index].show(this)")}),function(a,b,c,d){var e=d.parseNgTableDynamicExpr(c.ngTableDynamic);d.setupBindingsToInternalScope(e.tableParams),d.compileDirectiveTemplates(),a.$watchCollection(e.columns,function(b){a.$columns=d.buildColumns(b),d.loadFilterData(a.$columns)})}):void 0}}}])}(),function(){function b(a){function b(b,c,d){var e=a(d.ngTableColumnsBinding).assign;e&&b.$watch("$columns",function(a){var c=(a||[]).slice(0);e(b,c)})}var c={restrict:"A",require:"ngTable",link:b};return c}a.module("ngTable").directive("ngTableColumnsBinding",b),b.$inject=["$parse"]}(),function(){a.module("ngTable").directive("ngTablePagination",["$compile","ngTableEventsChannel",function(b,c){return{restrict:"A",scope:{params:"=ngTablePagination",templateUrl:"="},replace:!1,link:function(d,e){c.onAfterReloadData(function(a){d.pages=a.generatePagesArray()},d,function(a){return a===d.params}),d.$watch("templateUrl",function(c){if(!a.isUndefined(c)){var f=a.element(document.createElement("div"));f.attr({"ng-include":"templateUrl"}),e.append(f),b(f)(d)}})}}}])}(),function(){function b(b,c){b.config=c,b.getFilterCellCss=function(a,b){if("horizontal"!==b)return"s12";var c=Object.keys(a).length,d=parseInt(12/c,10);return"s"+d},b.getFilterPlaceholderValue=function(b){return a.isObject(b)?b.placeholder:""}}a.module("ngTable").controller("ngTableFilterRowController",b),b.$inject=["$scope","ngTableFilterConfig"]}(),function(){function b(){var a={restrict:"E",replace:!0,templateUrl:"ng-table/filterRow.html",scope:!0,controller:"ngTableFilterRowController"};return a}a.module("ngTable").directive("ngTableFilterRow",b),b.$inject=[]}(),function(){function b(b){function c(){b.getGroupables=g,b.getGroupTitle=f,b.getVisibleColumns=h,b.groupBy=i,b.isSelectedGroup=j,b.toggleDetail=l,b.$watch("params.group()",k,!0)}function d(){var a;a=b.params.hasGroup(b.$selGroup,"asc")?"desc":b.params.hasGroup(b.$selGroup,"desc")?"":"asc",b.params.group(b.$selGroup,a)}function e(a){return b.$columns.filter(function(c){return c.groupable(b)===a})[0]}function f(c){return a.isFunction(c)?c.title:c.title(b)}function g(){var a=b.$columns.filter(function(a){return a.groupable(b)});return m.concat(a)}function h(){return b.$columns.filter(function(a){return a.show(b)})}function i(a){j(a)?d():b.params.group(a.groupable?a.groupable(b):a)}function j(a){return a.groupable?a.groupable(b)===b.$selGroup:a===b.$selGroup}function k(c){var d=e(b.$selGroup);if(d&&d.show.assign&&d.show.assign(b,!0),a.isFunction(c))m=[c],b.$selGroup=c,b.$selGroupTitle=c.title;else{var f=Object.keys(c||{})[0],g=e(f);g&&(b.$selGroupTitle=g.title(b),b.$selGroup=f,g.show.assign&&g.show.assign(b,!1))}}function l(){return b.params.settings().groupOptions.isExpanded=!b.params.settings().groupOptions.isExpanded,b.params.reload()}var m=[];c()}a.module("ngTable").controller("ngTableGroupRowController",b),b.$inject=["$scope"]}(),function(){function b(){var a={restrict:"E",replace:!0,templateUrl:"ng-table/groupRow.html",scope:!0,controller:"ngTableGroupRowController",controllerAs:"dctrl"};return a}a.module("ngTable").directive("ngTableGroupRow",b),b.$inject=[]}(),function(){function b(a){function b(b,c){var d=b.sortable&&b.sortable();if(d){var e=a.params.settings().defaultSort,f="asc"===e?"desc":"asc",g=a.params.sorting()&&a.params.sorting()[d]&&a.params.sorting()[d]===e,h=c.ctrlKey||c.metaKey?a.params.sorting():{};h[d]=g?f:e,a.params.parameters({sorting:h})}}a.sortBy=b}a.module("ngTable").controller("ngTableSorterRowController",b),b.$inject=["$scope"]}(),function(){function b(){var a={restrict:"E",replace:!0,templateUrl:"ng-table/sorterRow.html",scope:!0,controller:"ngTableSorterRowController"};return a}a.module("ngTable").directive("ngTableSorterRow",b),b.$inject=[]}(),function(){function b(){var a={restrict:"A",controller:c};return a}function c(b,c,d,e){function f(){j=c(d.ngTableSelectFilterDs)(b),b.$watch(function(){return j.data},g)}function g(){i(j).then(function(a){a&&!h(a)&&a.unshift({id:"",title:""}),a=a||[],b.$selectData=a})}function h(a){for(var b,c=0;c<a.length;c++){var d=a[c];if(d&&""===d.id){b=!0;break}}return b}function i(b){var c=a.isFunction(b.data)?b.data():b.data;return e.when(c)}var j={};f()}a.module("ngTable").directive("ngTableSelectFilterDs",b),b.$inject=[],c.$inject=["$scope","$parse","$attrs","$q"]}(),a.module("ngTable").run(["$templateCache",function(a){a.put("ng-table/filterRow.html",'<tr ng-show="show_filter" class="ng-table-filters"> <th data-title-text="{{$column.titleAlt(this) || $column.title(this)}}" ng-repeat="$column in $columns" ng-if="$column.show(this)" class="filter {{$column.class(this)}}" ng-class="params.settings().filterOptions.filterLayout===\'horizontal\' ? \'filter-horizontal\' : \'\'"> <div ng-repeat="(name, filter) in $column.filter(this)" ng-include="config.getTemplateUrl(filter)" class="filter-cell" ng-class="[getFilterCellCss($column.filter(this), params.settings().filterOptions.filterLayout), $last ? \'last\' : \'\']"> </div> </th> </tr> '),a.put("ng-table/filters/number.html",'<input type="number" name="{{name}}" ng-disabled="$filterRow.disabled" ng-model="params.filter()[name]" class="input-filter form-control" placeholder="{{getFilterPlaceholderValue(filter, name)}}"/> '),a.put("ng-table/filters/select-multiple.html",'<select ng-options="data.id as data.title for data in $column.data" ng-disabled="$filterRow.disabled" multiple ng-multiple="true" ng-model="params.filter()[name]" class="filter filter-select-multiple form-control" name="{{name}}"> </select> '),a.put("ng-table/filters/select.html",'<select ng-options="data.id as data.title for data in $selectData" ng-table-select-filter-ds="$column" ng-disabled="$filterRow.disabled" ng-model="params.filter()[name]" class="filter filter-select form-control" name="{{name}}"> <option style="display:none" value=""></option> </select> '),a.put("ng-table/filters/text.html",'<input type="text" name="{{name}}" ng-disabled="$filterRow.disabled" ng-model="params.filter()[name]" class="input-filter form-control" placeholder="{{getFilterPlaceholderValue(filter, name)}}"/> '),a.put("ng-table/groupRow.html",'<tr ng-if="params.hasGroup()" ng-show="$groupRow.show" class="ng-table-group-header"> <th colspan="{{getVisibleColumns().length}}" class="sortable" ng-class="{ \'sort-asc\': params.hasGroup($selGroup, \'asc\'), \'sort-desc\':params.hasGroup($selGroup, \'desc\') }"> <a href="" ng-click="isSelectorOpen=!isSelectorOpen" class="ng-table-group-selector"> <strong class="sort-indicator">{{$selGroupTitle}}</strong> <button class="btn btn-default btn-xs ng-table-group-close" ng-click="$groupRow.show=false; $event.preventDefault(); $event.stopPropagation();"> <span class="glyphicon glyphicon-remove"></span> </button> <button class="btn btn-default btn-xs ng-table-group-toggle" ng-click="toggleDetail(); $event.preventDefault(); $event.stopPropagation();"> <span class="glyphicon" ng-class="{ \'glyphicon-resize-small\': params.settings().groupOptions.isExpanded, \'glyphicon-resize-full\': !params.settings().groupOptions.isExpanded }"></span> </button> </a> <div class="list-group" ng-if="isSelectorOpen"> <a href="" class="list-group-item" ng-repeat="group in getGroupables()" ng-click="groupBy(group)"> <strong>{{ getGroupTitle(group)}}</strong> <strong ng-class="isSelectedGroup(group) && \'sort-indicator\'"></strong> </a> </div> </th> </tr> '),a.put("ng-table/header.html","<ng-table-group-row></ng-table-group-row> <ng-table-sorter-row></ng-table-sorter-row> <ng-table-filter-row></ng-table-filter-row> "),a.put("ng-table/pager.html",'<div class="ng-cloak ng-table-pager" ng-if="params.data.length"> <div ng-if="params.settings().counts.length" class="ng-table-counts btn-group pull-right"> <button ng-repeat="count in params.settings().counts" type="button" ng-class="{\'active\':params.count()==count}" ng-click="params.count(count)" class="btn btn-default"> <span ng-bind="count"></span> </button> </div> <ul ng-if="pages.length" class="pagination ng-table-pagination"> <li ng-class="{\'disabled\': !page.active && !page.current, \'active\': page.current}" ng-repeat="page in pages" ng-switch="page.type"> <a ng-switch-when="prev" ng-click="params.page(page.number)" href="">&laquo;</a> <a ng-switch-when="first" ng-click="params.page(page.number)" href=""><span ng-bind="page.number"></span></a> <a ng-switch-when="page" ng-click="params.page(page.number)" href=""><span ng-bind="page.number"></span></a> <a ng-switch-when="more" ng-click="params.page(page.number)" href="">&#8230;</a> <a ng-switch-when="last" ng-click="params.page(page.number)" href=""><span ng-bind="page.number"></span></a> <a ng-switch-when="next" ng-click="params.page(page.number)" href="">&raquo;</a> </li> </ul> </div> '),a.put("ng-table/sorterRow.html",'<tr class="ng-table-sort-header"> <th title="{{$column.headerTitle(this)}}" ng-repeat="$column in $columns" ng-class="{ \'sortable\': $column.sortable(this), \'sort-asc\': params.sorting()[$column.sortable(this)]==\'asc\', \'sort-desc\': params.sorting()[$column.sortable(this)]==\'desc\' }" ng-click="sortBy($column, $event)" ng-if="$column.show(this)" ng-init="template=$column.headerTemplateURL(this)" class="header {{$column.class(this)}}"> <div ng-if="!template" class="ng-table-header" ng-class="{\'sort-indicator\': params.settings().sortingIndicator==\'div\'}"> <span ng-bind="$column.title(this)" ng-class="{\'sort-indicator\': params.settings().sortingIndicator==\'span\'}"></span> </div> <div ng-if="template" ng-include="template"></div> </th> </tr> ')}]),a.module("ngTable")});
//# sourceMappingURL=ng-table.min.js.map
\ No newline at end of file
/**
* @version 2.0.2
* @license MIT
*/
!function (t, e) {
"use strict";
t.module("smart-table", []).run(["$templateCache", function (t) {
t.put("template/smart-table/pagination.html", '<nav ng-if="pages.length >= 2"><ul class="pagination"><li ng-repeat="page in pages" ng-class="{active: page==currentPage}"><a ng-click="selectPage(page)">{{page}}</a></li></ul></nav>')
}]), t.module("smart-table").constant("stConfig", {
pagination: {
template: "template/smart-table/pagination.html",
itemsByPage: 10,
displayedPages: 5
},
search: {delay: 400},
select: {mode: "single", selectedClass: "st-selected"},
sort: {ascentClass: "st-sort-ascent", descentClass: "st-sort-descent"},
pipe: {delay: 100}
}), t.module("smart-table").controller("stTableController", ["$scope", "$parse", "$filter", "$attrs", function (a, s, n, r) {
function i(t) {
return t ? [].concat(t) : []
}
function c() {
h = i(l(a)), P === !0 && S.pipe()
}
var l, o, u, p = r.stTable, g = s(p), f = g.assign, d = n("orderBy"), m = n("filter"), h = i(g(a)), b = {
sort: {},
search: {},
pagination: {start: 0}
}, P = !0, S = this;
r.stSafeSrc && (l = s(r.stSafeSrc), a.$watch(function () {
var t = l(a);
return t ? t.length : 0
}, function (t) {
t !== h.length && c()
}), a.$watch(function () {
return l(a)
}, function (t, e) {
t !== e && c()
})), this.sortBy = function (e, a) {
return b.sort.predicate = e, b.sort.reverse = a === !0, t.isFunction(e) ? b.sort.functionName = e.name : delete b.sort.functionName, b.pagination.start = 0, this.pipe()
}, this.search = function (e, a) {
var s = b.search.predicateObject || {}, n = a ? a : "$";
return e = t.isString(e) ? e.trim() : e, s[n] = e, e || delete s[n], b.search.predicateObject = s, b.pagination.start = 0, this.pipe()
}, this.pipe = function () {
var t, s = b.pagination;
o = b.search.predicateObject ? m(h, b.search.predicateObject) : h, b.sort.predicate && (o = d(o, b.sort.predicate, b.sort.reverse)), s.number !== e && (s.numberOfPages = o.length > 0 ? Math.ceil(o.length / s.number) : 1, s.start = s.start >= o.length ? (s.numberOfPages - 1) * s.number : s.start, t = o.slice(s.start, s.start + parseInt(s.number))), f(a, t || o)
}, this.select = function (t, a) {
var s = h, n = s.indexOf(t);
-1 !== n && ("single" === a ? (t.isSelected = t.isSelected !== !0, u && (u.isSelected = !1), u = t.isSelected === !0 ? t : e) : s[n].isSelected = !s[n].isSelected)
}, this.slice = function (t, e) {
return b.pagination.start = t, b.pagination.number = e, this.pipe()
}, this.tableState = function () {
return b
}, this.getFilteredCollection = function () {
return o || h
}, this.setFilterFunction = function (t) {
m = n(t)
}, this.setSortFunction = function (t) {
d = n(t)
}, this.preventPipeOnWatch = function () {
P = !1
}
}]).directive("stTable", function () {
return {
restrict: "A", controller: "stTableController", link: function (t, e, a, s) {
a.stSetFilter && s.setFilterFunction(a.stSetFilter), a.stSetSort && s.setSortFunction(a.stSetSort)
}
}
}), t.module("smart-table").directive("stSearch", ["stConfig", "$timeout", function (t, e) {
return {
require: "^stTable", link: function (a, s, n, r) {
var i = r, c = null, l = n.stDelay || t.search.delay;
n.$observe("stSearch", function (t, e) {
var a = s[0].value;
t !== e && a && (r.tableState().search = {}, i.search(a, t))
}), a.$watch(function () {
return r.tableState().search
}, function (t) {
var e = n.stSearch || "$";
t.predicateObject && t.predicateObject[e] !== s[0].value && (s[0].value = t.predicateObject[e] || "")
}, !0), s.bind("input", function (t) {
t = t.originalEvent || t, null !== c && e.cancel(c), c = e(function () {
i.search(t.target.value, n.stSearch || ""), c = null
}, l)
})
}
}
}]), t.module("smart-table").directive("stSelectRow", ["stConfig", function (t) {
return {
restrict: "A", require: "^stTable", scope: {row: "=stSelectRow"}, link: function (e, a, s, n) {
var r = s.stSelectMode || t.select.mode;
a.bind("click", function () {
e.$apply(function () {
n.select(e.row, r)
})
}), e.$watch("row.isSelected", function (e) {
e === !0 ? a.addClass(t.select.selectedClass) : a.removeClass(t.select.selectedClass)
})
}
}
}]), t.module("smart-table").directive("stSort", ["stConfig", "$parse", function (a, s) {
return {
restrict: "A", require: "^stTable", link: function (n, r, i, c) {
function l() {
g++, u = t.isFunction(p(n)) ? p(n) : i.stSort, g % 3 === 0 && i.stSkipNatural === e ? (g = 0, c.tableState().sort = {}, c.tableState().pagination.start = 0, c.pipe()) : c.sortBy(u, g % 2 === 0)
}
var o, u = i.stSort, p = s(u), g = 0, f = i.stClassAscent || a.sort.ascentClass, d = i.stClassDescent || a.sort.descentClass, m = [f, d];
i.stSortDefault && (o = n.$eval(i.stSortDefault) !== e ? n.$eval(i.stSortDefault) : i.stSortDefault), r.bind("click", function () {
u && n.$apply(l)
}), o && (g = "reverse" === o ? 1 : 0, l()), n.$watch(function () {
return c.tableState().sort
}, function (t) {
t.predicate !== u ? (g = 0, r.removeClass(f).removeClass(d)) : (g = t.reverse === !0 ? 2 : 1, r.removeClass(m[g % 2]).addClass(m[g - 1]))
}, !0)
}
}
}]), t.module("smart-table").directive("stPagination", ["stConfig", function (t) {
return {
restrict: "EA",
require: "^stTable",
scope: {stItemsByPage: "=?", stDisplayedPages: "=?", stPageChange: "&"},
templateUrl: function (e, a) {
return a.stTemplate ? a.stTemplate : t.pagination.template
},
link: function (e, a, s, n) {
function r() {
var t, a, s = n.tableState().pagination, r = 1, i = e.currentPage;
for (e.currentPage = Math.floor(s.start / s.number) + 1, r = Math.max(r, e.currentPage - Math.abs(Math.floor(e.stDisplayedPages / 2))), t = r + e.stDisplayedPages, t > s.numberOfPages && (t = s.numberOfPages + 1, r = Math.max(1, t - e.stDisplayedPages)), e.pages = [], e.numPages = s.numberOfPages, a = r; t > a; a++)e.pages.push(a);
i !== e.currentPage && e.stPageChange({newPage: e.currentPage})
}
e.stItemsByPage = e.stItemsByPage ? +e.stItemsByPage : t.pagination.itemsByPage, e.stDisplayedPages = e.stDisplayedPages ? +e.stDisplayedPages : t.pagination.displayedPages, e.currentPage = 1, e.pages = [], e.$watch(function () {
return n.tableState().pagination
}, r, !0), e.$watch("stItemsByPage", function (t, a) {
t !== a && e.selectPage(1)
}), e.$watch("stDisplayedPages", r), e.selectPage = function (t) {
t > 0 && t <= e.numPages && n.slice((t - 1) * e.stItemsByPage, e.stItemsByPage)
}, n.tableState().pagination.number || n.slice(0, e.stItemsByPage)
}
}
}]), t.module("smart-table").directive("stPipe", ["stConfig", "$timeout", function (e, a) {
return {
require: "stTable", scope: {stPipe: "="}, link: {
pre: function (s, n, r, i) {
var c = null;
t.isFunction(s.stPipe) && (i.preventPipeOnWatch(), i.pipe = function () {
return null !== c && a.cancel(c), c = a(function () {
s.stPipe(i.tableState(), i)
}, e.pipe.delay)
})
}, post: function (t, e, a, s) {
s.pipe()
}
}
}
}])
}(angular);
/*!
angular-xeditable - 0.1.8
Edit-in-place for angular.js
Build date: 2014-01-10
*/
angular.module("xeditable", []).value("editableOptions", {
theme: "default",
buttons: "right",
blurElem: "cancel",
blurForm: "ignore",
activate: "focus"
}), angular.module("xeditable").directive("editableBsdate", ["editableDirectiveFactory", function (a) {
return a({directiveName: "editableBsdate", inputTpl: '<input type="text">'})
}]), angular.module("xeditable").directive("editableBstime", ["editableDirectiveFactory", function (a) {
return a({
directiveName: "editableBstime", inputTpl: "<timepicker></timepicker>", render: function () {
this.parent.render.call(this);
var a = angular.element('<div class="well well-small" style="display:inline-block;"></div>');
a.attr("ng-model", this.inputEl.attr("ng-model")), this.inputEl.removeAttr("ng-model"), this.attrs.eNgChange && (a.attr("ng-change", this.inputEl.attr("ng-change")), this.inputEl.removeAttr("ng-change")), this.inputEl.wrap(a)
}
})
}]), angular.module("xeditable").directive("editableCheckbox", ["editableDirectiveFactory", function (a) {
return a({
directiveName: "editableCheckbox", inputTpl: '<input type="checkbox">', render: function () {
this.parent.render.call(this), this.attrs.eTitle && (this.inputEl.wrap("<label></label>"), this.inputEl.after(angular.element("<span></span>").text(this.attrs.eTitle)))
}, autosubmit: function () {
var a = this;
a.inputEl.bind("change", function () {
setTimeout(function () {
a.scope.$apply(function () {
a.scope.$form.$submit()
})
}, 500)
})
}
})
}]), angular.module("xeditable").directive("editableChecklist", ["editableDirectiveFactory", "editableNgOptionsParser", function (a, b) {
return a({
directiveName: "editableChecklist", inputTpl: "<span></span>", useCopy: !0, render: function () {
this.parent.render.call(this);
var a = b(this.attrs.eNgOptions), c = '<label ng-repeat="' + a.ngRepeat + '">' + '<input type="checkbox" checklist-model="$parent.$data" checklist-value="' + a.locals.valueFn + '">' + '<span ng-bind="' + a.locals.displayFn + '"></span></label>';
this.inputEl.removeAttr("ng-model"), this.inputEl.removeAttr("ng-options"), this.inputEl.html(c)
}
})
}]), function () {
var a = "text|email|tel|number|url|search|color|date|datetime|time|month|week".split("|");
angular.forEach(a, function (a) {
var b = "editable" + a.charAt(0).toUpperCase() + a.slice(1);
angular.module("xeditable").directive(b, ["editableDirectiveFactory", function (c) {
return c({directiveName: b, inputTpl: '<input type="' + a + '">'})
}])
}), angular.module("xeditable").directive("editableRange", ["editableDirectiveFactory", function (a) {
return a({
directiveName: "editableRange",
inputTpl: '<input type="range" id="range" name="range">',
render: function () {
this.parent.render.call(this), this.inputEl.after("<output>{{$data}}</output>")
}
})
}])
}(), angular.module("xeditable").directive("editableRadiolist", ["editableDirectiveFactory", "editableNgOptionsParser", function (a, b) {
return a({
directiveName: "editableRadiolist", inputTpl: "<span></span>", render: function () {
this.parent.render.call(this);
var a = b(this.attrs.eNgOptions), c = '<label ng-repeat="' + a.ngRepeat + '">' + '<input type="radio" ng-model="$parent.$data" value="{{' + a.locals.valueFn + '}}">' + '<span ng-bind="' + a.locals.displayFn + '"></span></label>';
this.inputEl.removeAttr("ng-model"), this.inputEl.removeAttr("ng-options"), this.inputEl.html(c)
}, autosubmit: function () {
var a = this;
a.inputEl.bind("change", function () {
setTimeout(function () {
a.scope.$apply(function () {
a.scope.$form.$submit()
})
}, 500)
})
}
})
}]), angular.module("xeditable").directive("editableSelect", ["editableDirectiveFactory", function (a) {
return a({
directiveName: "editableSelect", inputTpl: "<select></select>", autosubmit: function () {
var a = this;
a.inputEl.bind("change", function () {
a.scope.$apply(function () {
a.scope.$form.$submit()
})
})
}
})
}]), angular.module("xeditable").directive("editableTextarea", ["editableDirectiveFactory", function (a) {
return a({
directiveName: "editableTextarea", inputTpl: "<textarea></textarea>", addListeners: function () {
var a = this;
a.parent.addListeners.call(a), a.single && "no" !== a.buttons && a.autosubmit()
}, autosubmit: function () {
var a = this;
a.inputEl.bind("keydown", function (b) {
(b.ctrlKey || b.metaKey) && 13 === b.keyCode && a.scope.$apply(function () {
a.scope.$form.$submit()
})
})
}
})
}]), angular.module("xeditable").factory("editableController", ["$q", "editableUtils", function (a, b) {
function c(a, c, d, e, f, g, h, i, j) {
var k, l, m = this;
m.scope = a, m.elem = d, m.attrs = c, m.inputEl = null, m.editorEl = null, m.single = !0, m.error = "", m.theme = f[g.theme] || f["default"], m.parent = {}, m.inputTpl = "", m.directiveName = "", m.useCopy = !1, m.single = null, m.buttons = "right", m.init = function (b) {
if (m.single = b, m.name = c.eName || c[m.directiveName], !c[m.directiveName])throw"You should provide value for `" + m.directiveName + "` in editable element!";
k = e(c[m.directiveName]), m.buttons = m.single ? m.attrs.buttons || g.buttons : "no", c.eName && m.scope.$watch("$data", function (a) {
m.scope.$form.$data[c.eName] = a
}), c.onshow && (m.onshow = function () {
return m.catchError(e(c.onshow)(a))
}), c.onhide && (m.onhide = function () {
return e(c.onhide)(a)
}), c.oncancel && (m.oncancel = function () {
return e(c.oncancel)(a)
}), c.onbeforesave && (m.onbeforesave = function () {
return m.catchError(e(c.onbeforesave)(a))
}), c.onaftersave && (m.onaftersave = function () {
return m.catchError(e(c.onaftersave)(a))
}), a.$parent.$watch(c[m.directiveName], function () {
m.handleEmpty()
})
}, m.render = function () {
var a = m.theme;
m.inputEl = angular.element(m.inputTpl), m.controlsEl = angular.element(a.controlsTpl), m.controlsEl.append(m.inputEl), "no" !== m.buttons && (m.buttonsEl = angular.element(a.buttonsTpl), m.submitEl = angular.element(a.submitTpl), m.cancelEl = angular.element(a.cancelTpl), m.buttonsEl.append(m.submitEl).append(m.cancelEl), m.controlsEl.append(m.buttonsEl), m.inputEl.addClass("editable-has-buttons")), m.errorEl = angular.element(a.errorTpl), m.controlsEl.append(m.errorEl), m.editorEl = angular.element(m.single ? a.formTpl : a.noformTpl), m.editorEl.append(m.controlsEl);
for (var d in c.$attr)if (!(d.length <= 1)) {
var e = !1, f = d.substring(1, 2);
if ("e" === d.substring(0, 1) && f === f.toUpperCase() && (e = d.substring(1), "Form" !== e && "NgSubmit" !== e)) {
e = e.substring(0, 1).toLowerCase() + b.camelToDash(e.substring(1));
var h = "" === c[d] ? e : c[d];
m.inputEl.attr(e, h)
}
}
m.inputEl.addClass("editable-input"), m.inputEl.attr("ng-model", "$data"), m.editorEl.addClass(b.camelToDash(m.directiveName)), m.single && (m.editorEl.attr("editable-form", "$form"), m.editorEl.attr("blur", m.attrs.blur || ("no" === m.buttons ? "cancel" : g.blurElem))), angular.isFunction(a.postrender) && a.postrender.call(m)
}, m.setLocalValue = function () {
m.scope.$data = m.useCopy ? angular.copy(k(a.$parent)) : k(a.$parent)
}, m.show = function () {
return m.setLocalValue(), m.render(), d.after(m.editorEl), i(m.editorEl)(a), m.addListeners(), d.addClass("editable-hide"), m.onshow()
}, m.hide = function () {
return m.editorEl.remove(), d.removeClass("editable-hide"), m.onhide()
}, m.cancel = function () {
m.oncancel()
}, m.addListeners = function () {
m.inputEl.bind("keyup", function (a) {
if (m.single)switch (a.keyCode) {
case 27:
m.scope.$apply(function () {
m.scope.$form.$cancel()
})
}
}), m.single && "no" === m.buttons && m.autosubmit(), m.editorEl.bind("click", function (a) {
1 === a.which && m.scope.$form.$visible && (m.scope.$form._clicked = !0)
})
}, m.setWaiting = function (a) {
a ? (l = !m.inputEl.attr("disabled") && !m.inputEl.attr("ng-disabled") && !m.inputEl.attr("ng-enabled"), l && (m.inputEl.attr("disabled", "disabled"), m.buttonsEl && m.buttonsEl.find("button").attr("disabled", "disabled"))) : l && (m.inputEl.removeAttr("disabled"), m.buttonsEl && m.buttonsEl.find("button").removeAttr("disabled"))
}, m.activate = function () {
setTimeout(function () {
var a = m.inputEl[0];
"focus" === g.activate && a.focus && a.focus(), "select" === g.activate && a.select && a.select()
}, 0)
}, m.setError = function (b) {
angular.isObject(b) || (a.$error = b, m.error = b)
}, m.catchError = function (a, b) {
return angular.isObject(a) && b !== !0 ? j.when(a).then(angular.bind(this, function (a) {
this.catchError(a, !0)
}), angular.bind(this, function (a) {
this.catchError(a, !0)
})) : b && angular.isObject(a) && a.status && 200 !== a.status && a.data && angular.isString(a.data) ? (this.setError(a.data), a = a.data) : angular.isString(a) && this.setError(a), a
}, m.save = function () {
k.assign(a.$parent, angular.copy(m.scope.$data))
}, m.handleEmpty = function () {
var b = k(a.$parent), c = null === b || void 0 === b || "" === b || angular.isArray(b) && 0 === b.length;
d.toggleClass("editable-empty", c)
}, m.autosubmit = angular.noop, m.onshow = angular.noop, m.onhide = angular.noop, m.oncancel = angular.noop, m.onbeforesave = angular.noop, m.onaftersave = angular.noop
}
return c.$inject = ["$scope", "$attrs", "$element", "$parse", "editableThemes", "editableOptions", "$rootScope", "$compile", "$q"], c
}]), angular.module("xeditable").factory("editableDirectiveFactory", ["$parse", "$compile", "editableThemes", "$rootScope", "$document", "editableController", "editableFormController", function (a, b, c, d, e, f, g) {
return function (b) {
return {
restrict: "A",
scope: !0,
require: [b.directiveName, "?^form"],
controller: f,
link: function (c, f, h, i) {
var j, k = i[0], l = !1;
if (i[1])j = i[1], l = !0; else if (h.eForm) {
var m = a(h.eForm)(c);
if (m)j = m, l = !0; else for (var n = 0; n < e[0].forms.length; n++)if (e[0].forms[n].name === h.eForm) {
j = null, l = !0;
break
}
}
if (angular.forEach(b, function (a, b) {
void 0 !== k[b] && (k.parent[b] = k[b])
}), angular.extend(k, b), k.init(!l), c.$editable = k, f.addClass("editable"), l)if (j) {
if (c.$form = j, !c.$form.$addEditable)throw"Form with editable elements should have `editable-form` attribute.";
c.$form.$addEditable(k)
} else d.$$editableBuffer = d.$$editableBuffer || {}, d.$$editableBuffer[h.eForm] = d.$$editableBuffer[h.eForm] || [], d.$$editableBuffer[h.eForm].push(k), c.$form = null; else c.$form = g(), c.$form.$addEditable(k), h.eForm && (c.$parent[h.eForm] = c.$form), h.eForm || (f.addClass("editable-click"), f.bind("click", function (a) {
a.preventDefault(), a.editable = k, c.$apply(function () {
c.$form.$show()
})
}))
}
}
}
}]), angular.module("xeditable").factory("editableFormController", ["$parse", "$document", "$rootScope", "editablePromiseCollection", "editableUtils", function (a, b, c, d, e) {
var f = [];
b.bind("click", function (a) {
if (1 === a.which) {
for (var b = [], d = [], e = 0; e < f.length; e++)f[e]._clicked ? f[e]._clicked = !1 : f[e].$waiting || ("cancel" === f[e]._blur && b.push(f[e]), "submit" === f[e]._blur && d.push(f[e]));
(b.length || d.length) && c.$apply(function () {
angular.forEach(b, function (a) {
a.$cancel()
}), angular.forEach(d, function (a) {
a.$submit()
})
})
}
});
var g = {
$addEditable: function (a) {
this.$editables.push(a), a.elem.bind("$destroy", angular.bind(this, this.$removeEditable, a)), a.scope.$form || (a.scope.$form = this), this.$visible && a.catchError(a.show())
},
$removeEditable: function (a) {
for (var b = 0; b < this.$editables.length; b++)if (this.$editables[b] === a)return this.$editables.splice(b, 1), void 0
},
$show: function () {
if (!this.$visible) {
this.$visible = !0;
var a = d();
a.when(this.$onshow()), this.$setError(null, ""), angular.forEach(this.$editables, function (b) {
a.when(b.show())
}), a.then({
onWait: angular.bind(this, this.$setWaiting),
onTrue: angular.bind(this, this.$activate),
onFalse: angular.bind(this, this.$activate),
onString: angular.bind(this, this.$activate)
}), setTimeout(angular.bind(this, function () {
this._clicked = !1, -1 === e.indexOf(f, this) && f.push(this)
}), 0)
}
},
$activate: function (a) {
var b;
if (this.$editables.length) {
if (angular.isString(a))for (b = 0; b < this.$editables.length; b++)if (this.$editables[b].name === a)return this.$editables[b].activate(), void 0;
for (b = 0; b < this.$editables.length; b++)if (this.$editables[b].error)return this.$editables[b].activate(), void 0;
this.$editables[0].activate()
}
},
$hide: function () {
this.$visible && (this.$visible = !1, this.$onhide(), angular.forEach(this.$editables, function (a) {
a.hide()
}), e.arrayRemove(f, this))
},
$cancel: function () {
this.$visible && (this.$oncancel(), angular.forEach(this.$editables, function (a) {
a.cancel()
}), this.$hide())
},
$setWaiting: function (a) {
this.$waiting = !!a, angular.forEach(this.$editables, function (b) {
b.setWaiting(!!a)
})
},
$setError: function (a, b) {
angular.forEach(this.$editables, function (c) {
a && c.name !== a || c.setError(b)
})
},
$submit: function () {
function a(a) {
var b = d();
b.when(this.$onbeforesave()), b.then({
onWait: angular.bind(this, this.$setWaiting),
onTrue: a ? angular.bind(this, this.$save) : angular.bind(this, this.$hide),
onFalse: angular.bind(this, this.$hide),
onString: angular.bind(this, this.$activate)
})
}
if (!this.$waiting) {
this.$setError(null, "");
var b = d();
angular.forEach(this.$editables, function (a) {
b.when(a.onbeforesave())
}), b.then({
onWait: angular.bind(this, this.$setWaiting),
onTrue: angular.bind(this, a, !0),
onFalse: angular.bind(this, a, !1),
onString: angular.bind(this, this.$activate)
})
}
},
$save: function () {
angular.forEach(this.$editables, function (a) {
a.save()
});
var a = d();
a.when(this.$onaftersave()), angular.forEach(this.$editables, function (b) {
a.when(b.onaftersave())
}), a.then({
onWait: angular.bind(this, this.$setWaiting),
onTrue: angular.bind(this, this.$hide),
onFalse: angular.bind(this, this.$hide),
onString: angular.bind(this, this.$activate)
})
},
$onshow: angular.noop,
$oncancel: angular.noop,
$onhide: angular.noop,
$onbeforesave: angular.noop,
$onaftersave: angular.noop
};
return function () {
return angular.extend({$editables: [], $visible: !1, $waiting: !1, $data: {}, _clicked: !1, _blur: null}, g)
}
}]), angular.module("xeditable").directive("editableForm", ["$rootScope", "$parse", "editableFormController", "editableOptions", function (a, b, c, d) {
return {
restrict: "A", require: ["form"], compile: function () {
return {
pre: function (b, d, e, f) {
var g, h = f[0];
e.editableForm ? b[e.editableForm] && b[e.editableForm].$show ? (g = b[e.editableForm], angular.extend(h, g)) : (g = c(), b[e.editableForm] = g, angular.extend(g, h)) : (g = c(), angular.extend(h, g));
var i = a.$$editableBuffer, j = h.$name;
j && i && i[j] && (angular.forEach(i[j], function (a) {
g.$addEditable(a)
}), delete i[j])
}, post: function (a, c, e, f) {
var g;
g = e.editableForm && a[e.editableForm] && a[e.editableForm].$show ? a[e.editableForm] : f[0], e.onshow && (g.$onshow = angular.bind(g, b(e.onshow), a)), e.onhide && (g.$onhide = angular.bind(g, b(e.onhide), a)), e.oncancel && (g.$oncancel = angular.bind(g, b(e.oncancel), a)), e.shown && b(e.shown)(a) && g.$show(), g._blur = e.blur || d.blurForm, e.ngSubmit || e.submit || (e.onbeforesave && (g.$onbeforesave = function () {
return b(e.onbeforesave)(a, {$data: g.$data})
}), e.onaftersave && (g.$onaftersave = function () {
return b(e.onaftersave)(a, {$data: g.$data})
}), c.bind("submit", function (b) {
b.preventDefault(), a.$apply(function () {
g.$submit()
})
})), c.bind("click", function (a) {
1 === a.which && g.$visible && (g._clicked = !0)
})
}
}
}
}
}]), angular.module("xeditable").factory("editablePromiseCollection", ["$q", function (a) {
function b() {
return {
promises: [], hasFalse: !1, hasString: !1, when: function (b, c) {
if (b === !1)this.hasFalse = !0; else if (!c && angular.isObject(b))this.promises.push(a.when(b)); else {
if (!angular.isString(b))return;
this.hasString = !0
}
}, then: function (b) {
function c() {
h.hasString || h.hasFalse ? !h.hasString && h.hasFalse ? e() : f() : d()
}
b = b || {};
var d = b.onTrue || angular.noop, e = b.onFalse || angular.noop, f = b.onString || angular.noop, g = b.onWait || angular.noop, h = this;
this.promises.length ? (g(!0), a.all(this.promises).then(function (a) {
g(!1), angular.forEach(a, function (a) {
h.when(a, !0)
}), c()
}, function () {
g(!1), f()
})) : c()
}
}
}
return b
}]), angular.module("xeditable").factory("editableUtils", [function () {
return {
indexOf: function (a, b) {
if (a.indexOf)return a.indexOf(b);
for (var c = 0; c < a.length; c++)if (b === a[c])return c;
return -1
}, arrayRemove: function (a, b) {
var c = this.indexOf(a, b);
return c >= 0 && a.splice(c, 1), b
}, camelToDash: function (a) {
var b = /[A-Z]/g;
return a.replace(b, function (a, b) {
return (b ? "-" : "") + a.toLowerCase()
})
}, dashToCamel: function (a) {
var b = /([\:\-\_]+(.))/g, c = /^moz([A-Z])/;
return a.replace(b, function (a, b, c, d) {
return d ? c.toUpperCase() : c
}).replace(c, "Moz$1")
}
}
}]), angular.module("xeditable").factory("editableNgOptionsParser", [function () {
function a(a) {
var c;
if (!(c = a.match(b)))throw"ng-options parse error";
var d, e = c[2] || c[1], f = c[4] || c[6], g = c[5], h = (c[3] || "", c[2] ? c[1] : f), i = c[7], j = c[8], k = j ? c[8] : null;
return void 0 === g ? (d = f + " in " + i, void 0 !== j && (d += " track by " + k)) : d = "(" + g + ", " + f + ") in " + i, {
ngRepeat: d,
locals: {valueName: f, keyName: g, valueFn: h, displayFn: e}
}
}
var b = /^\s*(.*?)(?:\s+as\s+(.*?))?(?:\s+group\s+by\s+(.*))?\s+for\s+(?:([\$\w][\$\w]*)|(?:\(\s*([\$\w][\$\w]*)\s*,\s*([\$\w][\$\w]*)\s*\)))\s+in\s+(.*?)(?:\s+track\s+by\s+(.*?))?$/;
return a
}]), angular.module("xeditable").factory("editableThemes", function () {
var a = {
"default": {
formTpl: '<form class="editable-wrap"></form>',
noformTpl: '<span class="editable-wrap"></span>',
controlsTpl: '<span class="editable-controls"></span>',
inputTpl: "",
errorTpl: '<div class="editable-error" ng-show="$error" ng-bind="$error"></div>',
buttonsTpl: '<span class="editable-buttons"></span>',
submitTpl: '<button type="submit">save</button>',
cancelTpl: '<button type="button" ng-click="$form.$cancel()">cancel</button>'
},
bs2: {
formTpl: '<form class="form-inline editable-wrap" role="form"></form>',
noformTpl: '<span class="editable-wrap"></span>',
controlsTpl: '<div class="editable-controls controls control-group" ng-class="{\'error\': $error}"></div>',
inputTpl: "",
errorTpl: '<div class="editable-error help-block" ng-show="$error" ng-bind="$error"></div>',
buttonsTpl: '<span class="editable-buttons"></span>',
submitTpl: '<button type="submit" class="btn btn-primary"><span class="icon-ok icon-white"></span></button>',
cancelTpl: '<button type="button" class="btn" ng-click="$form.$cancel()"><span class="icon-remove"></span></button>'
},
bs3: {
formTpl: '<form class="form-inline editable-wrap" role="form"></form>',
noformTpl: '<span class="editable-wrap"></span>',
controlsTpl: '<div class="editable-controls form-group" ng-class="{\'has-error\': $error}"></div>',
inputTpl: "",
errorTpl: '<div class="editable-error help-block" ng-show="$error" ng-bind="$error"></div>',
buttonsTpl: '<span class="editable-buttons"></span>',
submitTpl: '<button type="submit" class="btn btn-primary"><span class="glyphicon glyphicon-ok"></span></button>',
cancelTpl: '<button type="button" class="btn btn-default" ng-click="$form.$cancel()"><span class="glyphicon glyphicon-remove"></span></button>',
buttonsClass: "",
inputClass: "",
postrender: function () {
switch (this.directiveName) {
case"editableText":
case"editableSelect":
case"editableTextarea":
case"editableEmail":
case"editableTel":
case"editableNumber":
case"editableUrl":
case"editableSearch":
case"editableDate":
case"editableDatetime":
case"editableTime":
case"editableMonth":
case"editableWeek":
if (this.inputEl.addClass("form-control"), this.theme.inputClass) {
if (this.inputEl.attr("multiple") && ("input-sm" === this.theme.inputClass || "input-lg" === this.theme.inputClass))break;
this.inputEl.addClass(this.theme.inputClass)
}
}
this.buttonsEl && this.theme.buttonsClass && this.buttonsEl.find("button").addClass(this.theme.buttonsClass)
}
}
};
return a
});
......@@ -14,7 +14,7 @@
<div ng-include="'common/nav.html'"></div>
<div class="container-fluid">
<div class="container-fluid apollo-container">
<div class="app" ng-controller="AppConfigController as appConfig">
<!--配置信息-->
......@@ -100,8 +100,8 @@
</div>
</div>
</header>
<div ng-show="namespace.viewType == 'text'">
<textarea class="form-control" rows="30" ng-model="namespace.text"
ng-disabled="!namespace.isTextEditing">
{{namespace.text}}
......@@ -305,11 +305,10 @@
<!--controller-->
<script type="application/javascript" src="../scripts/controller/app/AppConfigController.js"></script>
<script type="application/javascript">
$(function () {
$('[data-toggle="tooltip"]').tooltip()
})
});
</script>
</body>
</html>
......@@ -14,8 +14,7 @@
<div ng-include="'common/nav.html'"></div>
<div class="container">
<div class="container-fluid">
<div class="container-fluid apollo-container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
......@@ -64,7 +63,6 @@
</div>
</div>
</div>
</div>
</div>
<div ng-include="'common/footer.html'"></div>
......
package com.ctrip.apollo.portal;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;
import org.junit.runners.Suite.SuiteClasses;
@RunWith(Suite.class)
@SuiteClasses({
ConfigServiceTest.class, PropertyResolverTest.class,
AppServiceTest.class
})
public class AllTests {
......
package com.ctrip.apollo.portal;
import com.ctrip.apollo.core.dto.AppDTO;
import com.ctrip.apollo.core.dto.ClusterDTO;
import com.ctrip.apollo.core.enums.Env;
import com.ctrip.apollo.portal.api.AdminServiceAPI;
import com.ctrip.apollo.portal.entity.ClusterNavTree;
import com.ctrip.apollo.portal.service.AppService;
import com.ctrip.apollo.portal.service.ClusterService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.when;
@RunWith(MockitoJUnitRunner.class)
public class AppServiceTest extends AbstractPortalTest{
@Mock
private PortalSettings settings;
@Mock
private ClusterService clusterService;
@Mock
private AdminServiceAPI.AppAPI appAPI;
@InjectMocks
private AppService appService;
@Test
public void testBuildNavTree(){
String appId = "6666";
ClusterDTO c1 = new ClusterDTO();
c1.setAppId(appId);
c1.setName("default");
c1.setId(1);
ClusterDTO c2 = new ClusterDTO();
c2.setAppId(appId);
c2.setName("oy");
c2.setId(2);
List<ClusterDTO> clusterDTOs = Arrays.asList(c1, c2);
when(settings.getEnvs()).thenReturn(Arrays.asList(Env.DEV, Env.FAT));
when(clusterService.findClusters(Env.DEV, appId)).thenReturn(clusterDTOs);
when(clusterService.findClusters(Env.FAT, appId)).thenReturn(Arrays.asList(c1));
ClusterNavTree tree = appService.buildClusterNavTree(appId);
assertEquals(2, tree.getNodes().size());
ClusterNavTree.Node node1 = tree.getNodes().get(0);
assertEquals(Env.DEV, node1.getEnv());
assertEquals(2, node1.getClusters().size());
assertEquals("default", node1.getClusters().get(0).getName());
}
@Test
public void testSaveApp(){
String appId = "6666";
String appName = "hermas";
AppDTO appDTO = new AppDTO();
appDTO.setAppId(appId);
appDTO.setName(appName);
appDTO.setDataChangeLastModifiedBy("ll");
appDTO.setDataChangeCreatedTime(new Date());
appDTO.setOwnerEmail("qq@qq.com");
appDTO.setOwnerName("zz");
when(appService.save(appDTO)).thenReturn(appDTO);
AppDTO createApp = appService.save(appDTO);
assertEquals(appId, createApp.getAppId());
assertEquals(appName, createApp.getName());
}
}
package com.ctrip.apollo.portal;
import com.ctrip.apollo.core.dto.ItemChangeSets;
import com.ctrip.apollo.core.dto.ItemDTO;
import com.ctrip.apollo.core.dto.NamespaceDTO;
import com.ctrip.apollo.core.dto.ReleaseDTO;
import com.ctrip.apollo.core.enums.Env;
import com.ctrip.apollo.core.exception.ServiceException;
import com.ctrip.apollo.portal.api.AdminServiceAPI;
import com.ctrip.apollo.portal.entity.NamespaceVO;
import com.ctrip.apollo.portal.entity.form.NamespaceTextModel;
import com.ctrip.apollo.portal.service.ConfigService;
import com.ctrip.apollo.portal.service.txtresolver.PropertyResolver;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import java.util.Arrays;
import java.util.List;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.when;
@RunWith(MockitoJUnitRunner.class)
public class ConfigServiceTest extends AbstractPortalTest{
@Mock
private AdminServiceAPI.NamespaceAPI namespaceAPI;
@Mock
private AdminServiceAPI.ReleaseAPI releaseAPI;
@Mock
private AdminServiceAPI.ItemAPI itemAPI;
@Mock
private PropertyResolver resolver;
@InjectMocks
private ConfigService configService;
@Before
public void setup() {
}
@Test
public void testFindNamespace() {
String appId = "6666";
String clusterName = "default";
String namespaceName = "application";
NamespaceDTO application = new NamespaceDTO();
application.setId(1);
application.setClusterName(clusterName);
application.setAppId(appId);
application.setNamespaceName(namespaceName);
NamespaceDTO hermas = new NamespaceDTO();
hermas.setId(2);
hermas.setClusterName("default");
hermas.setAppId(appId);
hermas.setNamespaceName("hermas");
List<NamespaceDTO> namespaces = Arrays.asList(application, hermas);
ReleaseDTO someRelease = new ReleaseDTO();
someRelease.setConfigurations("{\"a\":\"123\",\"b\":\"123\"}");
ItemDTO i1 = new ItemDTO("a", "123", "", 1);
ItemDTO i2 = new ItemDTO("b", "1", "", 2);
ItemDTO i3 = new ItemDTO("", "", "#dddd", 3);
ItemDTO i4 = new ItemDTO("c", "1", "", 4);
List<ItemDTO> someItems = Arrays.asList(i1, i2, i3, i4);
when(namespaceAPI.findNamespaceByCluster(appId, Env.DEV, clusterName)).thenReturn(namespaces);
when(releaseAPI.loadLatestRelease(appId, Env.DEV, clusterName, namespaceName)).thenReturn(someRelease);
when(itemAPI.findItems(appId, Env.DEV, clusterName, namespaceName)).thenReturn(someItems);
List<NamespaceVO> namespaceVOs = configService.findNampspaces(appId, Env.DEV, clusterName);
assertEquals(2, namespaceVOs.size());
NamespaceVO namespaceVO = namespaceVOs.get(0);
assertEquals(4, namespaceVO.getItems().size());
assertEquals("a", namespaceVO.getItems().get(0).getItem().getKey());
assertEquals(2, namespaceVO.getItemModifiedCnt());
assertEquals(appId, namespaceVO.getNamespace().getAppId());
assertEquals(clusterName, namespaceVO.getNamespace().getClusterName());
assertEquals(namespaceName, namespaceVO.getNamespace().getNamespaceName());
}
@Test
public void testUpdateConfigByText() {
String appId = "6666";
String clusterName = "default";
String namespaceName = "application";
NamespaceTextModel model = new NamespaceTextModel();
model.setEnv("DEV");
model.setModifyBy("ll");
model.setNamespaceName(namespaceName);
model.setClusterName(clusterName);
model.setAppId(appId);
model.setConfigText("a=b\nb=c\nc=d");
List<ItemDTO> itemDTOs = mockBaseItemHas3Key();
ItemChangeSets changeSets = new ItemChangeSets();
changeSets.setModifyBy("ll");
changeSets.addCreateItem(new ItemDTO("d", "c", "", 4));
when(itemAPI.findItems(appId, Env.DEV, clusterName, namespaceName)).thenReturn(itemDTOs);
try {
// 调用itemAPI.updateConfig 会抛出ServiceException.
// itemAPI.updateConfig ut 放在admin service.
// 所以只要在调用itemAPI.updateConfig前全部通过,此ut应该通过.
configService.updateConfigItemByText(model);
}catch (Exception e){
Assert.assertTrue(e instanceof ServiceException);
}
}
/**
* a=b b=c c=d
*/
private List<ItemDTO> mockBaseItemHas3Key() {
ItemDTO item1 = new ItemDTO("a", "b", "", 1);
ItemDTO item2 = new ItemDTO("b", "c", "", 2);
ItemDTO item3 = new ItemDTO("c", "d", "", 3);
return Arrays.asList(item1, item2, item3);
}
}
package com.ctrip.apollo.portal;
import com.ctrip.apollo.core.dto.ItemChangeSets;
import com.ctrip.apollo.core.dto.ItemDTO;
import com.ctrip.apollo.core.exception.BadRequestException;
import com.ctrip.apollo.portal.service.txtresolver.ConfigTextResolver;
import org.junit.Assert;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class PropertyResolverTest extends AbstractPortalTest {
@Autowired
private ConfigTextResolver resolver;
@Test
public void testEmptyText() {
try {
resolver.resolve(0, "", null);
} catch (Exception e) {
Assert.assertTrue(e instanceof BadRequestException);
}
}
@Test
public void testAddItemBeforeNoItem() {
ItemChangeSets changeSets = resolver.resolve(1, "a=b\nb=c", Collections.emptyList());
Assert.assertEquals(2, changeSets.getCreateItems().size());
}
@Test
public void testAddItemBeforeHasItem() {
ItemChangeSets changeSets = resolver.resolve(1, "x=y\na=b\nb=c\nc=d", mockBaseItemHas3Key());
Assert.assertEquals("x", changeSets.getCreateItems().get(0).getKey());
Assert.assertEquals(1, changeSets.getCreateItems().size());
Assert.assertEquals(3, changeSets.getUpdateItems().size());
}
@Test
public void testAddCommentAndBlankItem() {
ItemChangeSets changeSets = resolver.resolve(1, "#ddd\na=b\n\nb=c\nc=d", mockBaseItemHas3Key());
Assert.assertEquals(2, changeSets.getCreateItems().size());
Assert.assertEquals(3, changeSets.getUpdateItems().size());
}
@Test
public void testChangeItemNumLine() {
ItemChangeSets changeSets = resolver.resolve(1, "b=c\nc=d\na=b", mockBaseItemHas3Key());
Assert.assertEquals(3, changeSets.getUpdateItems().size());
}
@Test
public void testDeleteItem() {
ItemChangeSets changeSets = resolver.resolve(1, "a=b", mockBaseItemHas3Key());
Assert.assertEquals(2, changeSets.getDeleteItems().size());
}
@Test
public void testDeleteCommentItem() {
ItemChangeSets changeSets = resolver.resolve(1, "a=b\n\nb=c", mockBaseItemWith2Key1Comment1Blank());
Assert.assertEquals(2, changeSets.getDeleteItems().size());
Assert.assertEquals(2, changeSets.getUpdateItems().size());
Assert.assertEquals(1, changeSets.getCreateItems().size());
}
@Test
public void testDeleteBlankItem(){
ItemChangeSets changeSets = resolver.resolve(1, "#qqqq\na=b\nb=c", mockBaseItemWith2Key1Comment1Blank());
Assert.assertEquals(1, changeSets.getDeleteItems().size());
Assert.assertEquals(1, changeSets.getUpdateItems().size());
Assert.assertEquals(0, changeSets.getCreateItems().size());
}
@Test
public void testUpdateItem() {
ItemChangeSets changeSets = resolver.resolve(1, "a=d", mockBaseItemHas3Key());
List<ItemDTO> updateItems = changeSets.getUpdateItems();
Assert.assertEquals(1, updateItems.size());
Assert.assertEquals("d", updateItems.get(0).getValue());
}
@Test
public void testUpdateCommentItem() {
ItemChangeSets changeSets = resolver.resolve(1, "#ww\n"
+ "a=b\n"
+"\n"
+ "b=c", mockBaseItemWith2Key1Comment1Blank());
Assert.assertEquals(1, changeSets.getDeleteItems().size());
Assert.assertEquals(0, changeSets.getUpdateItems().size());
Assert.assertEquals(1, changeSets.getCreateItems().size());
}
@Test
public void testAllSituation(){
ItemChangeSets changeSets = resolver.resolve(1, "#ww\nd=e\nb=c\na=b\n\nq=w\n#eee", mockBaseItemWith2Key1Comment1Blank());
Assert.assertEquals(2, changeSets.getDeleteItems().size());
Assert.assertEquals(2, changeSets.getUpdateItems().size());
Assert.assertEquals(5, changeSets.getCreateItems().size());
}
/**
* a=b b=c c=d
*/
private List<ItemDTO> mockBaseItemHas3Key() {
ItemDTO item1 = new ItemDTO("a", "b", "", 1);
ItemDTO item2 = new ItemDTO("b", "c", "", 2);
ItemDTO item3 = new ItemDTO("c", "d", "", 3);
return Arrays.asList(item1, item2, item3);
}
/**
* #qqqq
* a=b
*
* b=c
*/
private List<ItemDTO> mockBaseItemWith2Key1Comment1Blank() {
ItemDTO i1 = new ItemDTO("", "", "#qqqq", 1);
ItemDTO i2 = new ItemDTO("a", "b", "", 2);
ItemDTO i3 = new ItemDTO("", "", "", 3);
ItemDTO i4 = new ItemDTO("b", "c", "", 4);
i4.setLineNum(4);
return Arrays.asList(i1, i2, i3, i4);
}
}
......@@ -17,3 +17,7 @@ logging:
ctrip:
appid: 100003173
apollo:
portal:
env: dev
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment