strolch-wc-inspector/strolch-wc-inspector-object...

532 lines
21 KiB
HTML

<link rel="import" href="../polymer/polymer.html">
<link rel="import" href="../paper-toolbar/paper-toolbar.html">
<link rel="import" href="../paper-input/paper-input.html">
<link rel="import" href="../paper-dialog/paper-dialog.html">
<link rel="import" href="../paper-button/paper-button.html">
<link rel="import" href="../paper-badge/paper-badge.html">
<link rel="import" href="../paper-icon-button/paper-icon-button.html">
<link rel="import" href="../iron-ajax/iron-ajax.html">
<link rel="import" href="../iron-icon/iron-icon.html">
<link rel="import" href="../iron-pages/iron-pages.html">
<link rel="import" href="../iron-icon/iron-icon.html">
<link rel="import" href="../iron-icons/communication-icons.html">
<link rel="import" href="../strolch-wc-styles/strolch-wc-styles.html">
<link rel="import" href="strolch-wc-inspector-behavior.html">
<link rel="import" href="strolch-wc-inspector-paging-behavior.html">
<link rel="import" href="strolch-wc-inspector-object.html">
<dom-module id="strolch-wc-inspector-objects">
<template>
<style is="custom-style" include="strolch-wc-styles">
:host {
display: block;
margin: 0;
padding: 0;
height: 100%;
--focus-color: white;
--regular-color: lightgrey;
--disabled-color: darkgrey;
}
.title {
margin-top: 2em;
font-weight: bold;
font-size: 1rem;
}
.card {
background-color: #ffffff;
cursor: pointer;
border-style: none;
}
.toolbar {
background-color: var(--paper-blue-900);
color: rgba(255, 255, 255, 0.8);
height: 42px;
padding-left: 20px;
}
.toolbar-title {
line-height: 42px;
}
paper-input {
--paper-input-container: {
padding-top: 12px;
};
--paper-input-container-color: var(--regular-color);
--paper-input-container-focus-color: var(--focus-color);
--paper-input-container-input-color: var(--focus-color);
--paper-input-container-input: {
font-size: 18px;
};
--paper-input-container-underline-disabled: {
border-bottom-style: solid;
}
}
paper-input::shadow input::-ms-clear {
display: none;
width: 0;
height: 0;
}
paper-input:not([focused]) iron-icon {
color: var(--regular-color);
}
paper-input[focused] iron-icon {
color: var(--focus-color);
}
.toolbar-icon {
margin-top: 4px;
}
#clear {
cursor: pointer;
}
.card-export-btn {
background-color: #faa193;
}
</style>
<template is="dom-if" if="[[_noElements(objectSummaries)]]" restamp>
<p class="title g-center">No [[objectType]] objects exists.</p>
</template>
<template is="dom-if" if="[[!_noElements(objectSummaries)]]" restamp>
<iron-pages selected="{{section}}" attr-for-selected="name">
<section name="typesSummary" class="g-pt-4">
<div class="g-row">
<div class="g-offset-4 g-4">
<paper-material class="card card-export-btn g-m-2 g-p-4"
elevation="1"
on-tap="onExportTapped">
<iron-icon icon="cloud-download"></iron-icon>
Export
</paper-material>
</div>
</div>
<template is="dom-repeat" items="[[objectSummaries.types]]">
<div class="g-row">
<div class="g-offset-4 g-4">
<paper-material class="card g-m-2 g-p-4" elevation="1" on-tap="_showTypeDetails">
<p class="g-mb-0">[[objectType]] of type <b>[[item.type]]</b> ([[item.size]])</p>
</paper-material>
</div>
</div>
</template>
</section>
<section name="typeDetails">
<div class="g-row toolbar">
<div class="g-1" on-tap="_closeTypeDetails">
<paper-icon-button icon="arrow-back"></paper-icon-button>
</div>
<div class="g-7">
<span class="toolbar-title">[[selectedType]] types</span>
</div>
<div class="g-3">
<paper-input no-label-float value="{{searchTerm}}" class="searchField">
<template is="dom-if" if="[[isEmptyString(searchTerm)]]">
<iron-icon suffix icon="search"></iron-icon>
</template>
<template is="dom-if" if="[[!isEmptyString(searchTerm)]]">
<iron-icon suffix icon="clear" id="clear" on-tap="onClearTapped"></iron-icon>
</template>
</paper-input>
</div>
<div class="g-1">
<paper-icon-button class="toolbar-icon"
icon="cloud-download"
title="Download queried elements"
on-tap="onExportQueriedElements"></paper-icon-button>
</div>
</div>
<div class="g-row">
<div class="g-12">
<template is="dom-repeat" items="[[dataObj.data]]">
<strolch-wc-inspector-object class="g-ml-3 g-mr-3 g-mt-4"
base-path="[[basePath]]"
realm="[[realm]]"
is-root-element="true"
on-strolch-wc-obj-remove="onRemoveElement"
on-strolch-element-selected="onElementSelected"
object="[[item]]"></strolch-wc-inspector-object>
</template>
</div>
</div>
<div class="g-row g-mt-3 g-mb-1">
<div class="g-3 g-pt-3 g-pl-4">
<paper-button on-tap="_toggleAllSelected" raised>
<template is="dom-if" if="[[allSelected]]">Select None</template>
<template is="dom-if" if="[[!allSelected]]">Select All</template>
</paper-button>
<paper-button on-tap="_removeSelected" raised>Remove
<paper-badge label="[[selectedObjectIds.length]]"></paper-badge>
</paper-button>
</div>
<div class="g-6">
<div class="g-m-2 g-center">
<paper-icon-button icon="first-page" on-tap="_toFirstPage"></paper-icon-button>
<paper-icon-button icon="chevron-left" on-tap="_toPreviousPage"></paper-icon-button>
<span>[[dataObj.offset]] to [[_getEnd(dataObj)]] of [[dataObj.size]] ([[dataObj.dataSetSize]])</span>
<paper-icon-button icon="chevron-right" on-tap="_toNextPage"></paper-icon-button>
<paper-icon-button icon="last-page" on-tap="_toLastPage"></paper-icon-button>
</div>
</div>
<div class="g-3">
<paper-button on-tap="_setLimit">10</paper-button>
<paper-button on-tap="_setLimit">50</paper-button>
<paper-button on-tap="_setLimit">100</paper-button>
</div>
</div>
</section>
</iron-pages>
</template>
<iron-ajax id="ajax"
content-type="application/json"
handle-as="json"
on-response="_handleAjaxResponse"
on-error="onAjaxError"></iron-ajax>
<iron-ajax id="ajaxXml"
content-type="application/xml"
handle-as="text"
method="GET"
on-response="_handleAjaxResponse"
on-error="onAjaxError"></iron-ajax>
</template>
<script>
Polymer({
is: 'strolch-wc-inspector-objects',
behaviors: [
StrolchInspectorBehavior,
StrolchInspectorPagingBehavior
],
properties: {
realm: {
type: String,
value: function () {
return null;
}
},
searchTerm: {
type: String,
observer: "observeSearchTerm",
value: function () {
return "";
}
},
objectType: {
type: String,
value: function () {
return null;
}
},
objectSummaries: {
type: Object,
value: function () {
return null;
},
observer: "_objectSummariesChanged"
},
section: {
type: String,
value: function () {
return 'typesSummary';
}
},
selectedType: {
type: String,
value: function () {
return null;
}
},
allSelected: {
type: Boolean,
value: false
},
selectedObjectIds: {
type: Array,
value: []
},
importType: {
type: String,
value: 'import'
},
modelType: {
type: String,
value: function () {
return 'xml';
}
}
},
isEmptyString: function (s) {
return s == null || s.length == 0;
},
onClearTapped: function (event) {
this.set("searchTerm", "");
},
observeSearchTerm: function (newValue, oldValue) {
if (this.realm == null || this.objectType == null || this.selectedType == null) {
return;
}
this.debounce("doSearch", function () {
this.dataObj.offset = 0;
this.queryPage();
}, 500);
},
_objectSummariesChanged: function (newValue, oldValue) {
this.selectedType = null;
this.section = 'typesSummary';
this.selectedType = null;
this.dataObj.data = null;
},
_noElements: function (objectSummaries) {
return objectSummaries == null || objectSummaries.types.length == 0;
},
_showTypeDetails: function (evt) {
this.dataObj.offset = 0;
this.selectType(evt.model.item.type);
},
selectType: function (type) {
var typeChanged = this.selectedType != type;
this.selectedType = type;
this.section = type == null ? 'typesSummary' : 'typeDetails';
this.dataObj.data = null;
console.log('Showing type ' + this.selectedType);
Strolch.setQueryParamValue('type', this.selectedType);
if (this.selectedType == null) {
this.dataObj.offset = 0;
} else {
if (typeChanged) {
this.dataObj.offset = 0;
}
this.queryPage();
}
},
_closeTypeDetails: function () {
this.section = 'typesSummary';
this.selectedType = null;
this.dataObj.data = null;
Strolch.setQueryParamValue('type', null);
},
_typeSubPath: function (selectedType) {
if (selectedType == 'Resource') {
return 'resources';
} else if (selectedType == 'Order') {
return 'orders';
} else if (selectedType == 'Activity') {
return 'activities';
} else {
throw 'Unhandled selected type ' + selectedType;
}
},
onImportTapped: function (event) {
this.set('importDlgTitle', 'Import Elements as XML');
this.importType = 'import';
this.addDlgOpen = true;
},
onExportTapped: function (event) {
this.dlgTitle = 'Export failed';
this._handleAjaxResponse = function (data) {
var response = data.detail.response;
var fileName = this.realm + '_' + this.objectType + '_' + Strolch.toDateTimeNoDelim(new Date()) + '.xml';
Strolch.handleAjaxFileDownload(response, fileName, 'application/xml');
};
this.$.ajaxXml.url = this.basePath + 'rest/strolch/inspector/' + this.realm + '/' + this._typeSubPath(this.objectType) + '/xml';
this.$.ajaxXml.headers = {'Accept': 'application/xml'};
this.$.ajaxXml.method = 'GET';
this.$.ajaxXml.generateRequest();
},
onExportQueriedElements: function (event) {
this.dlgTitle = 'Export failed';
this._handleAjaxResponse = function (data) {
var response = data.detail.response;
var fileName = this.realm + '_' + this.objectType + '_' + this.selectedType + '_' + Strolch.toDateTimeNoDelim(new Date()) + '.xml';
Strolch.handleAjaxFileDownload(response, fileName, 'application/xml');
};
var url = this.basePath + 'rest/strolch/inspector/' + this.realm + '/' + this._typeSubPath(this.objectType) + '/' + this.selectedType + '/xml';
url += '?query=' + this.searchTerm;
this.$.ajaxXml.url = url;
this.$.ajaxXml.headers = {'Accept': 'application/xml'};
this.$.ajaxXml.method = 'GET';
this.$.ajaxXml.generateRequest();
},
_toggleAllSelected: function (evt) {
var select = !this.allSelected;
console.log(select ? 'Selecting ALL' : 'Selecting NONE');
this.set('selectedObjectIds', []);
for (var i = 0; i < this.dataObj.data.length; i++) {
var path = 'dataObj.data.' + i + '._checked';
this.set(path, !select);
this.set(path, select);
console.log('Set path ' + path + ' = ' + select);
if (select) {
var object = this.dataObj.data[i];
this.push('selectedObjectIds', object.id);
console.log('Added ' + object.id + ' as selected');
}
}
this.set('allSelected', select);
},
onElementSelected: function (evt) {
var index = this.selectedObjectIds.indexOf(evt.detail.object.id);
var selected = evt.detail.object._checked;
console.log('Element ' + evt.detail.object.id + ' is ' + (selected ? 'selected' : 'not selected') + ' and its index is ' + index);
if (selected) {
if (index < 0) {
this.push('selectedObjectIds', evt.detail.object.id);
console.log('Added ' + evt.detail.object.id + ' as selected');
}
} else {
if (index >= 0) {
this.splice('selectedObjectIds', index, 1);
console.log('Removed ' + evt.detail.object.id + ' from selected');
}
}
this.set('allSelected', this.selectedObjectIds.length == this.dataObj.data.length);
console.log(this.allSelected ? 'All are selected' : 'None or some are selected');
},
onRemoveElement: function (event) {
console.log("Delete element " + event.detail.object.id);
var id = event.detail.object.id;
var index = null;
for (var i = 0; i < this.dataObj.data.length; i++) {
if (this.dataObj.data[i].id == id) {
index = i;
break;
}
}
if (index != null) {
this.splice("dataObj.data", index, 1);
}
},
queryPage: function () {
this.dlgTitle = 'Reload failed';
this._handleAjaxResponse = function (data) {
this.set('dataObj', data.detail.response);
};
var url = this.basePath + 'rest/strolch/inspector/' + this.realm + '/' + this._typeSubPath(this.objectType) + '/' + this.selectedType;
url += '?offset=' + this.dataObj.offset + '&limit=' + this.dataObj.limit + "&orderBy=id&query=" + encodeURIComponent(this.searchTerm) + '&overview=true';
this.$.ajax.url = url;
this.$.ajax.method = 'GET';
this.$.ajax.handleAs = 'json';
this.$.ajax.headers = {
'Accept': 'application/json'
};
this.$.ajax.contentType = 'application/json';
this.$.ajax.generateRequest();
},
ready: function () {
},
show: function () {
Strolch.setQueryParamValue('type', this.selectedType);
},
_handleAjaxResponse: function (evt) {
console.log('NOT YET DEFINED!');
},
_removeSelected: function (evt) {
if (!confirm('Do you really want to delete ' + this.selectedObjectIds.length + ' ' + this.selectedType + ' ' + this.objectType + ' elements?')) {
return;
}
this.dlgTitle = 'Remove elements failed';
this._handleAjaxResponse = function (data) {
this.set('this.dataObj.data = null;.data', null);
this.set('selectedObjectIds', []);
this.set('allSelected', false);
this.queryPage();
};
this.$.ajax.url = this.basePath + 'rest/strolch/inspector/' + this.realm + '/' + this._typeSubPath(this.objectType) + '/' + this.selectedType;
this.$.ajax.params = {
ids: ''
};
for (var i = 0; i < this.selectedObjectIds.length; i++) {
this.$.ajax.params.ids += this.selectedObjectIds[i];
if (i < this.selectedObjectIds.length - 1) {
this.$.ajax.params.ids += ',';
}
}
this.$.ajax.handleAs = 'text';
this.$.ajax.headers = {
'Accept': 'application/json'
};
this.$.ajax.method = 'DELETE';
this.$.ajax.generateRequest();
}
});
</script>
</dom-module>