mirror of
https://github.com/valitydev/wazuh-kibana-app.git
synced 2024-11-06 01:45:18 +00:00
Fixes after overall review (#1362)
This commit is contained in:
parent
ec28b8b280
commit
7bb0b46cf8
@ -1,4 +1,4 @@
|
||||
node_modules/
|
||||
public/utils/codemirror/
|
||||
public/kibana-integrations/
|
||||
public/utils/table-col-resizable.js
|
||||
public/utils/jquery-ui.js
|
130
package.json
130
package.json
@ -1,67 +1,67 @@
|
||||
{
|
||||
"name": "wazuh",
|
||||
"version": "3.9.0",
|
||||
"revision": "0429",
|
||||
"code": "0429-0",
|
||||
"kibana": {
|
||||
"version": "6.7.1"
|
||||
},
|
||||
"description": "Wazuh app",
|
||||
"main": "index.js",
|
||||
"keywords": [
|
||||
"kibana",
|
||||
"wazuh",
|
||||
"ossec"
|
||||
],
|
||||
"node_build": "8.14.0",
|
||||
"author": "Wazuh, Inc",
|
||||
"license": "GPL-2.0",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/wazuh/wazuh-kibana-app.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/wazuh/wazuh-kibana-app/issues"
|
||||
},
|
||||
"homepage": "https://www.wazuh.com/",
|
||||
"scripts": {
|
||||
"pretty": "prettier --single-quote \"{,!(node_modules)/**/}*.js\" --write",
|
||||
"tslint": "tslint -c .tslint.yml server/**/*.ts server/**/*.tsx public/**/*.ts public/**/*.tsx",
|
||||
"lint": "eslint . --ext .js -c .eslintrc.json --color",
|
||||
"prebuild": "tsc; find . -name \"*.ts*\" -type f -not -path \"./node_modules/*\" -delete",
|
||||
"build": "plugin-helpers build",
|
||||
"test": "_mocha test/**/*"
|
||||
},
|
||||
"dependencies": {
|
||||
"angular-animate": "1.6.5",
|
||||
"angular-chart.js": "^1.1.1",
|
||||
"angular-cookies": "1.6.5",
|
||||
"angular-material": "1.1.10",
|
||||
"dom-to-image": "^2.6.0",
|
||||
"install": "^0.10.1",
|
||||
"js2xmlparser": "^3.0.0",
|
||||
"json2csv": "^4.1.2",
|
||||
"needle": "^2.0.1",
|
||||
"node-cron": "^1.1.2",
|
||||
"pdfmake": "^0.1.37",
|
||||
"pug-loader": "^2.4.0",
|
||||
"querystring-browser": "1.0.4",
|
||||
"simple-tail": "^1.1.0",
|
||||
"timsort": "^0.3.0",
|
||||
"winston": "3.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@elastic/plugin-helpers": "^7.1.8",
|
||||
"babel-eslint": "^8.2.6",
|
||||
"chai": "^4.1.2",
|
||||
"eslint": "^5.10.0",
|
||||
"eslint-plugin-async-await": "^0.0.0",
|
||||
"eslint-plugin-import": "^2.14.0",
|
||||
"eslint-plugin-node": "^7.0.1",
|
||||
"mocha": "^5.2.0",
|
||||
"prettier": "^1.14.2",
|
||||
"tslint": "^5.11.0",
|
||||
"typescript": "^3.0.1",
|
||||
"typescript-eslint-parser": "^18.0.0"
|
||||
}
|
||||
"name": "wazuh",
|
||||
"version": "3.9.0",
|
||||
"revision": "0429",
|
||||
"code": "0429-0",
|
||||
"kibana": {
|
||||
"version": "6.7.1"
|
||||
},
|
||||
"description": "Wazuh app",
|
||||
"main": "index.js",
|
||||
"keywords": [
|
||||
"kibana",
|
||||
"wazuh",
|
||||
"ossec"
|
||||
],
|
||||
"node_build": "8.14.0",
|
||||
"author": "Wazuh, Inc",
|
||||
"license": "GPL-2.0",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/wazuh/wazuh-kibana-app.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/wazuh/wazuh-kibana-app/issues"
|
||||
},
|
||||
"homepage": "https://www.wazuh.com/",
|
||||
"scripts": {
|
||||
"pretty": "prettier --single-quote \"{,!(node_modules)/**/}*.js\" --write",
|
||||
"tslint": "tslint -c .tslint.yml server/**/*.ts server/**/*.tsx public/**/*.ts public/**/*.tsx",
|
||||
"lint": "eslint . --ext .js -c .eslintrc.json --color",
|
||||
"prebuild": "tsc; find . -name \"*.ts*\" -type f -not -path \"./node_modules/*\" -delete",
|
||||
"build": "plugin-helpers build",
|
||||
"test": "_mocha test/**/*"
|
||||
},
|
||||
"dependencies": {
|
||||
"angular-animate": "1.6.5",
|
||||
"angular-chart.js": "^1.1.1",
|
||||
"angular-cookies": "1.6.5",
|
||||
"angular-material": "1.1.10",
|
||||
"dom-to-image": "^2.6.0",
|
||||
"install": "^0.10.1",
|
||||
"js2xmlparser": "^3.0.0",
|
||||
"json2csv": "^4.1.2",
|
||||
"needle": "^2.0.1",
|
||||
"node-cron": "^1.1.2",
|
||||
"pdfmake": "^0.1.37",
|
||||
"pug-loader": "^2.4.0",
|
||||
"querystring-browser": "1.0.4",
|
||||
"simple-tail": "^1.1.0",
|
||||
"timsort": "^0.3.0",
|
||||
"winston": "3.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@elastic/plugin-helpers": "^7.1.8",
|
||||
"babel-eslint": "^8.2.6",
|
||||
"chai": "^4.1.2",
|
||||
"eslint": "^5.10.0",
|
||||
"eslint-plugin-async-await": "^0.0.0",
|
||||
"eslint-plugin-import": "^2.14.0",
|
||||
"eslint-plugin-node": "^7.0.1",
|
||||
"mocha": "^5.2.0",
|
||||
"prettier": "^1.14.2",
|
||||
"tslint": "^5.11.0",
|
||||
"typescript": "^3.0.1",
|
||||
"typescript-eslint-parser": "^18.0.0"
|
||||
}
|
||||
}
|
||||
|
@ -193,7 +193,7 @@ import './utils/fontawesome/css/font-awesome.min.css';
|
||||
// Dev tools
|
||||
import './utils/codemirror';
|
||||
|
||||
import './utils/table-col-resizable';
|
||||
import './utils/jquery-ui';
|
||||
|
||||
// Material
|
||||
import 'angular-material/angular-material.css';
|
||||
|
@ -158,6 +158,13 @@ export class DecodersController {
|
||||
return this.$sce.trustAsHtml(coloredString);
|
||||
}
|
||||
|
||||
switchLocalDecoders() {
|
||||
this.removeFilter('path');
|
||||
if (!this.showingLocalDecoders) {
|
||||
this.appliedFilters.push({ name: 'path', value: 'etc/decoders' });
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This perfoms a search by a given term
|
||||
* @param {String} term
|
||||
@ -165,12 +172,14 @@ export class DecodersController {
|
||||
search(term) {
|
||||
if (term && term.startsWith('path:') && term.split('path:')[1].trim()) {
|
||||
this.custom_search = '';
|
||||
const filter = { name: 'path', value: term.split('path:')[1].trim() };
|
||||
this.appliedFilters = this.appliedFilters.filter(
|
||||
item => item.name !== 'path'
|
||||
);
|
||||
this.appliedFilters.push(filter);
|
||||
this.$scope.$broadcast('wazuhFilter', { filter });
|
||||
if (!this.showingLocalDecoders) {
|
||||
const filter = { name: 'path', value: term.split('path:')[1].trim() };
|
||||
this.appliedFilters = this.appliedFilters.filter(
|
||||
item => item.name !== 'path'
|
||||
);
|
||||
this.appliedFilters.push(filter);
|
||||
this.$scope.$broadcast('wazuhFilter', { filter });
|
||||
}
|
||||
} else if (
|
||||
term &&
|
||||
term.startsWith('file:') &&
|
||||
|
@ -35,6 +35,7 @@ export function RulesController(
|
||||
* This performs a search with a given term
|
||||
*/
|
||||
$scope.search = term => {
|
||||
let clearInput = true;
|
||||
if (term && term.startsWith('group:') && term.split('group:')[1].trim()) {
|
||||
$scope.custom_search = '';
|
||||
const filter = { name: 'group', value: term.split('group:')[1].trim() };
|
||||
@ -97,15 +98,23 @@ export function RulesController(
|
||||
term.split('path:')[1].trim()
|
||||
) {
|
||||
$scope.custom_search = '';
|
||||
const filter = { name: 'path', value: term.split('path:')[1].trim() };
|
||||
$scope.appliedFilters = $scope.appliedFilters.filter(
|
||||
item => item.name !== 'path'
|
||||
);
|
||||
$scope.appliedFilters.push(filter);
|
||||
$scope.$broadcast('wazuhFilter', { filter });
|
||||
if (!$scope.mctrl.showingLocalRules) {
|
||||
const filter = { name: 'path', value: term.split('path:')[1].trim() };
|
||||
$scope.appliedFilters = $scope.appliedFilters.filter(
|
||||
item => item.name !== 'path'
|
||||
);
|
||||
$scope.appliedFilters.push(filter);
|
||||
$scope.$broadcast('wazuhFilter', { filter });
|
||||
}
|
||||
} else {
|
||||
clearInput = false;
|
||||
$scope.$broadcast('wazuhSearch', { term, removeFilters: 0 });
|
||||
}
|
||||
if (clearInput) {
|
||||
const searchBar = $('#search-input-rules');
|
||||
searchBar.val('');
|
||||
}
|
||||
$scope.$applyAsync();
|
||||
};
|
||||
|
||||
/**
|
||||
@ -126,6 +135,13 @@ export function RulesController(
|
||||
return filtered.length ? filtered[0].value : '';
|
||||
};
|
||||
|
||||
$scope.switchLocalRules = () => {
|
||||
$scope.removeFilter('path');
|
||||
if (!$scope.mctrl.showingLocalRules) {
|
||||
$scope.appliedFilters.push({ name: 'path', value: 'etc/rules' });
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* This a the filter given its name
|
||||
* @param {String} filterName
|
||||
@ -253,16 +269,19 @@ export function RulesController(
|
||||
);
|
||||
const response =
|
||||
(((ruleReloaded || {}).data || {}).data || {}).items || [];
|
||||
if (!response.length) {
|
||||
$scope.currentRule = null;
|
||||
$scope.closeDetailView(true);
|
||||
if (response.length) {
|
||||
const result = response.filter(rule => rule.details.overwrite);
|
||||
$scope.currentRule = result.length ? result[0] : response[0];
|
||||
} else {
|
||||
$scope.currentRule = response[0];
|
||||
$scope.currentRule = false;
|
||||
$scope.closeDetailView(true);
|
||||
}
|
||||
$scope.fetchedXML = false;
|
||||
} catch (error) {
|
||||
errorHandler.handle(error.message || error);
|
||||
}
|
||||
}
|
||||
|
||||
$scope.editingFile = false;
|
||||
$scope.$applyAsync();
|
||||
appState.setNavigation({ status: true });
|
||||
@ -279,6 +298,7 @@ export function RulesController(
|
||||
* This function changes to the rules list view
|
||||
*/
|
||||
$scope.closeDetailView = clear => {
|
||||
$scope.mctrl.showingLocalRules = !$scope.mctrl.showingLocalRules;
|
||||
if (clear)
|
||||
$scope.appliedFilters = $scope.appliedFilters.slice(
|
||||
0,
|
||||
@ -288,6 +308,8 @@ export function RulesController(
|
||||
$scope.currentRule = false;
|
||||
$scope.closeEditingFile();
|
||||
$scope.$emit('removeCurrentRule');
|
||||
$scope.switchLocalRules();
|
||||
$scope.mctrl.showingLocalRules = !$scope.mctrl.showingLocalRules;
|
||||
$scope.$applyAsync();
|
||||
};
|
||||
|
||||
@ -297,7 +319,11 @@ export function RulesController(
|
||||
apiReq
|
||||
.request('get', `/rules/${incomingRule}`, {})
|
||||
.then(data => {
|
||||
$scope.currentRule = data.data.data.items[0];
|
||||
const response = (((data || {}).data || {}).data || {}).items || [];
|
||||
if (response.length) {
|
||||
const result = response.filter(rule => rule.details.overwrite);
|
||||
$scope.currentRule = result.length ? result[0] : response[0];
|
||||
}
|
||||
$scope.$emit('setCurrentRule', { currentRule: $scope.currentRule });
|
||||
if (
|
||||
!(Object.keys(($scope.currentRule || {}).details || {}) || []).length
|
||||
|
@ -124,12 +124,10 @@ export class SettingsController {
|
||||
*/
|
||||
async removeManager(item) {
|
||||
try {
|
||||
const currentApi = this.appState.getCurrentAPI();
|
||||
let index = this.apiEntries.indexOf(item);
|
||||
if (this.appState.getCurrentAPI()) {
|
||||
if (
|
||||
this.apiEntries[index]._id ===
|
||||
JSON.parse(this.appState.getCurrentAPI()).id
|
||||
) {
|
||||
if (currentApi) {
|
||||
if (this.apiEntries[index]._id === JSON.parse(currentApi).id) {
|
||||
// We are trying to remove the one selected as default
|
||||
this.appState.removeCurrentAPI();
|
||||
}
|
||||
|
@ -30,7 +30,7 @@
|
||||
<tfoot>
|
||||
<td colspan="{{keys.length}}">
|
||||
<span ng-show="!wazuh_table_loading" class="color-grey">{{ totalItems }} items</span>
|
||||
<div ng-show="items.length >= itemsPerPage" class="pagination pull-right" style="margin:0 !important">
|
||||
<div ng-show="items.length > itemsPerPage" class="pagination pull-right" style="margin:0 !important">
|
||||
<ul layout="row">
|
||||
<li ng-show="currentPage" class="md-padding">
|
||||
<a href ng-click="prevPage()">« Prev</a>
|
||||
|
@ -103,7 +103,7 @@
|
||||
<tfoot>
|
||||
<td colspan="3">
|
||||
<span ng-show="!wazuh_table_loading" class="color-grey">{{ totalItems }} items</span>
|
||||
<div ng-show="items.length >= itemsPerPage" class="pagination pull-right"
|
||||
<div ng-show="items.length > itemsPerPage" class="pagination pull-right"
|
||||
style="margin:0 !important">
|
||||
<ul layout="row">
|
||||
<li ng-show="currentPage > 0" class="md-padding">
|
||||
@ -133,12 +133,14 @@
|
||||
</tfoot>
|
||||
</table>
|
||||
</md-card-content>
|
||||
<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('/lists', currentList.name, currentList.path)">
|
||||
<react-component name="EuiIcon" props="{type:'importAction', color:'primary'}" /> Formatted
|
||||
</a>
|
||||
<md-card-actions layout="row" layout-align="end center" class="layout-align-end-center layout-row">
|
||||
<button type="button" ng-click="downloadCsv('/lists', currentList.name, currentList.path)"
|
||||
class="euiButtonEmpty euiButtonEmpty--primary euiButtonEmpty--small" id="btnDownload">
|
||||
<span class="euiButtonEmpty__content">
|
||||
<react-component name="EuiIcon" props="{type:'importAction'}" />
|
||||
<span class="euiButtonEmpty__text">Formatted</span>
|
||||
</span>
|
||||
</button>
|
||||
</md-card-actions>
|
||||
</md-card>
|
||||
</div>
|
||||
|
@ -110,8 +110,7 @@ app.directive('wzTable', function() {
|
||||
// Prevents duplicated rows when resizing
|
||||
let resizing = false;
|
||||
$window.onresize = () => {
|
||||
if (resizing) return;
|
||||
$(`#table${$scope.scapepath}`).colResizable({ disable: true });
|
||||
if (resizing || $scope.resizingColumns) return;
|
||||
resizing = true;
|
||||
clearTimeout(doit);
|
||||
doit = setTimeout(() => {
|
||||
@ -119,6 +118,7 @@ app.directive('wzTable', function() {
|
||||
$scope.itemsPerPage = $scope.rowsPerPage;
|
||||
init(true)
|
||||
.then(() => {
|
||||
$scope.setColResizable();
|
||||
resizing = false;
|
||||
})
|
||||
.catch(() => (resizing = false));
|
||||
@ -501,11 +501,15 @@ app.directive('wzTable', function() {
|
||||
};
|
||||
|
||||
$scope.setColResizable = () => {
|
||||
$(`#table${$scope.scapepath}`).colResizable({
|
||||
liveDrag: true,
|
||||
minWidth: 78,
|
||||
partialRefresh: true,
|
||||
draggingClass: false
|
||||
$(`#table${$scope.scapepath} th`).resizable({
|
||||
handles: 'e',
|
||||
minWidth: 75,
|
||||
start: () => {
|
||||
$scope.resizingColumns = true;
|
||||
},
|
||||
end: () => {
|
||||
$scope.resizingColumns = false;
|
||||
}
|
||||
});
|
||||
$scope.$applyAsync();
|
||||
};
|
||||
|
@ -3,49 +3,42 @@
|
||||
</div>
|
||||
<div ng-if="customColumns" layout="row" ng-show="!error && !wazuh_table_loading && items.length" class="columns-bar"
|
||||
ng-class="{'columns-bar-active': showColumns}" ng-style="!showColumns && {'margin-bottom': '-35px'}">
|
||||
<div ng-if="showColumns" class="euiCheckbox wz-margin-right-8" ng-repeat="key in originalkeys"
|
||||
ng-click="updateColumns(key)">
|
||||
<div ng-if="showColumns" class="euiCheckbox wz-margin-right-8" ng-repeat="key in originalkeys" ng-click="updateColumns(key)">
|
||||
<input class="euiCheckbox__input" type="checkbox" aria-label="Select all rows" ng-checked="exists(key)">
|
||||
<div class="euiCheckbox__square"></div>
|
||||
<span class="euiCheckbox__label">{{ keyEquivalence[key.key.value || key.key] }}</span>
|
||||
</div>
|
||||
<span flex></span>
|
||||
<span class="wz-text-link" style="line-height: 28px;" ng-click="showColumns = !showColumns" tooltip="Columns">
|
||||
<span class="wz-text-link" style="line-height: 22px;z-index: 10000;" ng-click="showColumns = !showColumns" tooltip="Columns">
|
||||
<react-component name="EuiIcon" props="{type:'gear'}" />
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div ng-if="!wazuh_table_loading && !isPolicyMonitoring() && !isSyscheck()" ng-show="!error && items.length">
|
||||
<table class="euiTable euiTable--responsive table table-striped table-condensed table-hover no-margin-bottom"
|
||||
ng-class="customColumns ? 'table-resizable' : ''" style="table-layout: fixed !important"
|
||||
id="table{{scapepath}}">
|
||||
<table class="table table-striped table-condensed table-hover no-margin-bottom"
|
||||
ng-class="customColumns ? 'table-resizable' : 'euiTable euiTable--responsive'" id="table{{scapepath}}">
|
||||
<thead class="wz-text-bold">
|
||||
<th ng-repeat="key in keys" class="euiTableHeaderCell wz-text-left"
|
||||
ng-style="key.width && {'width':key.width}" ng-class="{ 'cursor-pointer' : !key.nosortable}"
|
||||
ng-click="!key.nosortable && sort(key)">
|
||||
<span>
|
||||
<th ng-repeat="key in keys" class="euiTableHeaderCell wz-text-left" ng-style="(key.width && !customColumns) && {'width':key.width}">
|
||||
<p ng-class="{ 'cursor-pointer' : !key.nosortable}" ng-click="!key.nosortable && sort(key)">
|
||||
{{ path === '/agents/groups' && (key.value || key) === 'count' ? 'Agents' :
|
||||
keyEquivalence[key.value ||
|
||||
key] || key.value || key }}
|
||||
<i ng-if="!key.nosortable" class="fa wz-theader-sort-icon"
|
||||
ng-class="sortValue === (key.value || key) ? (sortDir ? 'fa-sort-asc' : 'fa-sort-desc') : 'fa-sort'"
|
||||
<i ng-if="!key.nosortable" class="fa wz-theader-sort-icon" ng-class="sortValue === (key.value || key) ? (sortDir ? 'fa-sort-asc' : 'fa-sort-desc') : 'fa-sort'"
|
||||
aria-hidden="true"></i>
|
||||
</span>
|
||||
</p>
|
||||
</th>
|
||||
<th ng-if="(path === '/agents' || (path === '/agents/groups' && adminMode) || (isLookingGroup() && adminMode)
|
||||
|| path === '/rules/files' || path === '/decoders/files' || path === '/lists/files')"
|
||||
class="euiTableHeaderCell wz-text-left"
|
||||
ng-class="{'col-lg-2': path !== '/agents', 'col-lg-1': path === '/agents'}">
|
||||
class="euiTableHeaderCell wz-text-left">
|
||||
Actions
|
||||
</th>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-class="allowClick ? 'cursor-pointer' : ''" class="euiTableRow wz-word-wrap"
|
||||
ng-repeat="item in pagedItems[currentPage] | filter:{item:'!'}" ng-click="clickAction(item)">
|
||||
<td ng-repeat="key in keys" id="td-{{$parent.$index}}-{{$index}}"
|
||||
ng-mouseover="showTooltip($parent.$index, $index, item)">
|
||||
<div class="wz-text-truncatable">
|
||||
<span>
|
||||
<tr ng-class="allowClick ? 'cursor-pointer' : ''" class="wz-word-wrap" ng-repeat="item in pagedItems[currentPage] | filter:{item:'!'}"
|
||||
ng-click="clickAction(item)">
|
||||
<td ng-repeat="key in keys" id="td-{{$parent.$index}}-{{$index}}" ng-mouseover="showTooltip($parent.$index, $index, item)">
|
||||
<div ng-class="customColumns ? 'wz-text-truncatable-container' : ''">
|
||||
<span class="wz-text-truncatable">
|
||||
{{
|
||||
parseValue(key,item)
|
||||
}}
|
||||
@ -56,9 +49,8 @@
|
||||
</div>
|
||||
</td>
|
||||
<td ng-if="path === '/agents'" ng-click="$event.stopPropagation()" class="cursor-default action-btn-td">
|
||||
<span ng-click="clickAction(item, 'discover'); $event.stopPropagation()"
|
||||
class="wz-margin-left-8 cursor-pointer" tooltip="Open Discover panel for this agent"
|
||||
tooltip-placement="left" aria-hidden="true">
|
||||
<span ng-click="clickAction(item, 'discover'); $event.stopPropagation()" class="wz-margin-left-8 cursor-pointer"
|
||||
tooltip="Open Discover panel for this agent" tooltip-placement="left" aria-hidden="true">
|
||||
<react-component name="EuiIcon" props="{type:'discoverApp', color:'primary'}" />
|
||||
</span>
|
||||
<span ng-click="clickAction(item, 'configuration'); $event.stopPropagation()" class="cursor-pointer"
|
||||
@ -66,17 +58,15 @@
|
||||
<react-component name="EuiIcon" props="{type:'wrench', color:'primary'}" />
|
||||
</span>
|
||||
</td>
|
||||
<td ng-if="path === '/agents/groups' && adminMode" ng-click="$event.stopPropagation()"
|
||||
class="cursor-default action-btn-td">
|
||||
<span ng-if="removingGroup !== item.name && item.name !== 'default'"
|
||||
ng-click="showConfirmRemoveGroup($event, item); $event.stopPropagation()"
|
||||
ng-class="{'wz-margin-left-8': item.name !== 'default'}" class="cursor-pointer"
|
||||
tooltip="Remove this group" tooltip-placement="left" aria-hidden="true">
|
||||
<td ng-if="path === '/agents/groups' && adminMode" ng-click="$event.stopPropagation()" class="cursor-default action-btn-td">
|
||||
<span ng-if="removingGroup !== item.name && item.name !== 'default'" ng-click="showConfirmRemoveGroup($event, item); $event.stopPropagation()"
|
||||
ng-class="{'wz-margin-left-8': item.name !== 'default'}" class="cursor-pointer" tooltip="Remove this group"
|
||||
tooltip-placement="left" aria-hidden="true">
|
||||
<react-component name="EuiIcon" props="{type:'trash', color:'primary'}" />
|
||||
</span>
|
||||
<span ng-if="removingGroup !== item.name" ng-click="editGroup(item); $event.stopPropagation()"
|
||||
tooltip="Edit this group configuration" tooltip-placement="left"
|
||||
ng-class="{'wz-margin-left-8': item.name === 'default'}" class="cursor-pointer">
|
||||
tooltip="Edit this group configuration" tooltip-placement="left" ng-class="{'wz-margin-left-8': item.name === 'default'}"
|
||||
class="cursor-pointer">
|
||||
<react-component name="EuiIcon" props="{type:'pencil', color:'primary'}" />
|
||||
</span>
|
||||
|
||||
@ -86,18 +76,15 @@
|
||||
removed</span>
|
||||
</div>
|
||||
<div layout="row">
|
||||
<md-button class="cancelBtn" type="button" ng-click="cancelRemoveGroup()"><i
|
||||
aria-hidden='true' class='fa fa-fw fa-close'></i> Cancel</md-button>
|
||||
<md-button class="agreeBtn wz-button" type="button"
|
||||
ng-click="confirmRemoveGroup(item.name)"><i aria-hidden='true'
|
||||
class='fa fa-fw fa-check'></i> Confirm</md-button>
|
||||
<md-button class="cancelBtn" type="button" ng-click="cancelRemoveGroup()"><i aria-hidden='true'
|
||||
class='fa fa-fw fa-close'></i> Cancel</md-button>
|
||||
<md-button class="agreeBtn wz-button" type="button" ng-click="confirmRemoveGroup(item.name)"><i
|
||||
aria-hidden='true' class='fa fa-fw fa-check'></i> Confirm</md-button>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td ng-if="isLookingGroup() && adminMode" ng-click="$event.stopPropagation()"
|
||||
class="cursor-default action-btn-td">
|
||||
<span ng-if="removingAgent !== item.id && adminMode"
|
||||
ng-click="showConfirmRemoveAgentFromGroup($event, item); $event.stopPropagation()"
|
||||
<td ng-if="isLookingGroup() && adminMode" ng-click="$event.stopPropagation()" class="cursor-default action-btn-td">
|
||||
<span ng-if="removingAgent !== item.id && adminMode" ng-click="showConfirmRemoveAgentFromGroup($event, item); $event.stopPropagation()"
|
||||
class="wz-margin-left-8 cursor-pointer" tooltip="Remove this agent from the group"
|
||||
tooltip-placement="left" aria-hidden="true">
|
||||
<react-component name="EuiIcon" props="{type:'trash', color:'primary'}" />
|
||||
@ -109,32 +96,28 @@
|
||||
this group</span>
|
||||
</div>
|
||||
<div layout="row">
|
||||
<md-button class="cancelBtn" type="button" ng-click="cancelRemoveAgent()"><i
|
||||
aria-hidden='true' class='fa fa-fw fa-close'></i> Cancel</md-button>
|
||||
<md-button class="cancelBtn" type="button" ng-click="cancelRemoveAgent()"><i aria-hidden='true'
|
||||
class='fa fa-fw fa-close'></i> Cancel</md-button>
|
||||
<md-button class="agreeBtn wz-button" type="button" ng-click="confirmRemoveAgent(item.id)">
|
||||
<i aria-hidden='true' class='fa fa-fw fa-check'></i> Confirm</md-button>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td ng-if="path === '/rules/files' || path === '/decoders/files' || path === '/lists/files'"
|
||||
ng-click="$event.stopPropagation()" class="cursor-default action-btn-td">
|
||||
<span
|
||||
ng-if="(item.path === 'etc/rules' || item.path === 'etc/decoders') && ((item.name && removingFile !== item.name) || (item.file && removingFile !== item.file)) && adminMode && path !== '/lists/files'"
|
||||
ng-click="editFile(item, path); $event.stopPropagation()"
|
||||
class="wz-margin-left-8 cursor-pointer" tooltip="Edit this file" tooltip-placement="left"
|
||||
aria-hidden="true">
|
||||
<td ng-if="path === '/rules/files' || path === '/decoders/files' || path === '/lists/files'" ng-click="$event.stopPropagation()"
|
||||
class="cursor-default action-btn-td">
|
||||
<span ng-if="(item.path === 'etc/rules' || item.path === 'etc/decoders') && ((item.name && removingFile !== item.name) || (item.file && removingFile !== item.file)) && adminMode && path !== '/lists/files'"
|
||||
ng-click="editFile(item, path); $event.stopPropagation()" class="wz-margin-left-8 cursor-pointer"
|
||||
tooltip="Edit this file" tooltip-placement="left" aria-hidden="true">
|
||||
|
||||
<react-component name="EuiIcon" props="{type:'pencil', color:'primary'}" />
|
||||
</span>
|
||||
<span
|
||||
ng-if="(item.path === 'etc/rules' || item.path === 'etc/decoders' || path === '/lists/files') && ((item.name && removingFile !== item.name) || (item.file && removingFile !== item.file)) && adminMode"
|
||||
ng-click="showConfirmRemoveFile($event, item, path); $event.stopPropagation()"
|
||||
class="cursor-pointer" ng-class="{'wz-margin-left-8': path === '/lists/files'}"
|
||||
tooltip="Delete this file" tooltip-placement="right" aria-hidden="true">
|
||||
<span ng-if="(item.path === 'etc/rules' || item.path === 'etc/decoders' || path === '/lists/files') && ((item.name && removingFile !== item.name) || (item.file && removingFile !== item.file)) && adminMode"
|
||||
ng-click="showConfirmRemoveFile($event, item, path); $event.stopPropagation()" class="cursor-pointer"
|
||||
ng-class="{'wz-margin-left-8': path === '/lists/files'}" tooltip="Delete this file"
|
||||
tooltip-placement="right" aria-hidden="true">
|
||||
<react-component name="EuiIcon" props="{type:'trash', color:'primary'}" />
|
||||
</span>
|
||||
<span
|
||||
ng-if="(item.path !== 'etc/rules' && item.path !== 'etc/decoders') && ((item.name && removingFile !== item.name) || (item.file && removingFile !== item.file)) && adminMode && path !== '/lists/files'"
|
||||
<span ng-if="(item.path !== 'etc/rules' && item.path !== 'etc/decoders') && ((item.name && removingFile !== item.name) || (item.file && removingFile !== item.file)) && adminMode && path !== '/lists/files'"
|
||||
class="wz-margin-left-8" aria-hidden="true">
|
||||
-
|
||||
</span>
|
||||
@ -146,45 +129,39 @@
|
||||
: item.file}}</b> will be deleted</span>
|
||||
</div>
|
||||
<div layout="row">
|
||||
<md-button class="cancelBtn" type="button" ng-click="cancelRemoveFile()"><i
|
||||
aria-hidden='true' class='fa fa-fw fa-close'></i> Cancel</md-button>
|
||||
<md-button class="agreeBtn wz-button" type="button"
|
||||
ng-click="confirmRemoveFile(item, path)"><i aria-hidden='true'
|
||||
class='fa fa-fw fa-check'></i> Confirm</md-button>
|
||||
<md-button class="cancelBtn" type="button" ng-click="cancelRemoveFile()"><i aria-hidden='true'
|
||||
class='fa fa-fw fa-close'></i> Cancel</md-button>
|
||||
<md-button class="agreeBtn wz-button" type="button" ng-click="confirmRemoveFile(item, path)"><i
|
||||
aria-hidden='true' class='fa fa-fw fa-check'></i> Confirm</md-button>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<td
|
||||
colspan="{{ (path === '/agents' || (path === '/agents/groups' && adminMode) || (isLookingGroup() && adminMode) ||
|
||||
<td colspan="{{ (path === '/agents' || (path === '/agents/groups' && adminMode) || (isLookingGroup() && adminMode) ||
|
||||
path === '/rules/files' || path === '/decoders/files' || path === '/lists/files') ? keys.length + 1 : keys.length}}">
|
||||
<span ng-show="!wazuh_table_loading" class="color-grey">{{ totalItems }} items ({{time | number: 2}}
|
||||
seconds)</span>
|
||||
<div ng-show="items.length >= itemsPerPage" class="pagination pull-right" style="margin:0 !important">
|
||||
<div ng-show="items.length > itemsPerPage" class="pagination pull-right" style="margin:0 !important">
|
||||
<ul layout="row">
|
||||
<li ng-show="currentPage > 0" class="md-padding">
|
||||
<a href ng-click="firstPage()">First</a>
|
||||
</li>
|
||||
|
||||
<li ng-show="currentPage" class="md-padding">
|
||||
<a href ng-click="prevPage()">
|
||||
<react-component name="EuiIcon" props="{type:'arrowLeft'}" />
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li ng-repeat="n in range(pagedItems.length, currentPage, currentPage + gap) "
|
||||
ng-class="{'wz-text-active': n == currentPage}" ng-click="setPage()" class="md-padding">
|
||||
<li ng-repeat="n in range(pagedItems.length, currentPage, currentPage + gap) " ng-class="{'wz-text-active': n == currentPage}"
|
||||
ng-click="setPage()" class="md-padding">
|
||||
<a href ng-bind="n + 1">1</a>
|
||||
</li>
|
||||
|
||||
<li ng-show="currentPage < pagedItems.length - 1" class="md-padding">
|
||||
<a href ng-click="nextPage()">
|
||||
<react-component name="EuiIcon" props="{type:'arrowRight'}" />
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li ng-show="currentPage < pagedItems.length - 1" class="md-padding">
|
||||
<a href ng-click="setPage(pagedItems.length - 1, false, true)">Last</a>
|
||||
</li>
|
||||
@ -196,30 +173,23 @@
|
||||
</div>
|
||||
|
||||
<div ng-if="!wazuh_table_loading && isPolicyMonitoring()" ng-show="!error && items.length">
|
||||
<table
|
||||
class="euiTable euiTable--responsive table table-striped table-striped-duo table-condensed table-hover no-margin-bottom"
|
||||
ng-class="customColumns ? 'table-resizable' : ''" style="table-layout: fixed !important"
|
||||
id="table{{scapepath}}">
|
||||
<table class="table table-striped table-striped-duo table-condensed table-hover no-margin-bottom"
|
||||
ng-class="customColumns ? 'table-resizable' : 'euiTable euiTable--responsive'" id="table{{scapepath}}">
|
||||
<thead class="wz-text-bold">
|
||||
<th ng-repeat="key in keys" class="euiTableHeaderCell wz-text-left"
|
||||
ng-style="key.width && {'width':key.width}" ng-class="{ 'cursor-pointer' : !key.nosortable }"
|
||||
ng-click="!key.nosortable && sort(key)">
|
||||
<span>
|
||||
<th ng-repeat="key in keys" class="euiTableHeaderCell wz-text-left" ng-style="key.width && {'width':key.width}">
|
||||
<p ng-class="{ 'cursor-pointer' : !key.nosortable }" ng-click="!key.nosortable && sort(key)">
|
||||
{{ keyEquivalence[key.value || key] || key.value || key }}
|
||||
<i ng-if="!key.nosortable" class="fa wz-theader-sort-icon"
|
||||
ng-class="sortValue === (key.value || key) ? (sortDir ? 'fa-sort-asc' : 'fa-sort-desc') : 'fa-sort'"
|
||||
<i ng-if="!key.nosortable" class="fa wz-theader-sort-icon" ng-class="sortValue === (key.value || key) ? (sortDir ? 'fa-sort-asc' : 'fa-sort-desc') : 'fa-sort'"
|
||||
aria-hidden="true"></i>
|
||||
</span>
|
||||
</p>
|
||||
</th>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="euiTableRow wz-word-wrap cursor-pointer"
|
||||
ng-repeat-start="item in pagedItems[currentPage] | filter:{item:'!'}" ng-click="expandTableRow(item)"
|
||||
ng-class="{'selected': item.expanded}">
|
||||
<td ng-repeat="key in keys" id="td-{{$parent.$index}}-{{$index}}"
|
||||
ng-mouseover="showTooltip($parent.$index, $index, item)">
|
||||
<div class="wz-text-truncatable">
|
||||
<span>
|
||||
<tr class="wz-word-wrap cursor-pointer" ng-repeat-start="item in pagedItems[currentPage] | filter:{item:'!'}"
|
||||
ng-click="expandTableRow(item)" ng-class="{'selected': item.expanded}">
|
||||
<td ng-repeat="key in keys" id="td-{{$parent.$index}}-{{$index}}" ng-mouseover="showTooltip($parent.$index, $index, item)">
|
||||
<div ng-class="customColumns ? 'wz-text-truncatable-container' : ''">
|
||||
<span class="wz-text-truncatable">
|
||||
<span ng-show="(key.value || key ) === 'result'" class="no-wrap">
|
||||
<p class="round status little" ng-class="(item.result === 'passed') ? 'teal' : 'red'">
|
||||
</p>
|
||||
@ -235,7 +205,7 @@
|
||||
</td>
|
||||
</tr>
|
||||
<tr ng-show="(item.rationale || item.remediation || item.directory || (item.rules && item.rules.length) || (item.compliance && item.compliance.length)) && item.expanded"
|
||||
class="euiTableRow wz-word-wrap cursor-pointer selected" ng-repeat-end=""
|
||||
class="wz-word-wrap cursor-pointer selected" ng-repeat-end=""
|
||||
ng-click="expandTableRow(item)">
|
||||
<td colspan="{{keys.length}}" style="border-top: none">
|
||||
<div layout="row" layout-padding="" class="layout-padding layout-row">
|
||||
@ -244,8 +214,7 @@
|
||||
<div>
|
||||
<div class="euiFlexItem euiFlexItem--flexGrowZero" ng-if="item.rationale">
|
||||
<div class="euiStat euiStat--leftAligned">
|
||||
<p class="euiTitle euiTitle--small euiStat__title ng-binding"
|
||||
style="font-size: 1.15rem;">Rationale</p>
|
||||
<p class="euiTitle euiTitle--small euiStat__title ng-binding" style="font-size: 1.15rem;">Rationale</p>
|
||||
<div class="euiText euiText--small euiStat__description wz-text-gray">
|
||||
<p>{{item.rationale}}</p>
|
||||
</div>
|
||||
@ -254,8 +223,7 @@
|
||||
</div>
|
||||
<div class="euiFlexItem euiFlexItem--flexGrowZero" ng-if="item.remediation">
|
||||
<div class="euiStat euiStat--leftAligned">
|
||||
<p class="euiTitle euiTitle--small euiStat__title ng-binding"
|
||||
style="font-size: 1.15rem;">Remediation</p>
|
||||
<p class="euiTitle euiTitle--small euiStat__title ng-binding" style="font-size: 1.15rem;">Remediation</p>
|
||||
<div class="euiText euiText--small euiStat__description wz-text-gray">
|
||||
<p>{{item.remediation}}</p>
|
||||
</div>
|
||||
@ -264,8 +232,7 @@
|
||||
</div>
|
||||
<div class="euiFlexItem euiFlexItem--flexGrowZero" ng-if="item.description">
|
||||
<div class="euiStat euiStat--leftAligned">
|
||||
<p class="euiTitle euiTitle--small euiStat__title ng-binding"
|
||||
style="font-size: 1.15rem;">Description</p>
|
||||
<p class="euiTitle euiTitle--small euiStat__title ng-binding" style="font-size: 1.15rem;">Description</p>
|
||||
<div class="euiText euiText--small euiStat__description wz-text-gray">
|
||||
<p>{{item.description}}</p>
|
||||
</div>
|
||||
@ -274,8 +241,7 @@
|
||||
</div>
|
||||
<div class="euiFlexItem euiFlexItem--flexGrowZero" ng-if="item.directory">
|
||||
<div class="euiStat euiStat--leftAligned">
|
||||
<p class="euiTitle euiTitle--small euiStat__title ng-binding"
|
||||
style="font-size: 1.15rem;">Path(s)</p>
|
||||
<p class="euiTitle euiTitle--small euiStat__title ng-binding" style="font-size: 1.15rem;">Path(s)</p>
|
||||
<div class="euiText euiText--small euiStat__description wz-text-gray">
|
||||
<p>{{item.directory}}</p>
|
||||
</div>
|
||||
@ -297,9 +263,9 @@
|
||||
</div>
|
||||
<div class="euiFlexItem euiFlexItem--flexGrowZero"
|
||||
ng-if="item.compliance && item.compliance.length">
|
||||
|
||||
<div class="euiStat euiStat--leftAligned">
|
||||
<p class="euiTitle euiTitle--small euiStat__title ng-binding"
|
||||
style="font-size: 1.15rem;">Compliance</p>
|
||||
<p class="euiTitle euiTitle--small euiStat__title ng-binding" style="font-size: 1.15rem;">Compliance</p>
|
||||
<div class="euiText euiText--small euiStat__description wz-text-gray">
|
||||
<div layout="row" ng-repeat="c in item.compliance">
|
||||
{{c.key}}/{{c.value}}
|
||||
@ -319,24 +285,28 @@
|
||||
<td colspan="{{keys.length}}">
|
||||
<span ng-show="!wazuh_table_loading" class="color-grey">{{ totalItems }} items ({{time | number: 2}}
|
||||
seconds)</span>
|
||||
<div ng-show="items.length >= itemsPerPage" class="pagination pull-right" style="margin:0 !important">
|
||||
<div ng-show="items.length > itemsPerPage" class="pagination pull-right" style="margin:0 !important">
|
||||
<ul layout="row">
|
||||
<li ng-show="currentPage > 0" class="md-padding">
|
||||
<a href ng-click="firstPage()">First</a>
|
||||
</li>
|
||||
<li ng-show="currentPage" class="md-padding">
|
||||
<a href ng-click="prevPage()">
|
||||
<react-component name="EuiIcon" props="{type:'arrowLeft'}" />
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li ng-repeat="n in range(pagedItems.length, currentPage, currentPage + gap) "
|
||||
ng-class="{'wz-text-active': n == currentPage}" ng-click="setPage()" class="md-padding">
|
||||
<li ng-repeat="n in range(pagedItems.length, currentPage, currentPage + gap) " ng-class="{'wz-text-active': n == currentPage}"
|
||||
ng-click="setPage()" class="md-padding">
|
||||
<a href ng-bind="n + 1">1</a>
|
||||
</li>
|
||||
|
||||
<li ng-show="currentPage < pagedItems.length - 1" class="md-padding">
|
||||
<a href ng-click="nextPage()">
|
||||
<react-component name="EuiIcon" props="{type:'arrowRight'}" />
|
||||
</a>
|
||||
</li>
|
||||
<li ng-show="currentPage < pagedItems.length - 1" class="md-padding">
|
||||
<a href ng-click="setPage(pagedItems.length - 1, false, true)">Last</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</td>
|
||||
@ -345,30 +315,23 @@
|
||||
</div>
|
||||
|
||||
<div ng-if="!wazuh_table_loading && isSyscheck()" ng-show="!error && items.length">
|
||||
<table
|
||||
class="euiTable euiTable--responsive table table-striped table-striped-duo table-condensed table-hover no-margin-bottom"
|
||||
ng-class="customColumns ? 'table-resizable' : ''" style="table-layout: fixed !important"
|
||||
id="table{{scapepath}}">
|
||||
<table class="table table-striped table-striped-duo table-condensed table-hover no-margin-bottom"
|
||||
ng-class="customColumns ? 'table-resizable' : 'euiTable euiTable--responsive'" id="table{{scapepath}}">
|
||||
<thead class="wz-text-bold">
|
||||
<th ng-repeat="key in keys" class="euiTableHeaderCell wz-text-left"
|
||||
ng-style="key.width && {'width':key.width}" ng-class="{ 'cursor-pointer' : !key.nosortable }"
|
||||
ng-click="!key.nosortable && sort(key)">
|
||||
<span>{{
|
||||
<th ng-repeat="key in keys" class="euiTableHeaderCell wz-text-left" ng-style="key.width && {'width':key.width}">
|
||||
<p ng-class="{ 'cursor-pointer' : !key.nosortable }" ng-click="!key.nosortable && sort(key)">{{
|
||||
keyEquivalence[key.value || key] || key.value || key }}
|
||||
<i ng-if="!key.nosortable" class="fa wz-theader-sort-icon"
|
||||
ng-class="sortValue === (key.value || key) ? (sortDir ? 'fa-sort-asc' : 'fa-sort-desc') : 'fa-sort'"
|
||||
<i ng-if="!key.nosortable" class="fa wz-theader-sort-icon" ng-class="sortValue === (key.value || key) ? (sortDir ? 'fa-sort-asc' : 'fa-sort-desc') : 'fa-sort'"
|
||||
aria-hidden="true"></i>
|
||||
</span>
|
||||
</p>
|
||||
</th>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="euiTableRow wz-word-wrap cursor-pointer"
|
||||
ng-repeat-start="item in pagedItems[currentPage] | filter:{item:'!'}" ng-click="expandTableRow(item)"
|
||||
ng-class="{'selected': item.expanded}">
|
||||
<td ng-repeat="key in keys" id="td-{{$parent.$index}}-{{$index}}"
|
||||
ng-mouseover="showTooltip($parent.$index, $index, item)">
|
||||
<div class="wz-text-truncatable">
|
||||
<span>
|
||||
<tr class="wz-word-wrap cursor-pointer" ng-repeat-start="item in pagedItems[currentPage] | filter:{item:'!'}"
|
||||
ng-click="expandTableRow(item)" ng-class="{'selected': item.expanded}">
|
||||
<td ng-repeat="key in keys" id="td-{{$parent.$index}}-{{$index}}" ng-mouseover="showTooltip($parent.$index, $index, item)">
|
||||
<div class="wz-text-truncatable-container">
|
||||
<span class="wz-text-truncatable">
|
||||
{{
|
||||
parseValue(key,item)
|
||||
}}
|
||||
@ -379,7 +342,7 @@
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<tr class="euiTableRow wz-word-wrap cursor-pointer selected" ng-show="item.expanded" ng-repeat-end=""
|
||||
<tr class="wz-word-wrap cursor-pointer selected" ng-show="item.expanded" ng-repeat-end=""
|
||||
ng-click="expandTableRow(item)">
|
||||
<td colspan="{{keys.length}}" style="border-top: none">
|
||||
<div layout="row" layout-padding="" class="layout-padding layout-row" ng-if="item.expanded">
|
||||
@ -398,24 +361,28 @@
|
||||
<td colspan="{{keys.length}}">
|
||||
<span ng-show="!wazuh_table_loading" class="color-grey">{{ totalItems }} items ({{time | number: 2}}
|
||||
seconds)</span>
|
||||
<div ng-show="items.length >= itemsPerPage" class="pagination pull-right" style="margin:0 !important">
|
||||
<div ng-show="items.length > itemsPerPage" class="pagination pull-right" style="margin:0 !important">
|
||||
<ul layout="row">
|
||||
<li ng-show="currentPage > 0" class="md-padding">
|
||||
<a href ng-click="firstPage()">First</a>
|
||||
</li>
|
||||
<li ng-show="currentPage" class="md-padding">
|
||||
<a href ng-click="prevPage()">
|
||||
<react-component name="EuiIcon" props="{type:'arrowLeft'}" />
|
||||
</a>
|
||||
</li>
|
||||
|
||||
<li ng-repeat="n in range(pagedItems.length, currentPage, currentPage + gap) "
|
||||
ng-class="{'wz-text-active': n == currentPage}" ng-click="setPage()" class="md-padding">
|
||||
<li ng-repeat="n in range(pagedItems.length, currentPage, currentPage + gap) " ng-class="{'wz-text-active': n == currentPage}"
|
||||
ng-click="setPage()" class="md-padding">
|
||||
<a href ng-bind="n + 1">1</a>
|
||||
</li>
|
||||
|
||||
<li ng-show="currentPage < pagedItems.length - 1" class="md-padding">
|
||||
<a href ng-click="nextPage()">
|
||||
<react-component name="EuiIcon" props="{type:'arrowRight'}" />
|
||||
</a>
|
||||
</li>
|
||||
<li ng-show="currentPage < pagedItems.length - 1" class="md-padding">
|
||||
<a href ng-click="setPage(pagedItems.length - 1, false, true)">Last</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</td>
|
||||
|
@ -26,7 +26,7 @@
|
||||
<input id='wz-search-filter-bar-input' class='wz-search-filter-bar-input input' type='text' ng-model='newTag'
|
||||
ng-focus='showAutocomplete(true)' ng-blur='showAutocomplete(false)' placeholder='Add filter or search'
|
||||
ng-keyup='!autocompleteEnter && $event.keyCode == 13 ? addTag(true) : addSearchKey($event)' />
|
||||
<a class='wz-tag-remove-button wz-padding-top-5' ng-click='removeAll()'><i class="fa fa-trash-o" aria-hidden="true"></i></a>
|
||||
<a class='wz-tag-remove-button wz-padding-top-5' ng-show="groupedTagList.length" ng-click='removeAll()'><i class="fa fa-times" aria-hidden="true"></i></a>
|
||||
<div id='wz-search-filter-bar-autocomplete' class='wz-search-filter-bar-autocomplete' ng-show='isAutocomplete && autocompleteContent.list.length > 0'>
|
||||
<p><b>{{autocompleteContent.title}}</b></p>
|
||||
<ul id='wz-search-filter-bar-autocomplete-list'>
|
||||
|
@ -39,8 +39,9 @@
|
||||
}
|
||||
|
||||
.groupContentViewer {
|
||||
height: calc(~'100vh - 410px');
|
||||
min-height: 300px;
|
||||
height: calc(~'100vh - 250px');
|
||||
min-height: 300px!important;
|
||||
overflow: auto!important;
|
||||
}
|
||||
|
||||
.extraHeader{
|
||||
|
File diff suppressed because it is too large
Load Diff
1533
public/less/jquery-ui.css
vendored
Normal file
1533
public/less/jquery-ui.css
vendored
Normal file
File diff suppressed because it is too large
Load Diff
@ -20,3 +20,4 @@ import './layout.less';
|
||||
import './media-queries.less';
|
||||
import './typography.less';
|
||||
import './ui_framework.css';
|
||||
import './jquery-ui.css';
|
||||
|
@ -87,7 +87,16 @@ html, body, button:not(.fa):not(.fa-times), textarea, input, select, .wz-chip {
|
||||
.wz-text-truncatable {
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
text-overflow: ellipsis;
|
||||
&:before {
|
||||
content: attr(data-name);
|
||||
}
|
||||
}
|
||||
|
||||
.wz-text-truncatable-container {
|
||||
overflow: hidden;
|
||||
width: auto;
|
||||
display: grid;
|
||||
}
|
||||
|
||||
.font-size-12 {
|
||||
|
@ -47,7 +47,6 @@ export class ApiTester {
|
||||
return Promise.reject(result);
|
||||
}
|
||||
return result;
|
||||
|
||||
} catch (error) {
|
||||
if (((error || {}).data || {}).code === 3099) {
|
||||
// Do nothing
|
||||
|
@ -12,28 +12,23 @@
|
||||
<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 wz-margin-left-8"
|
||||
ng-click="switchAddingGroup()">
|
||||
<svg ng-if="!addingGroup" class="euiIcon euiIcon--medium" focusable="false"
|
||||
xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
||||
<path fill-rule="evenodd"
|
||||
d="M8 7h3.5a.5.5 0 1 1 0 1H8v3.5a.5.5 0 1 1-1 0V8H3.5a.5.5 0 0 1 0-1H7V3.5a.5.5 0 0 1 1 0V7zm-.5-7C11.636 0 15 3.364 15 7.5S11.636 15 7.5 15 0 11.636 0 7.5 3.364 0 7.5 0zm0 .882a6.618 6.618 0 1 0 0 13.236A6.618 6.618 0 0 0 7.5.882z">
|
||||
<span ng-if='adminMode' class="font-size-18 wz-text-link wz-margin-left-8" ng-click="switchAddingGroup()">
|
||||
<svg ng-if="!addingGroup" class="euiIcon euiIcon--medium" focusable="false" xmlns="http://www.w3.org/2000/svg"
|
||||
width="16" height="16" viewBox="0 0 16 16">
|
||||
<path fill-rule="evenodd" d="M8 7h3.5a.5.5 0 1 1 0 1H8v3.5a.5.5 0 1 1-1 0V8H3.5a.5.5 0 0 1 0-1H7V3.5a.5.5 0 0 1 1 0V7zm-.5-7C11.636 0 15 3.364 15 7.5S11.636 15 7.5 15 0 11.636 0 7.5 3.364 0 7.5 0zm0 .882a6.618 6.618 0 1 0 0 13.236A6.618 6.618 0 0 0 7.5.882z">
|
||||
</path>
|
||||
</svg>
|
||||
<svg ng-if="addingGroup" class="euiIcon euiIcon--medium" focusable="false"
|
||||
xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
||||
<path fill-rule="evenodd"
|
||||
d="M7.5 0C11.636 0 15 3.364 15 7.5S11.636 15 7.5 15 0 11.636 0 7.5 3.364 0 7.5 0zm0 .882a6.618 6.618 0 1 0 0 13.236A6.618 6.618 0 0 0 7.5.882zM3.5 7h8a.5.5 0 1 1 0 1h-8a.5.5 0 0 1 0-1z">
|
||||
<svg ng-if="addingGroup" class="euiIcon euiIcon--medium" focusable="false" xmlns="http://www.w3.org/2000/svg"
|
||||
width="16" height="16" viewBox="0 0 16 16">
|
||||
<path fill-rule="evenodd" d="M7.5 0C11.636 0 15 3.364 15 7.5S11.636 15 7.5 15 0 11.636 0 7.5 3.364 0 7.5 0zm0 .882a6.618 6.618 0 1 0 0 13.236A6.618 6.618 0 0 0 7.5.882zM3.5 7h8a.5.5 0 1 1 0 1h-8a.5.5 0 0 1 0-1z">
|
||||
</path>
|
||||
</svg>
|
||||
</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>
|
||||
@ -61,25 +56,21 @@
|
||||
<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='height-35 kuiButton kuiButton--secondary wz-margin-left-8'>
|
||||
<button ng-disabled='xmlHasErrors' ng-click='doSaveGroupAgentConfig()' class='height-35 kuiButton kuiButton--secondary wz-margin-left-8'>
|
||||
<span ng-show='!xmlHasErrors'>
|
||||
<svg class="euiIcon euiIcon--medium" focusable="false" xmlns="http://www.w3.org/2000/svg"
|
||||
width="16" height="16" viewBox="0 0 16 16">
|
||||
<path
|
||||
d="M5.008 2H2.282c-.181 0-.245.002-.275.007-.005.03-.007.094-.007.275v11.436c0 .181.002.245.007.275.03.005.094.007.275.007h11.436c.181 0 .245-.002.275-.007.005-.03.007-.094.007-.275V4.62c0-.13-.001-.18-.004-.204a2.654 2.654 0 0 0-.141-.147L11.73 2.145a2.654 2.654 0 0 0-.147-.141A2.654 2.654 0 0 0 11.38 2h-.388c.005.08.008.172.008.282v2.436c0 .446-.046.607-.134.77a.909.909 0 0 1-.378.378c-.163.088-.324.134-.77.134H6.282c-.446 0-.607-.046-.77-.134a.909.909 0 0 1-.378-.378C5.046 5.325 5 5.164 5 4.718V2.282c0-.11.003-.202.008-.282zM2.282 1h9.098c.259 0 .348.01.447.032a.87.87 0 0 1 .273.113c.086.054.156.11.338.293l2.124 2.124c.182.182.239.252.293.338a.87.87 0 0 1 .113.273c.023.1.032.188.032.447v9.098c0 .446-.046.607-.134.77a.909.909 0 0 1-.378.378c-.163.088-.324.134-.77.134H2.282c-.446 0-.607-.046-.77-.134a.909.909 0 0 1-.378-.378c-.088-.163-.134-.324-.134-.77V2.282c0-.446.046-.607.134-.77a.909.909 0 0 1 .378-.378c.163-.088.324-.134.77-.134zM6 2.282v2.436c0 .181.002.245.007.275.03.005.094.007.275.007h3.436c.181 0 .245-.002.275-.007.005-.03.007-.094.007-.275V2.282c0-.181-.002-.245-.007-.275A2.248 2.248 0 0 0 9.718 2H6.282c-.181 0-.245.002-.275.007-.005.03-.007.094-.007.275zM8 12a2 2 0 1 1 0-4 2 2 0 0 1 0 4zm0-1a1 1 0 1 0 0-2 1 1 0 0 0 0 2z">
|
||||
<path d="M5.008 2H2.282c-.181 0-.245.002-.275.007-.005.03-.007.094-.007.275v11.436c0 .181.002.245.007.275.03.005.094.007.275.007h11.436c.181 0 .245-.002.275-.007.005-.03.007-.094.007-.275V4.62c0-.13-.001-.18-.004-.204a2.654 2.654 0 0 0-.141-.147L11.73 2.145a2.654 2.654 0 0 0-.147-.141A2.654 2.654 0 0 0 11.38 2h-.388c.005.08.008.172.008.282v2.436c0 .446-.046.607-.134.77a.909.909 0 0 1-.378.378c-.163.088-.324.134-.77.134H6.282c-.446 0-.607-.046-.77-.134a.909.909 0 0 1-.378-.378C5.046 5.325 5 5.164 5 4.718V2.282c0-.11.003-.202.008-.282zM2.282 1h9.098c.259 0 .348.01.447.032a.87.87 0 0 1 .273.113c.086.054.156.11.338.293l2.124 2.124c.182.182.239.252.293.338a.87.87 0 0 1 .113.273c.023.1.032.188.032.447v9.098c0 .446-.046.607-.134.77a.909.909 0 0 1-.378.378c-.163.088-.324.134-.77.134H2.282c-.446 0-.607-.046-.77-.134a.909.909 0 0 1-.378-.378c-.088-.163-.134-.324-.134-.77V2.282c0-.446.046-.607.134-.77a.909.909 0 0 1 .378-.378c.163-.088.324-.134.77-.134zM6 2.282v2.436c0 .181.002.245.007.275.03.005.094.007.275.007h3.436c.181 0 .245-.002.275-.007.005-.03.007-.094.007-.275V2.282c0-.181-.002-.245-.007-.275A2.248 2.248 0 0 0 9.718 2H6.282c-.181 0-.245.002-.275.007-.005.03-.007.094-.007.275zM8 12a2 2 0 1 1 0-4 2 2 0 0 1 0 4zm0-1a1 1 0 1 0 0-2 1 1 0 0 0 0 2z">
|
||||
</path>
|
||||
</svg> 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>
|
||||
@ -97,23 +88,18 @@
|
||||
</div>
|
||||
|
||||
<!-- Search bar -->
|
||||
<div layout="row"
|
||||
class="wz-margin-top-16 euiFlexGroup euiFlexGroup--alignItemsCenter euiFormControlLayout__childrenWrapper md-padding-h ng-scope"
|
||||
<div layout="row" class="wz-margin-top-16 euiFlexGroup euiFlexGroup--alignItemsCenter euiFormControlLayout__childrenWrapper md-padding-h ng-scope"
|
||||
ng-if="!addingAgents && !file">
|
||||
<input
|
||||
placeholder="{{groupsSelectedTab==='files' ? 'Filter files...' : lookingGroup ? 'Filter agents...' : 'Filter groups...'}}"
|
||||
ng-model="custom_search" type="text"
|
||||
class="euiFieldSearch euiFieldSearch--fullWidth euiFlexItem height-35 ng-empty ng-pristine ng-touched ng-valid"
|
||||
<input placeholder="{{groupsSelectedTab==='files' ? 'Filter files...' : lookingGroup ? 'Filter agents...' : 'Filter groups...'}}"
|
||||
ng-model="custom_search" type="text" class="euiFieldSearch euiFieldSearch--fullWidth euiFlexItem height-35 ng-empty ng-pristine ng-touched ng-valid"
|
||||
aria-invalid="false" wz-enter="search(custom_search)">
|
||||
<div class="euiFormControlLayoutIcons wz-margin-left-16">
|
||||
<span class="euiFormControlLayoutCustomIcon">
|
||||
<react-component name="EuiIcon"
|
||||
props="{type:'search', className:'euiFormControlLayoutCustomIcon__icon'}" />
|
||||
<react-component name="EuiIcon" props="{type:'search', className:'euiFormControlLayoutCustomIcon__icon'}" />
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<button type="submit" aria-label="Search"
|
||||
class="euiFlexItem euiFlexItem--flexGrowZero height-35 kuiButton kuiButton--secondary wz-margin-left-8"
|
||||
<button type="submit" aria-label="Search" class="euiFlexItem euiFlexItem--flexGrowZero height-35 kuiButton kuiButton--secondary wz-margin-left-8"
|
||||
ng-click="search(custom_search)">
|
||||
Search
|
||||
</button>
|
||||
@ -121,30 +107,26 @@
|
||||
class="euiFlexItem euiFlexItem--flexGrowZero height-35 wz-margin-left-8">
|
||||
<div class="euiFilterGroup"></div>
|
||||
</div>
|
||||
<button
|
||||
ng-if="lookingGroup && currentGroup && !addingAgents && !editingFile && !file && adminMode && groupsSelectedTab==='files'"
|
||||
<button ng-if="lookingGroup && currentGroup && !addingAgents && !editingFile && !file && adminMode && groupsSelectedTab==='files'"
|
||||
class="euiFlexItem euiFlexItem--flexGrowZero height-35 kuiButton kuiButton--secondary ng-scope wz-margin-left-8"
|
||||
ng-click="editGroupAgentConfig(currentGroup)" aria-label="Edit group configuration">
|
||||
<svg class="euiIcon euiIcon--medium euiButtonIcon__icon" focusable="false" aria-hidden="true"
|
||||
xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="16"
|
||||
height="16" viewBox="0 0 16 16">
|
||||
<defs>
|
||||
<path id="pencil-a"
|
||||
d="M12.148 3.148L11 2l-9 9v3h3l9-9-1.144-1.144-8.002 7.998a.502.502 0 0 1-.708 0 .502.502 0 0 1 0-.708l8.002-7.998zM11 1c.256 0 .512.098.707.293l3 3a.999.999 0 0 1 0 1.414l-9 9A.997.997 0 0 1 5 15H2a1 1 0 0 1-1-1v-3c0-.265.105-.52.293-.707l9-9A.997.997 0 0 1 11 1zM5 14H2v-3l3 3z">
|
||||
<path id="pencil-a" d="M12.148 3.148L11 2l-9 9v3h3l9-9-1.144-1.144-8.002 7.998a.502.502 0 0 1-.708 0 .502.502 0 0 1 0-.708l8.002-7.998zM11 1c.256 0 .512.098.707.293l3 3a.999.999 0 0 1 0 1.414l-9 9A.997.997 0 0 1 5 15H2a1 1 0 0 1-1-1v-3c0-.265.105-.52.293-.707l9-9A.997.997 0 0 1 11 1zM5 14H2v-3l3 3z">
|
||||
</path>
|
||||
</defs>
|
||||
<use xlink:href="#pencil-a"></use>
|
||||
</svg>
|
||||
Edit group configuration
|
||||
</button>
|
||||
<button
|
||||
ng-if="lookingGroup && currentGroup && !addingAgents && !editingFile && !file && adminMode && groupsSelectedTab==='agents'"
|
||||
<button ng-if="lookingGroup && currentGroup && !addingAgents && !editingFile && !file && adminMode && groupsSelectedTab==='agents'"
|
||||
class="euiFlexItem euiFlexItem--flexGrowZero height-35 kuiButton kuiButton--secondary ng-scope wz-margin-left-8"
|
||||
ng-click="addMultipleAgents(true)" aria-label="Add or remove agents">
|
||||
<svg class="euiIcon euiIcon--medium" focusable="false" xmlns="http://www.w3.org/2000/svg"
|
||||
width="16" height="16" viewBox="0 0 16 16">
|
||||
<path fill-rule="evenodd"
|
||||
d="M8 7h3.5a.5.5 0 1 1 0 1H8v3.5a.5.5 0 1 1-1 0V8H3.5a.5.5 0 0 1 0-1H7V3.5a.5.5 0 0 1 1 0V7zm-.5-7C11.636 0 15 3.364 15 7.5S11.636 15 7.5 15 0 11.636 0 7.5 3.364 0 7.5 0zm0 .882a6.618 6.618 0 1 0 0 13.236A6.618 6.618 0 0 0 7.5.882z">
|
||||
<svg class="euiIcon euiIcon--medium" focusable="false" xmlns="http://www.w3.org/2000/svg" width="16"
|
||||
height="16" viewBox="0 0 16 16">
|
||||
<path fill-rule="evenodd" d="M8 7h3.5a.5.5 0 1 1 0 1H8v3.5a.5.5 0 1 1-1 0V8H3.5a.5.5 0 0 1 0-1H7V3.5a.5.5 0 0 1 1 0V7zm-.5-7C11.636 0 15 3.364 15 7.5S11.636 15 7.5 15 0 11.636 0 7.5 3.364 0 7.5 0zm0 .882a6.618 6.618 0 1 0 0 13.236A6.618 6.618 0 0 0 7.5.882z">
|
||||
</path>
|
||||
</svg>
|
||||
Add or remove agents
|
||||
@ -157,13 +139,12 @@
|
||||
<md-card flex class="wz-md-card _md flex md-margin-h wz-margin-top-16" 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>
|
||||
<div layout="row" layout-align="end center">
|
||||
<button type="button" ng-click="downloadCsv('/agents/groups')"
|
||||
class="euiButtonEmpty euiButtonEmpty--primary euiButtonEmpty--small">
|
||||
<button type="button" ng-click="downloadCsv('/agents/groups')" class="euiButtonEmpty euiButtonEmpty--primary euiButtonEmpty--small">
|
||||
<span class="euiButtonEmpty__content">
|
||||
<react-component name="EuiIcon" props="{type:'importAction'}" />
|
||||
<span class="euiButtonEmpty__text">Formatted</span>
|
||||
@ -176,8 +157,7 @@
|
||||
|
||||
<div ng-if='!addingAgents'>
|
||||
<!-- Group agents table -->
|
||||
<md-card flex class="wz-md-card _md flex md-margin-h wz-margin-top-16"
|
||||
ng-if="lookingGroup && groupsSelectedTab==='agents' && currentGroup">
|
||||
<md-card flex class="wz-md-card _md flex md-margin-h wz-margin-top-16" 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">
|
||||
@ -187,15 +167,13 @@
|
||||
</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>
|
||||
<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 custom-columns="true" 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>
|
||||
<div layout="row" ng-if="lookingGroup && groupsSelectedTab==='agents'">
|
||||
<span flex></span>
|
||||
@ -211,19 +189,16 @@
|
||||
</md-card>
|
||||
|
||||
<!-- Group files table -->
|
||||
<md-card flex class="wz-md-card _md flex md-margin-h wz-margin-top-16"
|
||||
ng-if="lookingGroup && groupsSelectedTab==='files' && !fileViewer && currentGroup">
|
||||
<md-card flex class="wz-md-card _md flex md-margin-h wz-margin-top-16" 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'"
|
||||
keys="[{value:'filename',width:'300px'},'hash']" allow-click="true"
|
||||
row-sizes="[16,14,12]">
|
||||
<wz-table custom-columns="true" extra-limit="100" flex path="'/agents/groups/' + currentGroup.name + '/files'"
|
||||
keys="[{value:'filename',width:'300px'},'hash']" allow-click="true" row-sizes="[16,14,12]">
|
||||
</wz-table>
|
||||
</div>
|
||||
<div layout="row" ng-if="lookingGroup && groupsSelectedTab==='files' && !file">
|
||||
<span flex></span>
|
||||
<button type="button"
|
||||
ng-click="downloadCsv('/agents/groups/' + currentGroup.name + '/files')"
|
||||
<button type="button" ng-click="downloadCsv('/agents/groups/' + currentGroup.name + '/files')"
|
||||
class="euiButtonEmpty euiButtonEmpty--primary euiButtonEmpty--small">
|
||||
<span class="euiButtonEmpty__content">
|
||||
<react-component name="EuiIcon" props="{type:'importAction'}" />
|
||||
@ -240,19 +215,17 @@
|
||||
<!-- 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>
|
||||
@ -260,8 +233,7 @@
|
||||
</div>
|
||||
|
||||
<div layout="row" class="md-padding" ng-if="addingAgents">
|
||||
<span ng-show='!multipleSelectorLoading' class="wzMultipleSelectorCounter"><span
|
||||
style='color:green'>+{{currentAdding}}</span> <span
|
||||
<span ng-show='!multipleSelectorLoading' class="wzMultipleSelectorCounter"><span style='color:green'>+{{currentAdding}}</span> <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"
|
||||
|
@ -20,7 +20,8 @@
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<md-chips class="wz-chips md-padding-h wz-margin-top-16" readonly="true" ng-show="dctrl.appliedFilters.length"
|
||||
<md-chips class="wz-chips md-padding-h wz-margin-top-16" readonly="true" ng-hide="!dctrl.appliedFilters.length ||
|
||||
(dctrl.appliedFilters.length === 1 && dctrl.includesFilter('path') && dctrl.showingLocalDecoders)"
|
||||
ng-if="!dctrl.editingFile">
|
||||
<md-chip class="wz-chip" ng-show="dctrl.includesFilter('file')">
|
||||
<span>File: {{ dctrl.getFilter('file') }}
|
||||
@ -28,7 +29,7 @@
|
||||
ng-click="dctrl.removeFilter('file')"></i>
|
||||
</span>
|
||||
</md-chip>
|
||||
<md-chip class="wz-chip" ng-show="dctrl.includesFilter('path')">
|
||||
<md-chip class="wz-chip" ng-show="dctrl.includesFilter('path') && !dctrl.showingLocalDecoders">
|
||||
<span>Path: {{ dctrl.getFilter('path') }}
|
||||
<i class="fa fa-fw fa-times cursor-pointer" aria-hidden="true"
|
||||
ng-click="dctrl.removeFilter('path')"></i>
|
||||
@ -42,7 +43,7 @@
|
||||
<a ng-if="adminMode" ng-click="mctrl.switchFilesSubTab('decoders')">Manage decoders files</a>
|
||||
<span flex></span>
|
||||
<wz-kbn-switch class="md-primary wz-no-top-bottom-margin" switch-model="dctrl.showingLocalDecoders"
|
||||
switch-text="Custom decoders"></wz-kbn-switch>
|
||||
switch-text="Custom decoders" switch-change="dctrl.switchLocalDecoders()"></wz-kbn-switch>
|
||||
</md-card-actions>
|
||||
<md-card-content class="wz-padding-bottom-0">
|
||||
<wz-table custom-columns="true" ng-if="!dctrl.showingLocalDecoders"
|
||||
@ -52,7 +53,7 @@
|
||||
</wz-table>
|
||||
<wz-table custom-columns="true" ng-if="dctrl.showingLocalDecoders" flex path="'/decoders'"
|
||||
keys="['name',{value:'details.program_name',size:2,nosortable:true},{value:'details.order',size:2,nosortable:true},'file']"
|
||||
implicit-filter="[{ name:'path',value: 'etc/decoders'}]" allow-click="true" row-sizes="[16,13,11]">
|
||||
implicit-filter="dctrl.appliedFilters" allow-click="true" row-sizes="[16,13,11]">
|
||||
</wz-table>
|
||||
</md-card-content>
|
||||
<md-card-actions layout="row" layout-align="end center" class="layout-align-end-center layout-row">
|
||||
|
@ -45,15 +45,15 @@
|
||||
</md-card-actions>
|
||||
<md-card-content>
|
||||
<wz-table ng-if="filesctrl.filesSubTab === 'rules' && mctrl.onlyLocalFiles" flex path="'/rules/files'"
|
||||
implicit-filter="[{name: 'path', value: 'etc/rules'}]" keys="[{value: 'file', width: '75px'}]"
|
||||
implicit-filter="[{name: 'path', value: 'etc/rules'}]" keys="['file']"
|
||||
allow-click="true" row-sizes="[16,13,11]" />
|
||||
<wz-table ng-if="filesctrl.filesSubTab === 'rules' && !mctrl.onlyLocalFiles" flex path="'/rules/files'"
|
||||
keys="[{value: 'file', width: '75px'}]" allow-click="true" row-sizes="[16,13,11]" />
|
||||
keys="['file']" allow-click="true" row-sizes="[16,13,11]" />
|
||||
<wz-table ng-if="filesctrl.filesSubTab === 'decoders' && mctrl.onlyLocalFiles" flex
|
||||
path="'/decoders/files'" implicit-filter="[{name: 'path', value: 'etc/decoders'}]"
|
||||
keys="[{value: 'file', width: '75px'}]" allow-click="true" row-sizes="[16,13,11]" />
|
||||
keys="['file']" allow-click="true" row-sizes="[16,13,11]" />
|
||||
<wz-table ng-if="filesctrl.filesSubTab === 'decoders' && !mctrl.onlyLocalFiles" flex
|
||||
path="'/decoders/files'" keys="[{value: 'file', width: '75px'}]" allow-click="true"
|
||||
path="'/decoders/files'" keys="['file']" allow-click="true"
|
||||
row-sizes="[16,13,11]" />
|
||||
</md-card-content>
|
||||
</md-card>
|
||||
|
@ -22,14 +22,15 @@
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<md-chips class="wz-chips md-padding-h wz-margin-top-16" readonly="true" ng-show="appliedFilters.length"
|
||||
<md-chips class="wz-chips md-padding-h wz-margin-top-16" readonly="true" ng-hide="!appliedFilters.length ||
|
||||
(appliedFilters.length === 1 && includesFilter('path') && mctrl.showingLocalRules)"
|
||||
ng-if="!editingFile && !mctrl.filesSubTab">
|
||||
<md-chip class="wz-chip" ng-show="includesFilter('file')">
|
||||
<span>File: {{getFilter('file')}}
|
||||
<i class="fa fa-fw fa-times cursor-pointer" aria-hidden="true" ng-click="removeFilter('file')"></i>
|
||||
</span>
|
||||
</md-chip>
|
||||
<md-chip class="wz-chip" ng-show="includesFilter('path')">
|
||||
<md-chip class="wz-chip" ng-show="includesFilter('path') && !mctrl.showingLocalRules">
|
||||
<span>Path: {{getFilter('path')}}
|
||||
<i class="fa fa-fw fa-times cursor-pointer" aria-hidden="true" ng-click="removeFilter('path')"></i>
|
||||
</span>
|
||||
@ -63,12 +64,12 @@
|
||||
rules files</a>
|
||||
<span flex></span>
|
||||
<wz-kbn-switch class="md-primary wz-no-top-bottom-margin" switch-model="mctrl.showingLocalRules"
|
||||
switch-text="Custom rules"></wz-kbn-switch>
|
||||
switch-text="Custom rules" switch-change="switchLocalRules()"></wz-kbn-switch>
|
||||
</md-card-actions>
|
||||
<md-card-content class="wz-padding-bottom-0">
|
||||
<wz-table custom-columns="true" flex ng-if="mctrl.showingLocalRules" path="'/rules'"
|
||||
keys="[{value: 'id', width: '85px'},{value:'description', width: 'auto'},{value:'groups',nosortable:true, width: '250px'},{value:'pci',nosortable:true, width: '170px'},{value:'gdpr',nosortable:true,width: '170px'}, {value: 'level', width: '100px'}, {value:'file',width: '200px'}]"
|
||||
implicit-filter="[{ name:'path',value: 'etc/rules'}]" allow-click="true" row-sizes="[16,14,12]">
|
||||
implicit-filter="appliedFilters" allow-click="true" row-sizes="[16,14,12]">
|
||||
</wz-table>
|
||||
<wz-table custom-columns="true" ng-if="!mctrl.showingLocalRules" implicit-filter="appliedFilters" flex
|
||||
path="'/rules'"
|
||||
|
@ -104,7 +104,7 @@
|
||||
<!-- End add API button section -->
|
||||
|
||||
<!-- Add API section-->
|
||||
<div layout="row" ng-show="!currentAPI || (ctrl.addManagerContainer && !ctrl.isEditing)">
|
||||
<div layout="row" ng-show="!currentAPI || (ctrl.addManagerContainer && !ctrl.isEditing) || !ctrl.apiEntries.length">
|
||||
<!-- Add API form -->
|
||||
<form flex ng-submit="ctrl.saveSettings()" layout="column" layout-align="start stretch"
|
||||
class="margin-top-30">
|
||||
|
12677
public/utils/jquery-ui.js
vendored
Normal file
12677
public/utils/jquery-ui.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,511 +0,0 @@
|
||||
/**
|
||||
_ _____ _ _ _
|
||||
| | __ \ (_) | | | |
|
||||
___ ___ | | |__) |___ ___ _ ______ _| |__ | | ___
|
||||
/ __/ _ \| | _ // _ \/ __| |_ / _` | '_ \| |/ _ \
|
||||
| (_| (_) | | | \ \ __/\__ \ |/ / (_| | |_) | | __/
|
||||
\___\___/|_|_| \_\___||___/_/___\__,_|_.__/|_|\___|
|
||||
|
||||
v1.6 - jQuery plugin created by Alvaro Prieto Lauroba
|
||||
|
||||
Licences: MIT & GPL
|
||||
Feel free to use or modify this plugin as far as my full name is kept
|
||||
|
||||
If you are going to use this plug-in in production environments it is
|
||||
strongly recommended to use its minified version: colResizable.min.js
|
||||
|
||||
*/
|
||||
|
||||
(function(global, factory) {
|
||||
typeof exports === 'object' && typeof module !== 'undefined'
|
||||
? (module.exports = factory())
|
||||
: typeof define === 'function' && define.amd
|
||||
? define(factory)
|
||||
: (global.CodeMirror = factory());
|
||||
})(this, function() {
|
||||
'use strict';
|
||||
|
||||
var d = $(document); //window object
|
||||
var h = $('head'); //head object
|
||||
var drag = null; //reference to the current grip that is being dragged
|
||||
var tables = {}; //object of the already processed tables (table.id as key)
|
||||
var count = 0; //internal count to create unique IDs when needed.
|
||||
|
||||
//common strings for packing
|
||||
var ID = 'id';
|
||||
var PX = 'px';
|
||||
var SIGNATURE = 'JColResizer';
|
||||
var FLEX = 'JCLRFlex';
|
||||
|
||||
//short-cuts
|
||||
var I = parseInt;
|
||||
var M = Math;
|
||||
var ie = navigator.userAgent.indexOf('Trident/4.0') > 0;
|
||||
var S;
|
||||
try {
|
||||
S = sessionStorage;
|
||||
} catch (e) {} //Firefox crashes when executed as local file system
|
||||
|
||||
//append required CSS rules
|
||||
h.append(
|
||||
"<style type='text/css'> .JColResizer{table-layout:fixed;} .JColResizer > tbody > tr > td, .JColResizer > tbody > tr > th{overflow:hidden;} .JCLRgrips{ height:0px; position:relative;} .JCLRgrip{margin-left:-5px; position:absolute; z-index:5; } .JCLRgrip .JColResizer{position:absolute;background-color:red;filter:alpha(opacity=1);opacity:0;width:10px;height:100%;cursor: e-resize;top:0px} .JCLRLastGrip{position:absolute; width:1px; } .JCLRgripDrag{ border-left:1px dotted black; } .JCLRFlex{width:auto!important;} .JCLRgrip.JCLRdisabledGrip .JColResizer{cursor:default; display:none;}</style>"
|
||||
);
|
||||
|
||||
/**
|
||||
* Function to allow column resizing for table objects. It is the starting point to apply the plugin.
|
||||
* @param {DOM node} tb - reference to the DOM table object to be enhanced
|
||||
* @param {Object} options - some customization values
|
||||
*/
|
||||
var init = function(tb, options) {
|
||||
var t = $(tb); //the table object is wrapped
|
||||
t.opt = options; //each table has its own options available at anytime
|
||||
t.mode = options.resizeMode; //shortcuts
|
||||
t.dc = t.opt.disabledColumns;
|
||||
if (t.opt.disable) return destroy(t); //the user is asking to destroy a previously colResized table
|
||||
var id = (t.id = t.attr(ID) || SIGNATURE + count++); //its id is obtained, if null new one is generated
|
||||
t.p = t.opt.postbackSafe; //short-cut to detect postback safe
|
||||
if (!t.is('table') || (tables[id] && !t.opt.partialRefresh)) return; //if the object is not a table or if it was already processed then it is ignored.
|
||||
if (t.opt.hoverCursor !== 'e-resize')
|
||||
h.append(
|
||||
"<style type='text/css'>.JCLRgrip .JColResizer:hover{cursor:" +
|
||||
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
|
||||
t.g = [];
|
||||
t.c = [];
|
||||
t.w = t.width();
|
||||
t.gc = t.prev();
|
||||
t.f = t.opt.fixed; //t.c and t.g are arrays of columns and grips respectively
|
||||
if (options.marginLeft) t.gc.css('marginLeft', options.marginLeft); //if the table contains margins, it must be specified
|
||||
if (options.marginRight) t.gc.css('marginRight', options.marginRight); //since there is no (direct) way to obtain margin values in its original units (%, em, ...)
|
||||
t.cs =
|
||||
I(
|
||||
ie
|
||||
? tb.cellSpacing || tb.currentStyle.borderSpacing
|
||||
: t.css('border-spacing')
|
||||
) || 2; //table cellspacing (not even jQuery is fully cross-browser)
|
||||
t.b =
|
||||
I(
|
||||
ie
|
||||
? tb.border || tb.currentStyle.borderLeftWidth
|
||||
: t.css('border-left-width')
|
||||
) || 1; //outer border width (again cross-browser issues)
|
||||
// if(!(tb.style.width || tb.width)) t.width(t.width()); //I am not an IE fan at all, but it is a pity that only IE has the currentStyle attribute working as expected. For this reason I can not check easily if the table has an explicit width or if it is rendered as "auto"
|
||||
tables[id] = t; //the table object is stored using its id as key
|
||||
createGrips(t); //grips are created
|
||||
};
|
||||
|
||||
/**
|
||||
* This function allows to remove any enhancements performed by this plugin on a previously processed table.
|
||||
* @param {jQuery ref} t - table object
|
||||
*/
|
||||
var destroy = function(t) {
|
||||
var id = t.attr(ID),
|
||||
t = tables[id]; //its table object is found
|
||||
if (!t || !t.is('table')) return; //if none, then it wasn't processed
|
||||
t.removeClass(SIGNATURE + ' ' + FLEX).gc.remove(); //class and grips are removed
|
||||
delete tables[id]; //clean up data
|
||||
};
|
||||
|
||||
/**
|
||||
* Function to create all the grips associated with the table given by parameters
|
||||
* @param {jQuery ref} t - table object
|
||||
*/
|
||||
var createGrips = function(t) {
|
||||
var th = t.find('>thead>tr:first>th,>thead>tr:first>td'); //table headers are obtained
|
||||
if (!th.length)
|
||||
th = t.find(
|
||||
'>tbody>tr:first>th,>tr:first>th,>tbody>tr:first>td, >tr:first>td'
|
||||
); //but headers can also be included in different ways
|
||||
th = th.filter(':visible'); //filter invisible columns
|
||||
t.cg = t.find('col'); //a table can also contain a colgroup with col elements
|
||||
t.ln = th.length; //table length is stored
|
||||
if (t.p && S && S[t.id]) memento(t, th); //if 'postbackSafe' is enabled and there is data for the current table, its coloumn layout is restored
|
||||
th.each(function(i) {
|
||||
//iterate through the table column headers
|
||||
var c = $(this); //jquery wrap for the current column
|
||||
var dc = t.dc.indexOf(i) != -1; //is this a disabled column?
|
||||
var g = $(t.gc.append('<div class="JCLRgrip"></div>')[0].lastChild); //add the visual node to be used as grip
|
||||
g.append(dc ? '' : t.opt.gripInnerHtml).append(
|
||||
'<div class="' + SIGNATURE + '"></div>'
|
||||
);
|
||||
if (i == t.ln - 1) {
|
||||
//if the current grip is the las one
|
||||
g.addClass('JCLRLastGrip'); //add a different css class to stlye it in a different way if needed
|
||||
if (t.f) g.html(''); //if the table resizing mode is set to fixed, the last grip is removed since table with can not change
|
||||
}
|
||||
g.bind('touchstart mousedown', onGripMouseDown); //bind the mousedown event to start dragging
|
||||
|
||||
if (!dc) {
|
||||
//if normal column bind the mousedown event to start dragging, if disabled then apply its css class
|
||||
g.removeClass('JCLRdisabledGrip').bind(
|
||||
'touchstart mousedown',
|
||||
onGripMouseDown
|
||||
);
|
||||
} else {
|
||||
g.addClass('JCLRdisabledGrip');
|
||||
}
|
||||
|
||||
g.t = t;
|
||||
g.i = i;
|
||||
g.c = c;
|
||||
c.w = c.width(); //some values are stored in the grip's node data as shortcut
|
||||
t.g.push(g);
|
||||
t.c.push(c); //the current grip and column are added to its table object
|
||||
c.width(c.w).removeAttr('width'); //the width of the column is converted into pixel-based measurements
|
||||
g.data(SIGNATURE, { i: i, t: t.attr(ID), last: i == t.ln - 1 }); //grip index and its table name are stored in the HTML
|
||||
});
|
||||
t.cg.removeAttr('width'); //remove the width attribute from elements in the colgroup
|
||||
|
||||
t.find('td, th')
|
||||
.not(th)
|
||||
.not('table th, table td')
|
||||
.each(function() {
|
||||
$(this).removeAttr('width'); //the width attribute is removed from all table cells which are not nested in other tables and dont belong to the header
|
||||
});
|
||||
if (!t.f) {
|
||||
t.removeAttr('width').addClass(FLEX); //if not fixed, let the table grow as needed
|
||||
}
|
||||
syncGrips(t); //the grips are positioned according to the current table layout
|
||||
//there is a small problem, some cells in the table could contain dimension values interfering with the
|
||||
//width value set by this plugin. Those values are removed
|
||||
};
|
||||
|
||||
/**
|
||||
* Function to allow the persistence of columns dimensions after a browser postback. It is based in
|
||||
* the HTML5 sessionStorage object, which can be emulated for older browsers using sessionstorage.js
|
||||
* @param {jQuery ref} t - table object
|
||||
* @param {jQuery ref} th - reference to the first row elements (only set in deserialization)
|
||||
*/
|
||||
var memento = function(t, th) {
|
||||
var w,
|
||||
m = 0,
|
||||
i = 0,
|
||||
aux = [],
|
||||
tw;
|
||||
if (th) {
|
||||
//in deserialization mode (after a postback)
|
||||
t.cg.removeAttr('width');
|
||||
if (t.opt.flush) {
|
||||
S[t.id] = '';
|
||||
return;
|
||||
} //if flush is activated, stored data is removed
|
||||
w = S[t.id].split(';'); //column widths is obtained
|
||||
tw = w[t.ln + 1];
|
||||
if (!t.f && tw) {
|
||||
//if not fixed and table width data available its size is restored
|
||||
t.width((tw *= 1));
|
||||
if (t.opt.overflow) {
|
||||
//if overfolw flag is set, restore table width also as table min-width
|
||||
t.css('min-width', tw + PX);
|
||||
t.w = tw;
|
||||
}
|
||||
}
|
||||
for (; i < t.ln; i++) {
|
||||
//for each column
|
||||
aux.push((100 * w[i]) / w[t.ln] + '%'); //width is stored in an array since it will be required again a couple of lines ahead
|
||||
th.eq(i).css('width', aux[i]); //each column width in % is restored
|
||||
}
|
||||
for (i = 0; i < t.ln; i++) t.cg.eq(i).css('width', aux[i]); //this code is required in order to create an inline CSS rule with higher precedence than an existing CSS class in the "col" elements
|
||||
} else {
|
||||
//in serialization mode (after resizing a column)
|
||||
S[t.id] = ''; //clean up previous data
|
||||
for (; i < t.c.length; i++) {
|
||||
//iterate through columns
|
||||
w = t.c[i].width(); //width is obtained
|
||||
S[t.id] += w + ';'; //width is appended to the sessionStorage object using ID as key
|
||||
m += w; //carriage is updated to obtain the full size used by columns
|
||||
}
|
||||
S[t.id] += m; //the last item of the serialized string is the table's active area (width),
|
||||
//to be able to obtain % width value of each columns while deserializing
|
||||
if (!t.f) S[t.id] += ';' + t.width(); //if not fixed, table width is stored
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Function that places each grip in the correct position according to the current table layout
|
||||
* @param {jQuery ref} t - table object
|
||||
*/
|
||||
var syncGrips = function(t) {
|
||||
t.gc.width(t.w); //the grip's container width is updated
|
||||
for (var i = 0; i < t.ln; i++) {
|
||||
//for each column
|
||||
var c = t.c[i];
|
||||
t.g[i].css({
|
||||
//height and position of the grip is updated according to the table layout
|
||||
left:
|
||||
c.offset().left -
|
||||
t.offset().left +
|
||||
c.outerWidth(false) +
|
||||
t.cs / 2 +
|
||||
PX,
|
||||
height: t.opt.headerOnly
|
||||
? t.c[0].outerHeight(false)
|
||||
: t.outerHeight(false)
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* This function updates column's width according to the horizontal position increment of the grip being
|
||||
* dragged. The function can be called while dragging if liveDragging is enabled and also from the onGripDragOver
|
||||
* event handler to synchronize grip's position with their related columns.
|
||||
* @param {jQuery ref} t - table object
|
||||
* @param {number} i - index of the grip being dragged
|
||||
* @param {bool} isOver - to identify when the function is being called from the onGripDragOver event
|
||||
*/
|
||||
var syncCols = function(t, i, isOver) {
|
||||
var inc = drag.x - drag.l,
|
||||
c = t.c[i],
|
||||
c2 = t.c[i + 1];
|
||||
var w = c.w + inc;
|
||||
var w2 = c2.w - inc; //their new width is obtained
|
||||
c.width(w + PX);
|
||||
t.cg.eq(i).width(w + PX);
|
||||
if (t.f) {
|
||||
//if fixed mode
|
||||
c2.width(w2 + PX);
|
||||
t.cg.eq(i + 1).width(w2 + PX);
|
||||
} else if (t.opt.overflow) {
|
||||
//if overflow is set, incriment min-width to force overflow
|
||||
t.css('min-width', t.w + inc);
|
||||
}
|
||||
if (isOver) {
|
||||
c.w = w;
|
||||
c2.w = t.f ? w2 : c2.w;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* This function updates all columns width according to its real width. It must be taken into account that the
|
||||
* sum of all columns can exceed the table width in some cases (if fixed is set to false and table has some kind
|
||||
* of max-width).
|
||||
* @param {jQuery ref} t - table object
|
||||
*/
|
||||
var applyBounds = function(t) {
|
||||
var w = $.map(t.c, function(c) {
|
||||
//obtain real widths
|
||||
return c.width();
|
||||
});
|
||||
t.width((t.w = t.width())).removeClass(FLEX); //prevent table width changes
|
||||
$.each(t.c, function(i, c) {
|
||||
c.width(w[i]).w = w[i]; //set column widths applying bounds (table's max-width)
|
||||
});
|
||||
t.addClass(FLEX); //allow table width changes
|
||||
};
|
||||
|
||||
/**
|
||||
* Event handler used while dragging a grip. It checks if the next grip's position is valid and updates it.
|
||||
* @param {event} e - mousemove event binded to the window object
|
||||
*/
|
||||
var onGripDrag = function(e) {
|
||||
if (!drag) return;
|
||||
var t = drag.t; //table object reference
|
||||
var oe = e.originalEvent.touches;
|
||||
var ox = oe ? oe[0].pageX : e.pageX; //original position (touch or mouse)
|
||||
var x = ox - drag.ox + drag.l; //next position according to horizontal mouse position increment
|
||||
var mw = t.opt.minWidth,
|
||||
i = drag.i; //cell's min width
|
||||
var l = t.cs * 1.5 + mw + t.b;
|
||||
var last = i == t.ln - 1; //check if it is the last column's grip (usually hidden)
|
||||
var min = i ? t.g[i - 1].position().left + t.cs + mw : l; //min position according to the contiguous cells
|
||||
var max = t.f //fixed mode?
|
||||
? i == t.ln - 1
|
||||
? t.w - l
|
||||
: t.g[i + 1].position().left - t.cs - mw
|
||||
: Infinity; //max position according to the contiguous cells
|
||||
x = M.max(min, M.min(max, x)); //apply bounding
|
||||
drag.x = x;
|
||||
drag.css('left', x + PX); //apply position increment
|
||||
if (last) {
|
||||
//if it is the last grip
|
||||
var c = t.c[drag.i]; //width of the last column is obtained
|
||||
drag.w = c.w + x - drag.l;
|
||||
}
|
||||
if (t.opt.liveDrag) {
|
||||
//if liveDrag is enabled
|
||||
if (last) {
|
||||
c.width(drag.w);
|
||||
if (!t.f && t.opt.overflow) {
|
||||
//if overflow is set, incriment min-width to force overflow
|
||||
t.css('min-width', t.w + x - drag.l);
|
||||
} else {
|
||||
t.w = t.width();
|
||||
}
|
||||
} else {
|
||||
syncCols(t, i); //columns are synchronized
|
||||
}
|
||||
syncGrips(t);
|
||||
var cb = t.opt.onDrag; //check if there is an onDrag callback
|
||||
if (cb) {
|
||||
e.currentTarget = t[0];
|
||||
cb(e);
|
||||
} //if any, it is fired
|
||||
}
|
||||
return false; //prevent text selection while dragging
|
||||
};
|
||||
|
||||
/**
|
||||
* Event handler fired when the dragging is over, updating table layout
|
||||
* @param {event} e - grip's drag over event
|
||||
*/
|
||||
var onGripDragOver = function(e) {
|
||||
d.unbind('touchend.' + SIGNATURE + ' mouseup.' + SIGNATURE).unbind(
|
||||
'touchmove.' + SIGNATURE + ' mousemove.' + SIGNATURE
|
||||
);
|
||||
$('head :last-child').remove(); //remove the dragging cursor style
|
||||
if (!drag) return;
|
||||
drag.removeClass(drag.t.opt.draggingClass); //remove the grip's dragging css-class
|
||||
if (!(drag.x - drag.l == 0)) {
|
||||
var t = drag.t;
|
||||
var cb = t.opt.onResize; //get some values
|
||||
var i = drag.i; //column index
|
||||
var last = i == t.ln - 1; //check if it is the last column's grip (usually hidden)
|
||||
var c = t.g[i].c; //the column being dragged
|
||||
if (last) {
|
||||
c.width(drag.w);
|
||||
c.w = drag.w;
|
||||
} else {
|
||||
syncCols(t, i, true); //the columns are updated
|
||||
}
|
||||
if (!t.f) applyBounds(t); //if not fixed mode, then apply bounds to obtain real width values
|
||||
syncGrips(t); //the grips are updated
|
||||
if (cb) {
|
||||
e.currentTarget = t[0];
|
||||
cb(e);
|
||||
} //if there is a callback function, it is fired
|
||||
if (t.p && S) memento(t); //if postbackSafe is enabled and there is sessionStorage support, the new layout is serialized and stored
|
||||
}
|
||||
drag = null; //since the grip's dragging is over
|
||||
};
|
||||
|
||||
/**
|
||||
* Event handler fired when the grip's dragging is about to start. Its main goal is to set up events
|
||||
* and store some values used while dragging.
|
||||
* @param {event} e - grip's mousedown event
|
||||
*/
|
||||
var onGripMouseDown = function(e) {
|
||||
var o = $(this).data(SIGNATURE); //retrieve grip's data
|
||||
var t = tables[o.t],
|
||||
g = t.g[o.i]; //shortcuts for the table and grip objects
|
||||
var oe = e.originalEvent.touches; //touch or mouse event?
|
||||
g.ox = oe ? oe[0].pageX : e.pageX; //the initial position is kept
|
||||
g.l = g.position().left;
|
||||
g.x = g.l;
|
||||
|
||||
d.bind(
|
||||
'touchmove.' + SIGNATURE + ' mousemove.' + SIGNATURE,
|
||||
onGripDrag
|
||||
).bind('touchend.' + SIGNATURE + ' mouseup.' + SIGNATURE, onGripDragOver); //mousemove and mouseup events are bound
|
||||
h.append(
|
||||
"<style type='text/css'>*{cursor:" +
|
||||
t.opt.dragCursor +
|
||||
'!important}</style>'
|
||||
); //change the mouse cursor
|
||||
g.addClass(t.opt.draggingClass); //add the dragging class (to allow some visual feedback)
|
||||
drag = g; //the current grip is stored as the current dragging object
|
||||
if (t.c[o.i].l)
|
||||
for (var i = 0, c; i < t.ln; i++) {
|
||||
c = t.c[i];
|
||||
c.l = false;
|
||||
c.w = c.width();
|
||||
} //if the colum is locked (after browser resize), then c.w must be updated
|
||||
return false; //prevent text selection
|
||||
};
|
||||
|
||||
/**
|
||||
* Event handler fired when the browser is resized. The main purpose of this function is to update
|
||||
* table layout according to the browser's size synchronizing related grips
|
||||
*/
|
||||
var onResize = function() {
|
||||
for (var t in tables) {
|
||||
if (tables.hasOwnProperty(t)) {
|
||||
t = tables[t];
|
||||
var i,
|
||||
mw = 0;
|
||||
t.removeClass(SIGNATURE); //firefox doesn't like layout-fixed in some cases
|
||||
if (t.f) {
|
||||
//in fixed mode
|
||||
t.w = t.width(); //its new width is kept
|
||||
for (i = 0; i < t.ln; i++) mw += t.c[i].w;
|
||||
//cell rendering is not as trivial as it might seem, and it is slightly different for
|
||||
//each browser. In the beginning i had a big switch for each browser, but since the code
|
||||
//was extremely ugly now I use a different approach with several re-flows. This works
|
||||
//pretty well but it's a bit slower. For now, lets keep things simple...
|
||||
for (i = 0; i < t.ln; i++)
|
||||
t.c[i].css(
|
||||
'width',
|
||||
M.round((1000 * t.c[i].w) / mw) / 10 + '%'
|
||||
).l = true;
|
||||
//c.l locks the column, telling us that its c.w is outdated
|
||||
} else {
|
||||
//in non fixed-sized tables
|
||||
applyBounds(t); //apply the new bounds
|
||||
if (t.mode == 'flex' && t.p && S) {
|
||||
//if postbackSafe is enabled and there is sessionStorage support,
|
||||
memento(t); //the new layout is serialized and stored for 'flex' tables
|
||||
}
|
||||
}
|
||||
syncGrips(t.addClass(SIGNATURE));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//bind resize event, to update grips position
|
||||
$(window).bind('resize.' + SIGNATURE, onResize);
|
||||
|
||||
/**
|
||||
* The plugin is added to the jQuery library
|
||||
* @param {Object} options - an object that holds some basic customization values
|
||||
*/
|
||||
$.fn.extend({
|
||||
colResizable: function(options) {
|
||||
var defaults = {
|
||||
//attributes:
|
||||
|
||||
resizeMode: 'fit', //mode can be 'fit', 'flex' or 'overflow'
|
||||
draggingClass: 'JCLRgripDrag', //css-class used when a grip is being dragged (for visual feedback purposes)
|
||||
gripInnerHtml: '', //if it is required to use a custom grip it can be done using some custom HTML
|
||||
liveDrag: false, //enables table-layout updating while dragging
|
||||
minWidth: 15, //minimum width value in pixels allowed for a column
|
||||
headerOnly: false, //specifies that the size of the the column resizing anchors will be bounded to the size of the first row
|
||||
hoverCursor: 'e-resize', //cursor to be used on grip hover
|
||||
dragCursor: 'e-resize', //cursor to be used while dragging
|
||||
postbackSafe: false, //when it is enabled, table layout can persist after postback or page refresh. It requires browsers with sessionStorage support (it can be emulated with sessionStorage.js).
|
||||
flush: false, //when postbakSafe is enabled, and it is required to prevent layout restoration after postback, 'flush' will remove its associated layout data
|
||||
marginLeft: null, //in case the table contains any margins, colResizable needs to know the values used, e.g. "10%", "15em", "5px" ...
|
||||
marginRight: null, //in case the table contains any margins, colResizable needs to know the values used, e.g. "10%", "15em", "5px" ...
|
||||
disable: false, //disables all the enhancements performed in a previously colResized table
|
||||
partialRefresh: false, //can be used in combination with postbackSafe when the table is inside of an updatePanel,
|
||||
disabledColumns: [], //column indexes to be excluded
|
||||
|
||||
//events:
|
||||
onDrag: null, //callback function to be fired during the column resizing process if liveDrag is enabled
|
||||
onResize: null //callback function fired when the dragging process is over
|
||||
};
|
||||
var options = $.extend(defaults, options);
|
||||
|
||||
//since now there are 3 different ways of resizing columns, I changed the external interface to make it clear
|
||||
//calling it 'resizeMode' but also to remove the "fixed" attribute which was confusing for many people
|
||||
options.fixed = true;
|
||||
options.overflow = false;
|
||||
switch (options.resizeMode) {
|
||||
case 'flex':
|
||||
options.fixed = false;
|
||||
break;
|
||||
case 'overflow':
|
||||
options.fixed = false;
|
||||
options.overflow = true;
|
||||
break;
|
||||
}
|
||||
|
||||
return this.each(function() {
|
||||
init(this, options);
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
Loading…
Reference in New Issue
Block a user