Merge branch '3.9-6.6'

This commit is contained in:
Jesús Ángel 2019-03-18 16:23:16 +01:00
commit fd50d9b55d
15 changed files with 140 additions and 111 deletions

View File

@ -2,9 +2,9 @@
"name": "wazuh",
"version": "3.9.0",
"revision": "0420",
"code": "0420-0",
"code": "0420-1",
"kibana": {
"version": "6.6.1"
"version": "6.6.2"
},
"description": "Wazuh app",
"main": "index.js",
@ -63,4 +63,4 @@
"typescript": "^3.0.1",
"typescript-eslint-parser": "^18.0.0"
}
}
}

View File

@ -239,13 +239,13 @@ export class AgentsController {
if (failed) {
throw new Error(result.failed_ids[0].error.message);
} else if (result) {
this.errorHandler.info(result.msg, '');
this.errorHandler.info(result.msg);
} else {
throw new Error('Unexpected error upgrading agent');
}
this.$scope.restartingAgent = false;
} catch (error) {
this.errorHandler.handle(error, '');
this.errorHandler.handle(error);
this.$scope.restartingAgent = false;
}
this.$scope.$applyAsync();
@ -413,7 +413,7 @@ export class AgentsController {
);
this.$scope.addingGroupToAgent = false;
this.$scope.editGroup = false;
this.errorHandler.info(`Group ${group} has been added.`, '');
this.errorHandler.info(`Group ${group} has been added.`);
if (!this.$scope.$$phase) this.$scope.$digest();
})
.catch(error => {
@ -542,7 +542,7 @@ export class AgentsController {
(((agentInfo || {}).data || {}).data || {}).status ||
this.$scope.agent.status;
}
} catch (error) { } // eslint-disable-line
} catch (error) {} // eslint-disable-line
try {
this.$scope.showSyscheckFiles = false;
@ -576,7 +576,7 @@ export class AgentsController {
if (tab === 'syscollector')
try {
await this.loadSyscollector(this.$scope.agent.id);
} catch (error) { } // eslint-disable-line
} catch (error) {} // eslint-disable-line
if (tab === 'configuration') {
this.$scope.switchConfigurationTab('welcome');
} else {
@ -698,7 +698,7 @@ export class AgentsController {
{}
);
netifaceResponse = ((resultNetiface || {}).data || {}).data || false;
} catch (error) { } // eslint-disable-line
} catch (error) {} // eslint-disable-line
// This API call may fail so we put it out of Promise.all
let netaddrResponse = false;
@ -710,7 +710,7 @@ export class AgentsController {
);
netaddrResponse =
((resultNetaddrResponse || {}).data || {}).data || false;
} catch (error) { } // eslint-disable-line
} catch (error) {} // eslint-disable-line
// Before proceeding, syscollector data is an empty object
this.$scope.syscollector = {};
@ -726,7 +726,7 @@ export class AgentsController {
this.$scope.syscollector = {
hardware:
typeof hardwareResponse === 'object' &&
Object.keys(hardwareResponse).length
Object.keys(hardwareResponse).length
? { ...hardwareResponse }
: false,
os:
@ -769,7 +769,7 @@ export class AgentsController {
try {
data[0] = await this.apiReq.request('GET', `/agents/${id}`, {});
} catch (error) { } //eslint-disable-line
} catch (error) {} //eslint-disable-line
try {
data[1] = await this.apiReq.request(
@ -777,7 +777,7 @@ export class AgentsController {
`/syscheck/${id}/last_scan`,
{}
);
} catch (error) { } //eslint-disable-line
} catch (error) {} //eslint-disable-line
try {
data[2] = await this.apiReq.request(
@ -785,7 +785,7 @@ export class AgentsController {
`/rootcheck/${id}/last_scan`,
{}
);
} catch (error) { } //eslint-disable-line
} catch (error) {} //eslint-disable-line
const result = data.map(item => ((item || {}).data || {}).data || false);
@ -975,12 +975,12 @@ export class AgentsController {
);
this.errorHandler.info(
`Policy monitoring scan launched successfully on agent ${
this.$scope.agent.id
this.$scope.agent.id
}`,
''
);
} catch (error) {
this.errorHandler.handle(error, '');
this.errorHandler.handle(error);
}
return;
}
@ -997,7 +997,7 @@ export class AgentsController {
''
);
} catch (error) {
this.errorHandler.handle(error, '');
this.errorHandler.handle(error);
}
return;
}

