Minor code refactor

This commit is contained in:
Jesús Ángel 2018-12-28 09:57:04 +01:00
parent 520a60fe09
commit 3a3937bb64
9 changed files with 502 additions and 362 deletions

View File

@ -311,7 +311,6 @@ export class AgentsController {
this.$scope.switchGroupEdit = () => this.switchGroupEdit();
this.$scope.showConfirm = (ev, group) => {
const confirm = this.$mdDialog
.confirm()
.title(`Add group "${group}" to agent "${this.$scope.agent.id}"?`)
@ -319,21 +318,26 @@ export class AgentsController {
.ok('Agree')
.cancel('Cancel');
this.$mdDialog.show(confirm).then(
this.$mdDialog.show(confirm).then(
() => {
this.groupHandler.addAgentToGroup(group,this.$scope.agent.id)
.then(() => this.apiReq.request('GET',`/agents/${this.$scope.agent.id}`,{}))
.then(agent => {
this.$scope.agent.group = agent.data.data.group;
this.$scope.groups = this.$scope.groups.filter(item => !agent.data.data.group.includes(item));
if(!this.$scope.$$phase) this.$scope.$digest()
})
.catch(error =>
this.errorHandler.handle(
error.message || error,
'Error adding group to agent'
this.groupHandler
.addAgentToGroup(group, this.$scope.agent.id)
.then(() =>
this.apiReq.request('GET', `/agents/${this.$scope.agent.id}`, {})
)
);
.then(agent => {
this.$scope.agent.group = agent.data.data.group;
this.$scope.groups = this.$scope.groups.filter(
item => !agent.data.data.group.includes(item)
);
if (!this.$scope.$$phase) this.$scope.$digest();
})
.catch(error =>
this.errorHandler.handle(
error.message || error,
'Error adding group to agent'
)
);
},
() => {}
);
@ -554,8 +558,8 @@ export class AgentsController {
this.apiReq.request('GET', `/syscollector/${id}/hardware`, {}),
this.apiReq.request('GET', `/syscollector/${id}/os`, {}),
this.apiReq.request('GET', `/syscollector/${id}/netiface`, {}),
this.apiReq.request('GET', `/syscollector/${id}/ports`, {limit:1}),
this.apiReq.request('GET', `/syscollector/${id}/netaddr`, {limit:1}),
this.apiReq.request('GET', `/syscollector/${id}/ports`, { limit: 1 }),
this.apiReq.request('GET', `/syscollector/${id}/netaddr`, { limit: 1 }),
this.apiReq.request('GET', `/syscollector/${id}/packages`, {
limit: 1,
select: 'scan_time'
@ -663,9 +667,14 @@ export class AgentsController {
await this.$scope.switchTab(this.$scope.tab, true);
const groups = await this.apiReq.request('GET','/agents/groups',{});
this.$scope.groups = groups.data.data.items.map(item => item.name).filter(item => this.$scope.agent.group && !this.$scope.agent.group.includes(item));
const groups = await this.apiReq.request('GET', '/agents/groups', {});
this.$scope.groups = groups.data.data.items
.map(item => item.name)
.filter(
item =>
this.$scope.agent.group && !this.$scope.agent.group.includes(item)
);
this.$scope.load = false;
if (!this.$scope.$$phase) this.$scope.$digest();
return;
@ -685,7 +694,7 @@ export class AgentsController {
switchGroupEdit() {
this.$scope.editGroup = !!!this.$scope.editGroup;
if(!this.$scope.$$phase) this.$scope.$digest();
if (!this.$scope.$$phase) this.$scope.$digest();
}
/**
* Navigate to the groups of an agent

View File

@ -168,8 +168,8 @@ export function GroupsController(
});
/**
* This navigate back to agents overview
*/
* This navigate back to agents overview
*/
$scope.goBackToAgents = () => {
$scope.groupsSelectedTab = 'agents';
$scope.file = false;
@ -218,8 +218,8 @@ export function GroupsController(
return;
};
$scope.editGroupAgentConfig = (group) => {
$rootScope.$emit('editXmlFile', { 'target': group });
$scope.editGroupAgentConfig = group => {
$scope.$broadcast('editXmlFile', { target: group });
};
$scope.reload = async (element, searchTerm, addOffset, start) => {
@ -243,20 +243,25 @@ export function GroupsController(
$timeout(() => {
$scope.multipleSelectorLoading = false;
}, 100);
}
};
$scope.loadSelectedAgents = async (searchTerm) => {
$scope.loadSelectedAgents = async searchTerm => {
try {
let params = { 'offset': !searchTerm ? $scope.selectedAgents.offset : 0, 'select': ["id", "name"] };
let params = {
offset: !searchTerm ? $scope.selectedAgents.offset : 0,
select: ['id', 'name']
};
if (searchTerm) {
params.search = searchTerm;
}
const result = await apiReq.request('GET',
const result = await apiReq.request(
'GET',
`/agents/groups/${$scope.currentGroup.name}`,
params);
params
);
$scope.totalSelectedAgents = result.data.data.totalItems;
const mapped = result.data.data.items.map((item) => {
return { 'key': item.id, 'value': item.name };
const mapped = result.data.data.items.map(item => {
return { key: item.id, value: item.name };
});
if (searchTerm) {
$scope.selectedAgents.data = mapped;
@ -264,37 +269,48 @@ export function GroupsController(
} else {
$scope.selectedAgents.data = $scope.selectedAgents.data.concat(mapped);
}
if ($scope.selectedAgents.data.length === 0 || $scope.selectedAgents.data.length < 500 || $scope.selectedAgents.offset >= $scope.totalSelectedAgents) {
if (
$scope.selectedAgents.data.length === 0 ||
$scope.selectedAgents.data.length < 500 ||
$scope.selectedAgents.offset >= $scope.totalSelectedAgents
) {
$scope.selectedAgents.loadedAll = true;
}
} catch (error) {
errorHandler.handle(error, 'Error fetching group agents');
}
$scope.selectedAgents.loaded = true;
}
};
$scope.loadAllAgents = async (searchTerm, start) => {
try {
let params = { 'offset': !searchTerm ? $scope.availableAgents.offset : 0, 'select': ["id", "name"] };
let params = {
offset: !searchTerm ? $scope.availableAgents.offset : 0,
select: ['id', 'name']
};
if (searchTerm) {
params.search = searchTerm;
$scope.availableAgents.offset = 0;
}
const req = await apiReq.request('GET',
'/agents/',
params);
const req = await apiReq.request('GET', '/agents/', params);
$scope.totalAgents = req.data.data.totalItems;
const mapped = req.data.data.items.filter((item) => {
return $scope.selectedAgents.data.filter((selected) => {
return selected.key == item.id;
}).length == 0 && item.id !== '000';
}).map((item) => {
return { 'key': item.id, 'value': item.name };
});
const mapped = req.data.data.items
.filter(item => {
return (
$scope.selectedAgents.data.filter(selected => {
return selected.key == item.id;
}).length == 0 && item.id !== '000'
);
})
.map(item => {
return { key: item.id, value: item.name };
});
if (searchTerm || start) {
$scope.availableAgents.data = mapped;
} else {
$scope.availableAgents.data = $scope.availableAgents.data.concat(mapped);
$scope.availableAgents.data = $scope.availableAgents.data.concat(
mapped
);
}
if ($scope.availableAgents.data.length === 0 && !searchTerm) {
if ($scope.availableAgents.offset >= $scope.totalAgents) {
@ -308,13 +324,23 @@ export function GroupsController(
} catch (error) {
errorHandler.handle(error, 'Error fetching all available agents');
}
}
};
$scope.addMultipleAgents = async (toggle) => {
$scope.addMultipleAgents = async toggle => {
$scope.addingAgents = toggle;
if (toggle && !$scope.availableAgents.loaded) {
$scope.availableAgents = { 'loaded': false, 'data': [], 'offset': 0, 'loadedAll': false };
$scope.selectedAgents = { 'loaded': false, 'data': [], 'offset': 0, 'loadedAll': false };
$scope.availableAgents = {
loaded: false,
data: [],
offset: 0,
loadedAll: false
};
$scope.selectedAgents = {
loaded: false,
data: [],
offset: 0,
loadedAll: false
};
$scope.multipleSelectorLoading = true;
while (!$scope.selectedAgents.loadedAll) {
await $scope.loadSelectedAgents();
@ -334,19 +360,22 @@ export function GroupsController(
$scope.deletedAgents = [];
$scope.addedAgents = [];
modified.forEach((mod) => {
modified.forEach(mod => {
if (original.filter(e => e.key === mod.key).length === 0) {
$scope.addedAgents.push(mod);
}
});
original.forEach((orig) => {
original.forEach(orig => {
if (modified.filter(e => e.key === orig.key).length === 0) {
$scope.deletedAgents.push(orig);
}
});
return { 'addedIds': [...new Set($scope.addedAgents.map(x => x.key))], 'deletedIds': [...new Set($scope.deletedAgents.map(x => x.key))] }
}
return {
addedIds: [...new Set($scope.addedAgents.map(x => x.key))],
deletedIds: [...new Set($scope.deletedAgents.map(x => x.key))]
};
};
$scope.saveAddAgents = async () => {
const itemsToSave = $scope.getItemsToSave();
@ -355,28 +384,34 @@ export function GroupsController(
try {
$scope.multipleSelectorLoading = true;
if (itemsToSave.addedIds.length) {
const addResponse = await apiReq.request('POST', `/agents/group/${$scope.currentGroup.name}`, { 'ids': itemsToSave.addedIds });
const addResponse = await apiReq.request(
'POST',
`/agents/group/${$scope.currentGroup.name}`,
{ ids: itemsToSave.addedIds }
);
if (addResponse.data.data.failed_ids) {
failedIds.push(...addResponse.data.data.failed_ids)
failedIds.push(...addResponse.data.data.failed_ids);
}
}
if (itemsToSave.deletedIds.length) {
const deleteResponse = await apiReq.request('DELETE', `/agents/group/${$scope.currentGroup.name}`, { 'ids': itemsToSave.deletedIds });
const deleteResponse = await apiReq.request(
'DELETE',
`/agents/group/${$scope.currentGroup.name}`,
{ ids: itemsToSave.deletedIds }
);
if (deleteResponse.data.data.failed_ids) {
failedIds.push(...deleteResponse.data.data.failed_ids)
failedIds.push(...deleteResponse.data.data.failed_ids);
}
}
if (failedIds.length) {
errorHandler.info(
`Warning. Group has been updated but an error has occurred with the following agents ${failedIds}`,
'', true
'',
true
);
} else {
errorHandler.info(
'Success. Group has been updated',
''
);
errorHandler.info('Success. Group has been updated', '');
}
$scope.addMultipleAgents(false);
} catch (err) {
@ -384,27 +419,40 @@ export function GroupsController(
}
$timeout(() => {
$scope.multipleSelectorLoading = false;
$scope.$emit('updateGroupInformation', { 'group': $scope.currentGroup.name });
$scope.$emit('updateGroupInformation', {
group: $scope.currentGroup.name
});
}, 100);
}
};
$scope.checkLimit = () => {
if ($scope.firstSelectedList) {
const itemsToSave = $scope.getItemsToSave();
$scope.currentAdding = itemsToSave.addedIds.length;
$scope.currentDeleting = itemsToSave.deletedIds.length;
$scope.moreThan1000 = $scope.currentAdding > 1000 || $scope.currentDeleting > 1000;
$scope.moreThan1000 =
$scope.currentAdding > 1000 || $scope.currentDeleting > 1000;
}
};
// Resetting the factory configuration
$scope.$on('$destroy', () => { });
$scope.$on('$destroy', () => {});
$scope.$watch('lookingGroup', value => {
$scope.availableAgents = { 'loaded': false, 'data': [], 'offset': 0, 'loadedAll': false };
$scope.selectedAgents = { 'loaded': false, 'data': [], 'offset': 0, 'loadedAll': false };
$scope.availableAgents = {
loaded: false,
data: [],
offset: 0,
loadedAll: false
};
$scope.selectedAgents = {
loaded: false,
data: [],
offset: 0,
loadedAll: false
};
$scope.addMultipleAgents(false);
$rootScope.$emit('closeEditXmlFile', {});
$scope.$broadcast('closeEditXmlFile', {});
if (!value) {
$scope.file = false;
$scope.filename = false;

View File

@ -15,7 +15,7 @@ import { uiModules } from 'ui/modules';
const app = uiModules.get('app/wazuh', []);
app.directive('wzMultipleSelector', function () {
app.directive('wzMultipleSelector', function() {
return {
restrict: 'E',
scope: {
@ -29,16 +29,12 @@ app.directive('wzMultipleSelector', function () {
totalAvailableItems: '=',
reloadScroll: '&'
},
controller(
$scope
) {
$scope.moveItem = function (item, from, to, type) {
if (item.length > 0) {
item.forEach(function (elem) {
$scope.moveItem(elem, from, to, type);
});
controller($scope) {
$scope.moveItem = (item, from, to, type) => {
if (item.length) {
item.forEach(elem => $scope.moveItem(elem, from, to, type));
} else {
var idx = from.findIndex((x) => x.key === item.key);
const idx = from.findIndex(x => x.key === item.key);
if (idx !== -1) {
from.splice(idx, 1);
item.type = !item.type ? type : '';
@ -46,8 +42,9 @@ app.directive('wzMultipleSelector', function () {
}
}
};
$scope.moveAll = function (from, to, type) {
from.forEach(function (item) {
$scope.moveAll = (from, to, type) => {
from.forEach(item => {
item.type = !item.type ? type : '';
to.push(item);
});
@ -58,32 +55,31 @@ app.directive('wzMultipleSelector', function () {
if ($scope.checkLimit) {
$scope.checkLimit();
}
}
};
$scope.sort = (a) => {
$scope.sort = a => {
return parseInt(a.key);
}
};
$('#wzMultipleSelector select').scroll(function (ev) {
$scope.scrollList(ev.currentTarget);
$('#wzMultipleSelector select').scroll(function(ev) {
scrollList(ev.currentTarget);
});
$scope.doReload = (side, term, fromStart = false) => {
$scope.reloadScroll({ 'element': side, 'searchTerm': term, 'start': fromStart });
}
$scope.scrollList = (target) => {
let pos = target.scrollTop + target.offsetHeight;
let max = target.scrollHeight;
$scope.doReload = (element, searchTerm, start = false) => {
$scope.reloadScroll({ element, searchTerm, start });
};
const scrollList = target => {
const pos = target.scrollTop + target.offsetHeight;
const max = target.scrollHeight;
if (pos >= max) {
target.parentElement.parentElement.parentElement.className === 'wzMultipleSelectorLeft' ? $scope.doReload('left') : $scope.doReload('right');
target.parentElement.parentElement.parentElement.className ===
'wzMultipleSelectorLeft'
? $scope.doReload('left')
: $scope.doReload('right');
}
}
};
},
template
};
});

View File

@ -38,7 +38,6 @@ app.directive('wzTable', function() {
extraLimit: '=extraLimit'
},
controller(
$rootScope,
$scope,
apiReq,
$timeout,
@ -276,16 +275,18 @@ app.directive('wzTable', function() {
};
$scope.editGroupAgentConfig = (ev, group) => {
$rootScope.$emit('editXmlFile', { 'target' : group });
$scope.$broadcast('editXmlFile', { target: group });
};
$scope.showConfirm = function (ev, agent) {
$scope.showConfirm = function(ev, agent) {
const group = instance.path.split('/').pop();
const confirm = $mdDialog
.confirm()
.title("Remove agent from group?")
.textContent(`The agent '${agent.id}' will be removed from group '${group}'.`)
.title('Remove agent from group?')
.textContent(
`The agent '${agent.id}' will be removed from group '${group}'.`
)
.targetEvent(ev)
.clickOutsideToClose(false)
.escapeToClose(false)
@ -305,7 +306,7 @@ app.directive('wzTable', function() {
)
);
},
() => { }
() => {}
);
};
},

View File

@ -53,8 +53,12 @@ app.directive('wzTagFilter', function() {
value: term[1] ? term[1].trim() : ''
};
const isFilter = obj.value;
if ((isFilter && $scope.fieldsModel && Object.keys($scope.fieldsModel).indexOf(obj.name) === -1) ||
(!isFilter && (!obj.name || /^\s*$/.test(obj.name)))) {
if (
(isFilter &&
$scope.fieldsModel &&
Object.keys($scope.fieldsModel).indexOf(obj.name) === -1) ||
(!isFilter && (!obj.name || /^\s*$/.test(obj.name)))
) {
$scope.showAutocomplete(flag);
$scope.newTag = '';
} else {
@ -64,14 +68,12 @@ app.directive('wzTagFilter', function() {
value: obj,
type: isFilter ? 'filter' : 'search'
};
const idxSearch = $scope.tagList.find(function(x) {
return x.type === 'search';
});
const idxSearch = $scope.tagList.find(x => x.type === 'search');
if (!isFilter && idxSearch) {
$scope.removeTag(idxSearch.id, false);
}
if (
!$scope.tagList.find(function(x) {
!$scope.tagList.find(x => {
return (
x.type === 'filter' &&
x.key === tag.key &&
@ -97,15 +99,13 @@ app.directive('wzTagFilter', function() {
*/
const buildQuery = groups => {
try {
let queryObj = {
const queryObj = {
query: '',
search: ''
};
let first = true;
groups.forEach(function(group) {
const search = group.find(function(x) {
return x.type === 'search';
});
for(const group of groups) {
const search = group.find(x => x.type === 'search');
if (search) {
queryObj.search = search.value.name;
} else {
@ -117,10 +117,8 @@ app.directive('wzTagFilter', function() {
queryObj.query += '(';
}
group
.filter(function(x) {
return x.type === 'filter';
})
.forEach(function(tag, idx2) {
.filter(x => x.type === 'filter')
.forEach((tag, idx2) => {
queryObj.query += tag.key + '=' + tag.value.value;
if (idx2 != group.length - 1) {
queryObj.query += ',';
@ -131,7 +129,7 @@ app.directive('wzTagFilter', function() {
}
first = false;
}
});
}
$scope.queryFn({ q: queryObj.query, search: queryObj.search });
} catch (error) {
errorHandler.handle(error, 'Error in query request');
@ -144,19 +142,16 @@ app.directive('wzTagFilter', function() {
* @param {Object} property
*/
const groupBy = (collection, property) => {
let i = 0,
val,
index,
values = [],
result = [];
for (; i < collection.length; i++) {
val = collection[i][property];
index = values.indexOf(val);
if (index > -1 && collection[i].type === 'filter')
result[index].push(collection[i]);
const values = [];
const result = [];
for (const item of collection) {
const index = values.indexOf(item[property]);
if (index > -1 && item.type === 'filter')
result[index].push(item);
else {
values.push(val);
result.push([collection[i]]);
values.push(item[property]);
result.push([item]);
}
}
return result;
@ -187,14 +182,10 @@ app.directive('wzTagFilter', function() {
*/
$scope.removeTag = (id, deleteGroup) => {
if (deleteGroup) {
$scope.tagList = $scope.tagList.filter(function(x) {
return x.key !== id;
});
$scope.tagList = $scope.tagList.filter(x => x.key !== id);
} else {
$scope.tagList.splice(
$scope.tagList.findIndex(function(x) {
return x.id === id;
}),
$scope.tagList.findIndex(x => x.id === id),
1
);
}
@ -223,21 +214,17 @@ app.directive('wzTagFilter', function() {
$scope.autocompleteContent = { title: '', isKey: isKey, list: [] };
$scope.autocompleteContent.title = isKey ? 'Filter keys' : 'Values';
if (isKey && $scope.fieldsModel) {
for (let key in $scope.fieldsModel) {
for (const key in $scope.fieldsModel) {
if (key.toUpperCase().includes(term[0].trim().toUpperCase())) {
$scope.autocompleteContent.list.push(key);
}
}
} else {
const model = $scope.dataModel.find(function(x) {
return x.key === $scope.newTag.split(':')[0].trim();
});
const model = $scope.dataModel.find(x => x.key === $scope.newTag.split(':')[0].trim());
if (model) {
$scope.autocompleteContent.list = [
...new Set(
model.list.filter(function(x) {
return x.toUpperCase().includes(term[1].trim().toUpperCase());
})
model.list.filter(x => x.toUpperCase().includes(term[1].trim().toUpperCase()))
)
];
}
@ -259,7 +246,7 @@ app.directive('wzTagFilter', function() {
* @param {Boolean} flag Indicate if after apply style the autocomplete have to be shown
*/
const indexAutocomplete = (flag = true) => {
$timeout(function() {
$timeout(() => {
const bar = $document[0].getElementById('wz-search-filter-bar');
const autocomplete = $document[0].getElementById(
'wz-search-filter-bar-autocomplete'
@ -285,8 +272,9 @@ app.directive('wzTagFilter', function() {
//Use when api call be implemented
//const result = await instance.fetch();
if ($scope.fieldsModel) {
Object.keys($scope.fieldsModel).forEach(function (key) {
$scope.dataModel.push({ 'key': key, 'list': $scope.fieldsModel[key] });
Object.keys($scope.fieldsModel).forEach(key => {
const list = $scope.fieldsModel[key];
$scope.dataModel.push({ key, list });
});
}
return;

View File

@ -16,7 +16,7 @@ import { uiModules } from 'ui/modules';
const app = uiModules.get('app/wazuh', []);
app.directive('wzXmlFileEditor', function () {
app.directive('wzXmlFileEditor', function() {
return {
restrict: 'E',
scope: {
@ -24,15 +24,8 @@ app.directive('wzXmlFileEditor', function () {
updatePath: '=updatePath',
fileName: '@fileName'
},
controller(
$rootScope,
$scope,
$timeout,
apiReq,
$document,
errorHandler
) {
$($document[0]).ready(function () {
controller($scope, $timeout, apiReq, $document, errorHandler) {
$($document[0]).ready(function() {
$scope.xmlCodeBox = CodeMirror.fromTextArea(
$document[0].getElementById('xml_box'),
{
@ -52,42 +45,43 @@ app.directive('wzXmlFileEditor', function () {
});
const checkXmlParseError = () => {
try {
var parser = new DOMParser();
var xml = $scope.xmlCodeBox.getValue();
var xmlDoc = parser.parseFromString(xml, "text/xml");
$timeout(function () {
$scope.xmlHasErrors = xmlDoc.getElementsByTagName("parsererror").length > 0 ? true : false
const parser = new DOMParser(); // eslint-disable-line
const xml = $scope.xmlCodeBox.getValue();
const xmlDoc = parser.parseFromString(xml, 'text/xml');
$timeout(function() {
$scope.xmlHasErrors =
xmlDoc.getElementsByTagName('parsererror').length > 0
? true
: false;
}, 50);
} catch (error) {
errorHandler.handle(error, 'Error validating XML');
}
}
};
});
const autoFormat = () => {
var totalLines = $scope.xmlCodeBox.lineCount();
$scope.xmlCodeBox.autoFormatRange({ 'line': 0, 'ch': 0 }, { line: totalLines - 1 });
const totalLines = $scope.xmlCodeBox.lineCount();
$scope.xmlCodeBox.autoFormatRange(
{ line: 0, ch: 0 },
{ line: totalLines - 1 }
);
$scope.xmlCodeBox.setCursor(0);
}
};
const updateFile = async () => {
$scope.saveFile = async () => {
try {
/*const response = await this.apiReq.request(
'PUT',
$scope.updatePath,
{}
);*/
const response = "";
const response = '';
return response;
} catch (error) {
this.apiInputBox.model = [];
}
}
$scope.saveFile = async () => {
const response = await updateFile();
console.log(response);
}
};
const fetchFile = async () => {
try {
@ -96,16 +90,17 @@ app.directive('wzXmlFileEditor', function () {
$scope.loadPath,
{}
);*/
const xml = "<agent_config>" +
"\n" +
"<!-- Shared agent configuration here -->\n" +
"\n" +
"</agent_config>";
const xml =
'<agent_config>' +
'\n' +
'<!-- Shared agent configuration here -->\n' +
'\n' +
'</agent_config>';
return xml;
} catch (error) {
errorHandler.handle(error, 'Fetch file error');
}
}
};
$scope.editXmlFile = async (item, params) => {
$scope.editingFile = true;
@ -116,13 +111,17 @@ app.directive('wzXmlFileEditor', function () {
$scope.xmlCodeBox.setValue(xml);
autoFormat();
$scope.loadingFile = false;
$timeout(function () { $scope.xmlCodeBox.refresh() }, 100);
$timeout(function() {
$scope.xmlCodeBox.refresh();
}, 100);
} catch (error) {
errorHandler.handle(error, 'Fetch file error');
}
};
$rootScope.$on('editXmlFile', (item, params) => $scope.editXmlFile(item, params));
$rootScope.$on('closeEditXmlFile', () => $scope.editingFile = false);
$scope.$on('editXmlFile', (item, params) =>
$scope.editXmlFile(item, params)
);
$scope.$on('closeEditXmlFile', () => ($scope.editingFile = false));
},
template
};

View File

@ -16,7 +16,11 @@ export class GroupHandler {
async removeAgentFromGroup(group, agentId) {
try {
const result = await this.apiReq.request('DELETE',`/agents/${agentId}/group/${group}`,{})
const result = await this.apiReq.request(
'DELETE',
`/agents/${agentId}/group/${group}`,
{}
);
return result;
} catch (error) {
return Promise.reject(error);
@ -25,7 +29,11 @@ export class GroupHandler {
async addAgentToGroup(group, agentId) {
try {
const result = await this.apiReq.request('PUT',`/agents/${agentId}/group/${group}`,{})
const result = await this.apiReq.request(
'PUT',
`/agents/${agentId}/group/${group}`,
{}
);
return result;
} catch (error) {
return Promise.reject(error);

View File

@ -10,56 +10,66 @@
})(function(CodeMirror) {
'use strict';
CodeMirror.extendMode("css", {
commentStart: "/*",
commentEnd: "*/",
CodeMirror.extendMode('css', {
commentStart: '/*',
commentEnd: '*/',
newlineAfterToken: function(type, content) {
return /^[;{}]$/.test(content);
}
});
CodeMirror.extendMode("javascript", {
commentStart: "/*",
commentEnd: "*/",
CodeMirror.extendMode('javascript', {
commentStart: '/*',
commentEnd: '*/',
// FIXME semicolons inside of for
newlineAfterToken: function(type, content, textAfter, state) {
if (this.jsonMode) {
return /^[\[,{]$/.test(content) || /^}/.test(textAfter);
} else {
if (content == ";" && state.lexical && state.lexical.type == ")") return false;
if (content == ';' && state.lexical && state.lexical.type == ')')
return false;
return /^[;{}]$/.test(content) && !/^;/.test(textAfter);
}
}
});
CodeMirror.extendMode("xml", {
commentStart: "<!--",
commentEnd: "-->",
CodeMirror.extendMode('xml', {
commentStart: '<!--',
commentEnd: '-->',
newlineAfterToken: function(type, content, textAfter) {
return type == "tag" && />$/.test(content) || /^</.test(textAfter);
return (type == 'tag' && />$/.test(content)) || /^</.test(textAfter);
}
});
// Comment/uncomment the specified range
CodeMirror.defineExtension("commentRange", function (isComment, from, to) {
var cm = this, curMode = CodeMirror.innerMode(cm.getMode(), cm.getTokenAt(from).state).mode;
CodeMirror.defineExtension('commentRange', function(isComment, from, to) {
var cm = this,
curMode = CodeMirror.innerMode(cm.getMode(), cm.getTokenAt(from).state)
.mode;
cm.operation(function() {
if (isComment) { // Comment range
if (isComment) {
// Comment range
cm.replaceRange(curMode.commentEnd, to);
cm.replaceRange(curMode.commentStart, from);
if (from.line == to.line && from.ch == to.ch) // An empty comment inserted - put cursor inside
if (from.line == to.line && from.ch == to.ch)
// An empty comment inserted - put cursor inside
cm.setCursor(from.line, from.ch + curMode.commentStart.length);
} else { // Uncomment range
} else {
// Uncomment range
var selText = cm.getRange(from, to);
var startIndex = selText.indexOf(curMode.commentStart);
var endIndex = selText.lastIndexOf(curMode.commentEnd);
if (startIndex > -1 && endIndex > -1 && endIndex > startIndex) {
// Take string till comment start
selText = selText.substr(0, startIndex)
// From comment start till comment end
+ selText.substring(startIndex + curMode.commentStart.length, endIndex)
// From comment end till string end
+ selText.substr(endIndex + curMode.commentEnd.length);
selText =
selText.substr(0, startIndex) +
// From comment start till comment end
selText.substring(
startIndex + curMode.commentStart.length,
endIndex
) +
// From comment end till string end
selText.substr(endIndex + curMode.commentEnd.length);
}
cm.replaceRange(selText, from, to);
}
@ -67,25 +77,28 @@
});
// Applies automatic mode-aware indentation to the specified range
CodeMirror.defineExtension("autoIndentRange", function (from, to) {
CodeMirror.defineExtension('autoIndentRange', function(from, to) {
var cmInstance = this;
this.operation(function () {
this.operation(function() {
for (var i = from.line; i <= to.line; i++) {
cmInstance.indentLine(i, "smart");
cmInstance.indentLine(i, 'smart');
}
});
});
// Applies automatic formatting to the specified range
CodeMirror.defineExtension("autoFormatRange", function (from, to) {
CodeMirror.defineExtension('autoFormatRange', function(from, to) {
var cm = this;
var outer = cm.getMode(), text = cm.getRange(from, to).split("\n");
var outer = cm.getMode(),
text = cm.getRange(from, to).split('\n');
var state = CodeMirror.copyState(outer, cm.getTokenAt(from).state);
var tabSize = cm.getOption("tabSize");
var tabSize = cm.getOption('tabSize');
var out = "", lines = 0, atSol = from.ch == 0;
var out = '',
lines = 0,
atSol = from.ch == 0;
function newline() {
out += "\n";
out += '\n';
atSol = true;
++lines;
}
@ -94,24 +107,33 @@
var stream = new CodeMirror.StringStream(text[i], tabSize);
while (!stream.eol()) {
var inner = CodeMirror.innerMode(outer, state);
var style = outer.token(stream, state), cur = stream.current();
var style = outer.token(stream, state),
cur = stream.current();
stream.start = stream.pos;
if (!atSol || /\S/.test(cur)) {
out += cur;
atSol = false;
}
if (!atSol && inner.mode.newlineAfterToken &&
inner.mode.newlineAfterToken(style, cur, stream.string.slice(stream.pos) || text[i+1] || "", inner.state))
if (
!atSol &&
inner.mode.newlineAfterToken &&
inner.mode.newlineAfterToken(
style,
cur,
stream.string.slice(stream.pos) || text[i + 1] || '',
inner.state
)
)
newline();
}
if (!stream.pos && outer.blankLine) outer.blankLine(state);
if (!atSol) newline();
}
cm.operation(function () {
cm.operation(function() {
cm.replaceRange(out, from, to);
for (var cur = from.line + 1, end = from.line + lines; cur <= end; ++cur)
cm.indentLine(cur, "smart");
cm.indentLine(cur, 'smart');
cm.setSelection(from, cm.getCursor(false));
});
});

View File

@ -1,7 +1,7 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: https://codemirror.net/LICENSE
(function (mod) {
(function(mod) {
if (typeof exports == 'object' && typeof module == 'object')
// CommonJS
mod(require('./lib/codemirror'));
@ -10,48 +10,93 @@
define(['./lib/codemirror'], mod);
// Plain browser env
else mod(CodeMirror);
})(function (CodeMirror) {
"use strict";
})(function(CodeMirror) {
'use strict';
var htmlConfig = {
autoSelfClosers: {
'area': true, 'base': true, 'br': true, 'col': true, 'command': true,
'embed': true, 'frame': true, 'hr': true, 'img': true, 'input': true,
'keygen': true, 'link': true, 'meta': true, 'param': true, 'source': true,
'track': true, 'wbr': true, 'menuitem': true
area: true,
base: true,
br: true,
col: true,
command: true,
embed: true,
frame: true,
hr: true,
img: true,
input: true,
keygen: true,
link: true,
meta: true,
param: true,
source: true,
track: true,
wbr: true,
menuitem: true
},
implicitlyClosed: {
'dd': true, 'li': true, 'optgroup': true, 'option': true, 'p': true,
'rp': true, 'rt': true, 'tbody': true, 'td': true, 'tfoot': true,
'th': true, 'tr': true
dd: true,
li: true,
optgroup: true,
option: true,
p: true,
rp: true,
rt: true,
tbody: true,
td: true,
tfoot: true,
th: true,
tr: true
},
contextGrabbers: {
'dd': { 'dd': true, 'dt': true },
'dt': { 'dd': true, 'dt': true },
'li': { 'li': true },
'option': { 'option': true, 'optgroup': true },
'optgroup': { 'optgroup': true },
'p': {
'address': true, 'article': true, 'aside': true, 'blockquote': true, 'dir': true,
'div': true, 'dl': true, 'fieldset': true, 'footer': true, 'form': true,
'h1': true, 'h2': true, 'h3': true, 'h4': true, 'h5': true, 'h6': true,
'header': true, 'hgroup': true, 'hr': true, 'menu': true, 'nav': true, 'ol': true,
'p': true, 'pre': true, 'section': true, 'table': true, 'ul': true
dd: { dd: true, dt: true },
dt: { dd: true, dt: true },
li: { li: true },
option: { option: true, optgroup: true },
optgroup: { optgroup: true },
p: {
address: true,
article: true,
aside: true,
blockquote: true,
dir: true,
div: true,
dl: true,
fieldset: true,
footer: true,
form: true,
h1: true,
h2: true,
h3: true,
h4: true,
h5: true,
h6: true,
header: true,
hgroup: true,
hr: true,
menu: true,
nav: true,
ol: true,
p: true,
pre: true,
section: true,
table: true,
ul: true
},
'rp': { 'rp': true, 'rt': true },
'rt': { 'rp': true, 'rt': true },
'tbody': { 'tbody': true, 'tfoot': true },
'td': { 'td': true, 'th': true },
'tfoot': { 'tbody': true },
'th': { 'td': true, 'th': true },
'thead': { 'tbody': true, 'tfoot': true },
'tr': { 'tr': true }
rp: { rp: true, rt: true },
rt: { rp: true, rt: true },
tbody: { tbody: true, tfoot: true },
td: { td: true, th: true },
tfoot: { tbody: true },
th: { td: true, th: true },
thead: { tbody: true, tfoot: true },
tr: { tr: true }
},
doNotIndent: { "pre": true },
doNotIndent: { pre: true },
allowUnquoted: true,
allowMissing: true,
caseFold: true
}
};
var xmlConfig = {
autoSelfClosers: {},
@ -62,14 +107,14 @@
allowMissing: false,
allowMissingTagName: false,
caseFold: false
}
};
CodeMirror.defineMode("xml", function (editorConf, config_) {
var indentUnit = editorConf.indentUnit
var config = {}
var defaults = config_.htmlMode ? htmlConfig : xmlConfig
for (var prop in defaults) config[prop] = defaults[prop]
for (var prop in config_) config[prop] = config_[prop]
CodeMirror.defineMode('xml', function(editorConf, config_) {
var indentUnit = editorConf.indentUnit;
var config = {};
var defaults = config_.htmlMode ? htmlConfig : xmlConfig;
for (var prop in defaults) config[prop] = defaults[prop];
for (var prop in config_) config[prop] = config_[prop];
// Return variables for tokenizers
var type, setStyle;
@ -81,40 +126,40 @@
}
var ch = stream.next();
if (ch == "<") {
if (stream.eat("!")) {
if (stream.eat("[")) {
if (stream.match("CDATA[")) return chain(inBlock("atom", "]]>"));
if (ch == '<') {
if (stream.eat('!')) {
if (stream.eat('[')) {
if (stream.match('CDATA[')) return chain(inBlock('atom', ']]>'));
else return null;
} else if (stream.match("--")) {
return chain(inBlock("comment", "-->"));
} else if (stream.match("DOCTYPE", true, true)) {
} else if (stream.match('--')) {
return chain(inBlock('comment', '-->'));
} else if (stream.match('DOCTYPE', true, true)) {
stream.eatWhile(/[\w\._\-]/);
return chain(doctype(1));
} else {
return null;
}
} else if (stream.eat("?")) {
} else if (stream.eat('?')) {
stream.eatWhile(/[\w\._\-]/);
state.tokenize = inBlock("meta", "?>");
return "meta";
state.tokenize = inBlock('meta', '?>');
return 'meta';
} else {
type = stream.eat("/") ? "closeTag" : "openTag";
type = stream.eat('/') ? 'closeTag' : 'openTag';
state.tokenize = inTag;
return "tag bracket";
return 'tag bracket';
}
} else if (ch == "&") {
} else if (ch == '&') {
var ok;
if (stream.eat("#")) {
if (stream.eat("x")) {
ok = stream.eatWhile(/[a-fA-F\d]/) && stream.eat(";");
if (stream.eat('#')) {
if (stream.eat('x')) {
ok = stream.eatWhile(/[a-fA-F\d]/) && stream.eat(';');
} else {
ok = stream.eatWhile(/[\d]/) && stream.eat(";");
ok = stream.eatWhile(/[\d]/) && stream.eat(';');
}
} else {
ok = stream.eatWhile(/[\w\.\-:]/) && stream.eat(";");
ok = stream.eatWhile(/[\w\.\-:]/) && stream.eat(';');
}
return ok ? "atom" : "error";
return ok ? 'atom' : 'error';
} else {
stream.eatWhile(/[^&<]/);
return null;
@ -124,45 +169,45 @@
function inTag(stream, state) {
var ch = stream.next();
if (ch == ">" || (ch == "/" && stream.eat(">"))) {
if (ch == '>' || (ch == '/' && stream.eat('>'))) {
state.tokenize = inText;
type = ch == ">" ? "endTag" : "selfcloseTag";
return "tag bracket";
} else if (ch == "=") {
type = "equals";
type = ch == '>' ? 'endTag' : 'selfcloseTag';
return 'tag bracket';
} else if (ch == '=') {
type = 'equals';
return null;
} else if (ch == "<") {
} else if (ch == '<') {
state.tokenize = inText;
state.state = baseState;
state.tagName = state.tagStart = null;
var next = state.tokenize(stream, state);
return next ? next + " tag error" : "tag error";
return next ? next + ' tag error' : 'tag error';
} else if (/[\'\"]/.test(ch)) {
state.tokenize = inAttribute(ch);
state.stringStartCol = stream.column();
return state.tokenize(stream, state);
} else {
stream.match(/^[^\s\u00a0=<>\"\']*[^\s\u00a0=<>\"\'\/]/);
return "word";
return 'word';
}
}
function inAttribute(quote) {
var closure = function (stream, state) {
var closure = function(stream, state) {
while (!stream.eol()) {
if (stream.next() == quote) {
state.tokenize = inTag;
break;
}
}
return "string";
return 'string';
};
closure.isInAttribute = true;
return closure;
}
function inBlock(style, terminator) {
return function (stream, state) {
return function(stream, state) {
while (!stream.eol()) {
if (stream.match(terminator)) {
state.tokenize = inText;
@ -171,17 +216,17 @@
stream.next();
}
return style;
}
};
}
function doctype(depth) {
return function (stream, state) {
return function(stream, state) {
var ch;
while ((ch = stream.next()) != null) {
if (ch == "<") {
if (ch == '<') {
state.tokenize = doctype(depth + 1);
return state.tokenize(stream, state);
} else if (ch == ">") {
} else if (ch == '>') {
if (depth == 1) {
state.tokenize = inText;
break;
@ -191,7 +236,7 @@
}
}
}
return "meta";
return 'meta';
};
}
@ -200,7 +245,10 @@
this.tagName = tagName;
this.indent = state.indented;
this.startOfLine = startOfLine;
if (config.doNotIndent.hasOwnProperty(tagName) || (state.context && state.context.noIndent))
if (
config.doNotIndent.hasOwnProperty(tagName) ||
(state.context && state.context.noIndent)
)
this.noIndent = true;
}
function popContext(state) {
@ -213,8 +261,10 @@
return;
}
parentTagName = state.context.tagName;
if (!config.contextGrabbers.hasOwnProperty(parentTagName) ||
!config.contextGrabbers[parentTagName].hasOwnProperty(nextTagName)) {
if (
!config.contextGrabbers.hasOwnProperty(parentTagName) ||
!config.contextGrabbers[parentTagName].hasOwnProperty(nextTagName)
) {
return;
}
popContext(state);
@ -222,135 +272,150 @@
}
function baseState(type, stream, state) {
if (type == "openTag") {
if (type == 'openTag') {
state.tagStart = stream.column();
return tagNameState;
} else if (type == "closeTag") {
} else if (type == 'closeTag') {
return closeTagNameState;
} else {
return baseState;
}
}
function tagNameState(type, stream, state) {
if (type == "word") {
if (type == 'word') {
state.tagName = stream.current();
setStyle = "tag";
setStyle = 'tag';
return attrState;
} else if (config.allowMissingTagName && type == "endTag") {
setStyle = "tag bracket";
} else if (config.allowMissingTagName && type == 'endTag') {
setStyle = 'tag bracket';
return attrState(type, stream, state);
} else {
setStyle = "error";
setStyle = 'error';
return tagNameState;
}
}
function closeTagNameState(type, stream, state) {
if (type == "word") {
if (type == 'word') {
var tagName = stream.current();
if (state.context && state.context.tagName != tagName &&
config.implicitlyClosed.hasOwnProperty(state.context.tagName))
if (
state.context &&
state.context.tagName != tagName &&
config.implicitlyClosed.hasOwnProperty(state.context.tagName)
)
popContext(state);
if ((state.context && state.context.tagName == tagName) || config.matchClosing === false) {
setStyle = "tag";
if (
(state.context && state.context.tagName == tagName) ||
config.matchClosing === false
) {
setStyle = 'tag';
return closeState;
} else {
setStyle = "tag error";
setStyle = 'tag error';
return closeStateErr;
}
} else if (config.allowMissingTagName && type == "endTag") {
setStyle = "tag bracket";
} else if (config.allowMissingTagName && type == 'endTag') {
setStyle = 'tag bracket';
return closeState(type, stream, state);
} else {
setStyle = "error";
setStyle = 'error';
return closeStateErr;
}
}
function closeState(type, _stream, state) {
if (type != "endTag") {
setStyle = "error";
if (type != 'endTag') {
setStyle = 'error';
return closeState;
}
popContext(state);
return baseState;
}
function closeStateErr(type, stream, state) {
setStyle = "error";
setStyle = 'error';
return closeState(type, stream, state);
}
function attrState(type, _stream, state) {
if (type == "word") {
setStyle = "attribute";
if (type == 'word') {
setStyle = 'attribute';
return attrEqState;
} else if (type == "endTag" || type == "selfcloseTag") {
var tagName = state.tagName, tagStart = state.tagStart;
} else if (type == 'endTag' || type == 'selfcloseTag') {
var tagName = state.tagName,
tagStart = state.tagStart;
state.tagName = state.tagStart = null;
if (type == "selfcloseTag" ||
config.autoSelfClosers.hasOwnProperty(tagName)) {
if (
type == 'selfcloseTag' ||
config.autoSelfClosers.hasOwnProperty(tagName)
) {
maybePopContext(state, tagName);
} else {
maybePopContext(state, tagName);
state.context = new Context(state, tagName, tagStart == state.indented);
state.context = new Context(
state,
tagName,
tagStart == state.indented
);
}
return baseState;
}
setStyle = "error";
setStyle = 'error';
return attrState;
}
function attrEqState(type, stream, state) {
if (type == "equals") return attrValueState;
if (!config.allowMissing) setStyle = "error";
if (type == 'equals') return attrValueState;
if (!config.allowMissing) setStyle = 'error';
return attrState(type, stream, state);
}
function attrValueState(type, stream, state) {
if (type == "string") return attrContinuedState;
if (type == "word" && config.allowUnquoted) { setStyle = "string"; return attrState; }
setStyle = "error";
if (type == 'string') return attrContinuedState;
if (type == 'word' && config.allowUnquoted) {
setStyle = 'string';
return attrState;
}
setStyle = 'error';
return attrState(type, stream, state);
}
function attrContinuedState(type, stream, state) {
if (type == "string") return attrContinuedState;
if (type == 'string') return attrContinuedState;
return attrState(type, stream, state);
}
return {
startState: function (baseIndent) {
startState: function(baseIndent) {
var state = {
tokenize: inText,
state: baseState,
indented: baseIndent || 0,
tagName: null, tagStart: null,
tagName: null,
tagStart: null,
context: null
}
if (baseIndent != null) state.baseIndent = baseIndent
return state
};
if (baseIndent != null) state.baseIndent = baseIndent;
return state;
},
token: function (stream, state) {
token: function(stream, state) {
if (!state.tagName && stream.sol())
state.indented = stream.indentation();
if (stream.eatSpace()) return null;
type = null;
var style = state.tokenize(stream, state);
if ((style || type) && style != "comment") {
if ((style || type) && style != 'comment') {
setStyle = null;
state.state = state.state(type || style, stream, state);
if (setStyle)
style = setStyle == "error" ? style + " error" : setStyle;
style = setStyle == 'error' ? style + ' error' : setStyle;
}
return style;
},
indent: function (state, textAfter, fullLine) {
indent: function(state, textAfter, fullLine) {
var context = state.context;
// Indent multi-line strings (e.g. css).
if (state.tokenize.isInAttribute) {
if (state.tagStart == state.indented)
return state.stringStartCol + 1;
else
return state.indented + indentUnit;
if (state.tagStart == state.indented) return state.stringStartCol + 1;
else return state.indented + indentUnit;
}
if (context && context.noIndent) return CodeMirror.Pass;
if (state.tokenize != inTag && state.tokenize != inText)
@ -360,28 +425,34 @@
if (config.multilineTagIndentPastTag !== false)
return state.tagStart + state.tagName.length + 2;
else
return state.tagStart + indentUnit * (config.multilineTagIndentFactor || 1);
return (
state.tagStart +
indentUnit * (config.multilineTagIndentFactor || 1)
);
}
if (config.alignCDATA && /<!\[CDATA\[/.test(textAfter)) return 0;
var tagAfter = textAfter && /^<(\/)?([\w_:\.-]*)/.exec(textAfter);
if (tagAfter && tagAfter[1]) { // Closing tag spotted
if (tagAfter && tagAfter[1]) {
// Closing tag spotted
while (context) {
if (context.tagName == tagAfter[2]) {
context = context.prev;
break;
} else if (config.implicitlyClosed.hasOwnProperty(context.tagName)) {
} else if (
config.implicitlyClosed.hasOwnProperty(context.tagName)
) {
context = context.prev;
} else {
break;
}
}
} else if (tagAfter) { // Opening tag spotted
} else if (tagAfter) {
// Opening tag spotted
while (context) {
var grabbers = config.contextGrabbers[context.tagName];
if (grabbers && grabbers.hasOwnProperty(tagAfter[2]))
context = context.prev;
else
break;
else break;
}
}
while (context && context.prev && !context.startOfLine)
@ -391,22 +462,20 @@
},
electricInput: /<\/[\s\w:]+>$/,
blockCommentStart: "<!--",
blockCommentEnd: "-->",
blockCommentStart: '<!--',
blockCommentEnd: '-->',
configuration: config.htmlMode ? "html" : "xml",
helperType: config.htmlMode ? "html" : "xml",
configuration: config.htmlMode ? 'html' : 'xml',
helperType: config.htmlMode ? 'html' : 'xml',
skipAttribute: function (state) {
if (state.state == attrValueState)
state.state = attrState
skipAttribute: function(state) {
if (state.state == attrValueState) state.state = attrState;
}
};
});
CodeMirror.defineMIME("text/xml", "xml");
CodeMirror.defineMIME("application/xml", "xml");
if (!CodeMirror.mimeModes.hasOwnProperty("text/html"))
CodeMirror.defineMIME("text/html", { name: "xml", htmlMode: true });
});
CodeMirror.defineMIME('text/xml', 'xml');
CodeMirror.defineMIME('application/xml', 'xml');
if (!CodeMirror.mimeModes.hasOwnProperty('text/html'))
CodeMirror.defineMIME('text/html', { name: 'xml', htmlMode: true });
});