View File

@ -67,7 +67,7 @@ export class CdbListsController {
this.$scope.$emit('setCurrentList', { currentList: this.currentList });
} catch (error) {
this.currentList.list = [];
this.errorHandler.handle(error, '');
this.errorHandler.handle(error);
}
this.$scope.$broadcast('changeCdbList', {
currentList: this.currentList

View File

@ -100,9 +100,9 @@ export class ConfigurationGroupsController {
try {
this.$scope.addingGroup = false;
await this.groupHandler.createGroup(name);
this.errorHandler.info(`Success. Group ${name} has been created`, '');
this.errorHandler.info(`Group ${name} has been created`);
} catch (error) {
this.errorHandler.handle(`${error.message || error}`, '');
this.errorHandler.handle(error.message || error);
}
this.$scope.$broadcast('wazuhSearch', {});
};

View File

@ -218,7 +218,7 @@ export class ConfigurationRulesetController {
this.$scope.viewingDetail = true;
} catch (error) {
this.$scope.currentList.list = [];
this.errorHandler.handle(error, '');
this.errorHandler.handle(error);
}
this.$scope.$broadcast('changeCdbList', {
currentList: this.$scope.currentList

View File

@ -477,6 +477,30 @@ export function GroupsController(
return { addedIds, deletedIds };
};
/**
* Re-group the given array depending on the property provided as parameter.
* @param {*} collection Array<object>
* @param {*} property String
*/
const groupBy = (collection, property) => {
try {
const values = [];
const result = [];
for (const item of collection) {
const index = values.indexOf(item[property]);
if (index > -1) result[index].push(item);
else {
values.push(item[property]);
result.push([item]);
}
}
return result.length ? result : false;
} catch (error) {
return false;
}
};
$scope.saveAddAgents = async () => {
const itemsToSave = getItemsToSave();
const failedIds = [];
@ -505,13 +529,20 @@ export function GroupsController(
}
if (failedIds.length) {
const failedErrors = failedIds.map(item => ({
id: (item || {}).id,
message: ((item || {}).error || {}).message
}));
$scope.failedErrors = groupBy(failedErrors, 'message') || false;
errorHandler.info(
`Warning. Group has been updated but an error has occurred with the following agents ${failedIds}`,
`Group has been updated but an error has occurred with ${
failedIds.length
} agents`,
'',
true
);
} else {
errorHandler.info('Success. Group has been updated', '');
errorHandler.info('Group has been updated');
}
$scope.addMultipleAgents(false);
$scope.multipleSelectorLoading = false;
@ -567,9 +598,9 @@ export function GroupsController(
try {
$scope.addingGroup = false;
await groupHandler.createGroup(name);
errorHandler.info(`Success. Group ${name} has been created`, '');
errorHandler.info(`Group ${name} has been created`);
} catch (error) {
errorHandler.handle(`${error.message || error}`, '');
errorHandler.handle(error.message || error);
}
$scope.$broadcast('wazuhSearch', {});
};

View File

@ -61,11 +61,11 @@ export class LogsController {
parseLogsToText(logs) {
let result = '';
logs.forEach(function (log, idx) {
logs.forEach(function(log, idx) {
if (log) {
result = result.concat(
`${log.timestamp} ${log.tag} ${(log.level || '').toUpperCase()}: ${
log.description
log.description
}`
);
if (idx !== logs.length - 1) {
@ -195,10 +195,10 @@ export class LogsController {
const data = clusterEnabled
? await this.apiReq.request(
'GET',
`/cluster/${this.selectedNode}/logs/summary`,
{}
)
'GET',
`/cluster/${this.selectedNode}/logs/summary`,
{}
)
: await this.apiReq.request('GET', '/manager/logs/summary', {});
const daemons = data.data.data;
this.daemons = Object.keys(daemons).map(item => ({ title: item }));
@ -209,4 +209,4 @@ export class LogsController {
}
return;
}
}
}

View File

@ -139,4 +139,4 @@ class WzConfigViewer {
}
}
app.directive('wzConfigViewer', () => new WzConfigViewer());
app.directive('wzConfigViewer', () => new WzConfigViewer());

View File

@ -152,7 +152,7 @@ app.directive('wzListManage', function() {
$scope.currentList.list[key] = value ? value : '';
fetch();
} else {
errorHandler.handle('Entry already exists', '');
errorHandler.handle('Entry already exists');
}
};

View File

@ -20,14 +20,18 @@ export async function nextPage(currentPage, $scope, errorHandler, fetch) {
) {
$scope.currentPage++;
}
if ($scope.pagedItems[currentPage || $scope.currentPage].includes(null)) {
if (
($scope.pagedItems[currentPage || $scope.currentPage] || []).includes(
null
)
) {
const copy = $scope.currentPage;
$scope.wazuh_table_loading = true;
const currentNonNull = $scope.items.filter(item => !!item);
await fetch({ offset: currentNonNull.length });
$scope.wazuh_table_loading = false;
$scope.currentPage = copy;
if (!$scope.$$phase) $scope.$digest();
$scope.$applyAsync();
}
} catch (error) {
$scope.wazuh_table_loading = false;

View File

@ -26,7 +26,7 @@ import { checkGap } from './lib/check-gap';
const app = uiModules.get('app/wazuh', []);
app.directive('wzTable', function () {
app.directive('wzTable', function() {
return {
restrict: 'E',
scope: {
@ -111,6 +111,7 @@ app.directive('wzTable', function () {
let resizing = false;
$window.onresize = () => {
if (resizing) return;
$('#wz_table').colResizable({ disable: true });
resizing = true;
clearTimeout(doit);
doit = setTimeout(() => {
@ -289,7 +290,7 @@ app.directive('wzTable', function () {
$scope.prevPage = () => pagination.prevPage($scope);
$scope.nextPage = async currentPage =>
pagination.nextPage(currentPage, $scope, errorHandler, fetch);
$scope.setPage = function (page = false) {
$scope.setPage = function(page = false) {
$scope.currentPage = page || this.n;
$scope.nextPage(this.n).then(() => {
if (page) {
@ -395,13 +396,10 @@ app.directive('wzTable', function () {
$scope.confirmRemoveAgent = async agent => {
try {
const group = instance.path.split('/').pop();
await groupHandler.removeAgentFromGroup(group, agent);
errorHandler.info(
`Success. Agent ${agent} has been removed from ${group}`,
''
);
const data = await groupHandler.removeAgentFromGroup(group, agent);
errorHandler.info(((data || {}).data || {}).data);
} catch (error) {
errorHandler.handle(`${error.message || error}`, '');
errorHandler.handle(error.message || error);
}
$scope.removingAgent = null;
return init();
@ -410,9 +408,9 @@ app.directive('wzTable', function () {
$scope.confirmRemoveGroup = async group => {
try {
await groupHandler.removeGroup(group);
errorHandler.info(`Success. Group ${group} has been removed`, '');
errorHandler.info(`Group ${group} has been removed`);
} catch (error) {
errorHandler.handle(`${error.message || error}`, '');
errorHandler.handle(error.message || error);
}
$scope.removingGroup = null;
return init();
@ -421,9 +419,9 @@ app.directive('wzTable', function () {
$scope.confirmRemoveFile = async (file, type) => {
try {
await rulesetHandler.deleteFile(file, type);
errorHandler.info(`Success. File ${file.file} has been deleted`, '');
errorHandler.info(`File ${file.file} has been deleted`);
} catch (error) {
errorHandler.handle(`${error.message || error}`, '');
errorHandler.handle(error.message || error);
}
$scope.removingFile = null;
return init();

View File

@ -172,7 +172,7 @@ app.directive('wzXmlFileEditor', function() {
return formatted.trim();
};
const validateAfterSent = async (node = false) => {
const validateAfterSent = async (node = false, isConfig = false) => {
$scope.configError = false;
try {
const clusterStatus = await apiReq.request(
@ -210,15 +210,14 @@ app.directive('wzXmlFileEditor', function() {
if (
!isOk &&
Array.isArray(data.details) &&
data.details.join().includes('Configuration error')
(!isConfig || (isConfig && data.details.join().includes(isConfig)))
) {
$scope.configError = data.details;
$scope.$applyAsync();
return Promise.reject();
throw new Error('Validation error');
}
return true;
} catch (error) {
$scope.configError = false;
return Promise.reject(error);
}
};
@ -234,7 +233,7 @@ app.directive('wzXmlFileEditor', function() {
close = false;
await groupHandler.sendConfiguration(params.group, xml);
try {
await validateAfterSent();
await validateAfterSent(false, 'groups');
} catch (err) {
params.showRestartManager = 'warn';
}
@ -252,7 +251,10 @@ app.directive('wzXmlFileEditor', function() {
params.isNewFile && !params.isOverwrite
);
try {
await validateAfterSent();
await validateAfterSent(
false,
`${params.rule.path}/${params.rule.file}`
);
} catch (err) {
params.showRestartManager = 'warn';
}
@ -270,7 +272,10 @@ app.directive('wzXmlFileEditor', function() {
params.isNewFile && !params.isOverwrite
);
try {
await validateAfterSent();
await validateAfterSent(
false,
`${params.decoder.path}/${params.decoder.file}`
);
} catch (err) {
params.showRestartManager = 'warn';
}
@ -284,7 +289,7 @@ app.directive('wzXmlFileEditor', function() {
close = false;
await configHandler.saveNodeConfiguration(params.node, xml);
try {
await validateAfterSent(params.node);
await validateAfterSent(params.node, 'etc/ossec.conf');
} catch (err) {
params.showRestartManager = 'warn';
}
@ -299,7 +304,7 @@ app.directive('wzXmlFileEditor', function() {
} else if (params.manager) {
await configHandler.saveManagerConfiguration(xml);
try {
await validateAfterSent();
await validateAfterSent(false, 'etc/ossec.conf');
} catch (err) {
params.showRestartManager = 'warn';
}

View File

@ -56,7 +56,7 @@ export class ReportingService {
const array = await this.vis2png.checkArray(idArray);
const name = `wazuh-${
isAgents ? 'agents' : 'overview'
}-${tab}-${(Date.now() / 1000) | 0}.pdf`;
}-${tab}-${(Date.now() / 1000) | 0}.pdf`;
const browserTimezone = moment.tz.guess(true);

View File

@ -12,15 +12,13 @@
<div layout="row">
<span class="font-size-18">
<i class="fa fa-fw fa-object-group" aria-hidden="true"></i> Groups </span>
<span ng-if='adminMode' class="font-size-18 wz-text-link" ng-click="switchAddingGroup()"> <i
class="fa fa-fw" ng-class="!addingGroup ? 'fa-plus-circle' : 'fa-minus-circle'"></i></span>
<span ng-if='adminMode' class="font-size-18 wz-text-link" ng-click="switchAddingGroup()"> <i class="fa fa-fw"
ng-class="!addingGroup ? 'fa-plus-circle' : 'fa-minus-circle'"></i></span>
</div>
<div layout="row" ng-if="addingGroup" ng-if='adminMode' class="wz-padding-bottom-0">
<input placeholder="Group name..." ng-model="groupToBeAdded" type="text"
class="kuiLocalSearchInput addGroupInput ng-empty ng-pristine ng-scope ng-touched ng-valid"
<input placeholder="Group name..." ng-model="groupToBeAdded" type="text" class="kuiLocalSearchInput addGroupInput ng-empty ng-pristine ng-scope ng-touched ng-valid"
aria-invalid="false">
<button type="submit" aria-label="Search" class="kuiLocalSearchButton addGroupBtn"
ng-click="createGroup(groupToBeAdded)">
<button type="submit" aria-label="Search" class="kuiLocalSearchButton addGroupBtn" ng-click="createGroup(groupToBeAdded)">
<span class="fa fa-save fa-fw" aria-hidden="true"></span>
</button>
</div>
@ -36,8 +34,7 @@
<!-- Group MD5 sums section -->
<md-card flex class="no-margin-left no-margin-right wz-margin-top-8 wz-md-card">
<md-card-content>
<span class="wz-headline-title font-size-18"><i class="fa fa-fw fa-object-group"
aria-hidden="true"></i>
<span class="wz-headline-title font-size-18"><i class="fa fa-fw fa-object-group" aria-hidden="true"></i>
{{currentGroup.name}}</span>
<md-divider class="wz-margin-top-10"></md-divider>
<div layout="row" class="wz-padding-top-10">
@ -71,19 +68,16 @@
<div ng-show="editingFile">
<div layout="row" class="md-padding-h wz-margin-top-10">
<span ng-click='closeEditingFile()' class='btn btn-info'>Cancel</span>
<button ng-disabled='xmlHasErrors' ng-click='doSaveGroupAgentConfig()'
class='btn wz-button pull-right wz-margin-left-8'>
<button ng-disabled='xmlHasErrors' ng-click='doSaveGroupAgentConfig()' class='btn wz-button pull-right wz-margin-left-8'>
<span ng-show='!xmlHasErrors'><i aria-hidden='true' class='fa fa-fw fa-save'></i>Save
file</span>
<span ng-show='xmlHasErrors' class='btn-danger'><i aria-hidden='true'
class='fa fa-fw fa-exclamation-triangle'></i>
<span ng-show='xmlHasErrors' class='btn-danger'><i aria-hidden='true' class='fa fa-fw fa-exclamation-triangle'></i>
XML format error</span>
</button>
</div>
<div class="md-padding md-padding-top-10" style="height: calc(100vh - 350px);" ng-if="fetchedXML">
<wz-xml-file-editor file-name='agent.conf' data="fetchedXML"
target-name="currentGroup.name + ' group'" valid-fn='xmlIsValid(valid)'
close-fn='closeEditingFile(reload)'>
<wz-xml-file-editor file-name='agent.conf' data="fetchedXML" target-name="currentGroup.name + ' group'"
valid-fn='xmlIsValid(valid)' close-fn='closeEditingFile(reload)'>
</wz-xml-file-editor>
</div>
</div>
@ -100,11 +94,9 @@
possible to apply changes of more than 500 additions or deletions</span>
</div>
<div layout="row" class="md-padding wz-padding-bottom-0"
ng-if="lookingGroup && currentGroup && !addingAgents && !editingFile && !file && adminMode">
<button ng-if="lookingGroup && groupsSelectedTab==='files'"
ng-click='editGroupAgentConfig(currentGroup)' class='btn wz-button'><i aria-hidden='true'
class='fa fa-fw fa-pencil'></i>
<div layout="row" class="md-padding wz-padding-bottom-0" ng-if="lookingGroup && currentGroup && !addingAgents && !editingFile && !file && adminMode">
<button ng-if="lookingGroup && groupsSelectedTab==='files'" ng-click='editGroupAgentConfig(currentGroup)'
class='btn wz-button'><i aria-hidden='true' class='fa fa-fw fa-pencil'></i>
Edit group configuration
</button>
<button ng-if="lookingGroup && groupsSelectedTab==='agents'" ng-click='addMultipleAgents(true)'
@ -115,13 +107,10 @@
<!-- Search bar -->
<div layout="row" class="md-padding" ng-if="!addingAgents && !file">
<input
placeholder="{{groupsSelectedTab==='files' ? 'Filter files...' : lookingGroup ? 'Filter agents...' : 'Filter groups...'}}"
ng-model="custom_search" type="text"
class="kuiLocalSearchInput ng-empty ng-pristine ng-scope ng-touched ng-valid"
<input placeholder="{{groupsSelectedTab==='files' ? 'Filter files...' : lookingGroup ? 'Filter agents...' : 'Filter groups...'}}"
ng-model="custom_search" type="text" class="kuiLocalSearchInput ng-empty ng-pristine ng-scope ng-touched ng-valid"
aria-invalid="false" wz-enter="search(custom_search)">
<button type="submit" aria-label="Search" class="kuiLocalSearchButton height-40"
ng-click="search(custom_search)">
<button type="submit" aria-label="Search" class="kuiLocalSearchButton height-40" ng-click="search(custom_search)">
<span class="fa fa-search" aria-hidden="true"></span>
</button>
</div>
@ -131,16 +120,14 @@
<md-card flex class="wz-md-card _md flex md-margin-h" ng-if="!lookingGroup">
<md-card-content>
<div layout="row">
<wz-table custom-columns="true" flex extra-limit="100" path="'/agents/groups'"
keys="['name','count','mergedSum']" allow-click="true" row-sizes="[14,12,10]">
<wz-table custom-columns="true" flex extra-limit="100" path="'/agents/groups'" keys="['name','count','mergedSum']"
allow-click="true" row-sizes="[14,12,10]">
</wz-table>
</div>
</md-card-content>
<!-- CSV Download button section for groups -->
<md-card-actions layout="row" layout-align="end center"
class="wz-card-actions layout-align-end-center layout-row">
<a class="wz-text-link cursor-pointer small md-button md-ink-ripple" id="btnDownload"
ng-click="downloadCsv('/agents/groups')">Formatted
<md-card-actions layout="row" layout-align="end center" class="wz-card-actions layout-align-end-center layout-row">
<a class="wz-text-link cursor-pointer small md-button md-ink-ripple" id="btnDownload" ng-click="downloadCsv('/agents/groups')">Formatted
<i aria-hidden="true" class="fa fa-download"></i></a>
</md-card-actions>
<!-- End CSV Download button section for groups -->
@ -149,14 +136,23 @@
<div ng-if='!addingAgents'>
<!-- Group agents table -->
<md-card flex class="wz-md-card _md flex md-margin-h"
ng-if="lookingGroup && groupsSelectedTab==='agents' && currentGroup">
<md-card flex class="wz-md-card _md flex md-margin-h" ng-if="lookingGroup && groupsSelectedTab==='agents' && currentGroup">
<div layout="row" ng-show="failedErrors" class="extraHeader">
<md-list>
<md-list-item class="error-enum-configuration" ng-repeat="group in failedErrors">
<span class="wz-agent-status-indicator small red-text padding-left-0"><span
ng-repeat="error in group">{{error.id}}{{$last
? '' : ',&nbsp;'}}</span>: {{group[0].message}}</span>
</md-list-item>
</md-list>
<span flex></span>
<a class='md-padding md-padding-top-10' ng-click='failedErrors = false'><i class="fa fa-times"
aria-hidden="true"></i></a>
</div>
<md-card-content>
<div layout="row">
<wz-table flex path="'/agents/groups/' + currentGroup.name"
keys="['id','name','ip','status','os.name','os.version','version']"
allow-click="true" row-sizes="[14,12,10]"
empty-results="'No agents were added to this group.'" />
<wz-table flex path="'/agents/groups/' + currentGroup.name" keys="['id','name','ip','status','os.name','os.version','version']"
allow-click="true" row-sizes="[14,12,10]" empty-results="'No agents were added to this group.'" />
</div>
</md-card-content>
</md-card>
@ -165,16 +161,14 @@
<!-- CSV Download button section for group agents -->
<div layout="row" class="md-padding" ng-if="lookingGroup && groupsSelectedTab==='agents'">
<span flex></span>
<a class="small" id="btnDownload"
ng-click="downloadCsv('/agents/groups/' + currentGroup.name)">Formatted
<a class="small" id="btnDownload" ng-click="downloadCsv('/agents/groups/' + currentGroup.name)">Formatted
<i aria-hidden="true" class="fa fa-fw fa-download"></i>
</a>
</div>
<!-- End CSV Download button section for group agents -->
<!-- Group files table -->
<md-card flex class="wz-md-card _md flex md-margin-h"
ng-if="lookingGroup && groupsSelectedTab==='files' && !fileViewer && currentGroup">
<md-card flex class="wz-md-card _md flex md-margin-h" ng-if="lookingGroup && groupsSelectedTab==='files' && !fileViewer && currentGroup">
<md-card-content>
<div layout="row">
<wz-table extra-limit="100" flex path="'/agents/groups/' + currentGroup.name + '/files'"
@ -189,27 +183,24 @@
<!-- CSV Download button section for group files-->
<div layout="row" class="md-padding" ng-if="lookingGroup && groupsSelectedTab==='files' && !file">
<span flex></span>
<a class="small" id="btnDownload"
ng-click="downloadCsv('/agents/groups/' + currentGroup.name + '/files')">Formatted
<a class="small" id="btnDownload" ng-click="downloadCsv('/agents/groups/' + currentGroup.name + '/files')">Formatted
<i aria-hidden="true" class="fa fa-fw fa-download"></i>
</a>
</div>
<!-- End CSV Download button section for group files -->
<!-- File JSON viewer section -->
<div flex layout="column" class="md-padding"
ng-if="lookingGroup && groupsSelectedTab==='files' && file">
<div flex layout="column" class="md-padding" ng-if="lookingGroup && groupsSelectedTab==='files' && file">
<div flex layout="column">
<div layout="row" class="wz-padding-bottom-14">
<span flex class="wz-headline-title">{{ filename }}</span>
<button class="md-icon-button" ng-if="lookingGroup" aria-label="Back"
tooltip="Close file" tooltip-placement="left" ng-click="goBackFiles()"><i
class="fa fa-fw fa-close" aria-hidden="true"></i></button>
<button class="md-icon-button" ng-if="lookingGroup" aria-label="Back" tooltip="Close file"
tooltip-placement="left" ng-click="goBackFiles()"><i class="fa fa-fw fa-close"
aria-hidden="true"></i></button>
<!--<span flex class="wz-text-right cursor-pointer color-grey" ng-click="goBackFiles()">close</span>-->
</div>
<div flex layout="column">
<pre flex
class="wz-pre groupContentViewer wzXmlEditor wz-overflow-y-auto"><code wz-dynamic="file"></code></pre>
<pre flex class="wz-pre groupContentViewer wzXmlEditor wz-overflow-y-auto"><code wz-dynamic="file"></code></pre>
</div>
</div>
</div>
@ -217,8 +208,7 @@
</div>
<div layout="row" class="md-padding" ng-if="addingAgents">
<span ng-show='!multipleSelectorLoading' class="wzMultipleSelectorCounter"><span
style='color:green'>+{{currentAdding}}</span>&nbsp;<span
<span ng-show='!multipleSelectorLoading' class="wzMultipleSelectorCounter"><span style='color:green'>+{{currentAdding}}</span>&nbsp;<span
style='color:red'>-{{currentDeleting}}</span></span>
<wz-multiple-selector class='wzMultipleSelector' available-items="availableAgents.data"
selected-items="selectedAgents.data" title-available-items="Available agents"

View File

@ -71,6 +71,7 @@
t.opt.hoverCursor +
'!important}</style>'
); //if hoverCursor has been set, append the style
$('.JCLRgrips').remove();
t.addClass(SIGNATURE)
.attr(ID, id)
.before('<div class="JCLRgrips"/>'); //the grips container object is added. Signature class forces table rendering in fixed-layout mode to prevent column's min-width