|
|
@@ -575,7 +575,7 @@ global['P5UI__TableAjaxSpecialFilter'] = createReactClass({
|
|
|
|
|
|
getStateFromStore: function () {
|
|
|
var state = this.props.store.getState();
|
|
|
- DBG && console.log('DBG::P5UI__TableAjaxSpecialFilters::getStateFromStore (name:'+this.props.name+')', { store: state, name: this.props.name, selected: state.specialFilter.get(this.props.name) });
|
|
|
+ DBG && console.log('DBG::P5UI__TableAjaxSpecialFilter::getStateFromStore (name:'+this.props.name+')', { store: state, name: this.props.name, selected: state.specialFilter.get(this.props.name) });
|
|
|
return {
|
|
|
selected: state.specialFilter.get(this.props.name),
|
|
|
};
|
|
|
@@ -584,18 +584,18 @@ global['P5UI__TableAjaxSpecialFilter'] = createReactClass({
|
|
|
return this.getStateFromStore();
|
|
|
},
|
|
|
componentDidMount: function () {
|
|
|
- DBG && console.log('DBG::P5UI__TableAjaxSpecialFilters::componentDidMount (name:'+this.props.name+')');
|
|
|
+ DBG && console.log('DBG::P5UI__TableAjaxSpecialFilter::componentDidMount (name:'+this.props.name+')');
|
|
|
this.unsubscribe = this.props.store.subscribe(this.storeUpdated)
|
|
|
},
|
|
|
componentWillUnmount: function () {
|
|
|
this.unsubscribe()
|
|
|
},
|
|
|
storeUpdated: function () {
|
|
|
- DBG && console.log('DBG::P5UI__TableAjaxSpecialFilters::storeUpdated (name:'+this.props.name+')');
|
|
|
+ DBG && console.log('DBG::P5UI__TableAjaxSpecialFilter::storeUpdated (name:'+this.props.name+')');
|
|
|
this.setState(this.getStateFromStore())
|
|
|
},
|
|
|
shouldComponentUpdate: function (nextProps, nextState) {
|
|
|
- DBG && console.log('DBG::P5UI__TableAjaxSpecialFilters::shouldComponentUpdate (name:'+this.props.name+')', { state: this.state, nextState});
|
|
|
+ DBG && console.log('DBG::P5UI__TableAjaxSpecialFilter::shouldComponentUpdate (name:'+this.props.name+')', { state: this.state, nextState});
|
|
|
return (
|
|
|
this.state.selected !== nextState.selected
|
|
|
);
|
|
|
@@ -624,7 +624,7 @@ global['P5UI__TableAjaxSpecialFilter'] = createReactClass({
|
|
|
}, option);
|
|
|
},
|
|
|
render: function () {
|
|
|
- DBG && console.log('DBG::P5UI__TableAjaxSpecialFilters::render (name:'+this.props.name+')', { state: this.state, props: this.props });
|
|
|
+ DBG && console.log('DBG::P5UI__TableAjaxSpecialFilter::render (name:'+this.props.name+')', { state: this.state, props: this.props });
|
|
|
var label = this.props.label || this.props.name;
|
|
|
return h('div', { className: "btn-group", style: { margin: '0 4px 0 0' } },
|
|
|
[
|
|
|
@@ -652,6 +652,272 @@ global['P5UI__TableAjaxSpecialFilter'] = createReactClass({
|
|
|
);
|
|
|
}
|
|
|
});
|
|
|
+global['P5UI__TableAjaxSpecialFilterRelations'] = createReactClass({
|
|
|
+ // props.store: Redux store with state: { isLoading bool, selected array of strings }
|
|
|
+ // props.actions: Redux store actions
|
|
|
+ // props.name: PropTypes.string.isRequired
|
|
|
+ // props.values: PropTypes.array.isRequired
|
|
|
+ // props.icon: PropTypes.string.isRequired
|
|
|
+ // props.label: PropTypes.string
|
|
|
+ // props.availableBackRefs: PropTypes.array.isRequired // array of objects { id, namespace, label }
|
|
|
+ // props.availableChildRefs: PropTypes.array.isRequired // array of objects { id, namespace, label }
|
|
|
+
|
|
|
+ getStateFromStore: function () {
|
|
|
+ var state = this.props.store.getState();
|
|
|
+ DBG && console.log('DBG::P5UI__TableAjaxSpecialFilterRelations::getStateFromStore (name:'+this.props.name+')', { store: state, name: this.props.name, selected: state.specialFilter.get(this.props.name) });
|
|
|
+ var selected = []; // Array of { idInstance, primaryKey }
|
|
|
+ state.specialFilter.forEach(function (value, key) {
|
|
|
+ if ('Ref_From_' === key.substr(0, 'Ref_From_'.length)) {
|
|
|
+ selected.push({ type: 'From', idInstance: key.substr('Ref_From_'.length), primaryKey: value, filterKey: key })
|
|
|
+ }
|
|
|
+ if ('Ref_To_' === key.substr(0, 'Ref_To_'.length)) {
|
|
|
+ selected.push({ type: 'To', idInstance: key.substr('Ref_To_'.length), primaryKey: value, filterKey: key })
|
|
|
+ }
|
|
|
+ })
|
|
|
+ DBG && console.log('TODO: DBG::P5UI__TableAjaxSpecialFilterRelations::getStateFromStore (name:'+this.props.name+')', { store: state, name: this.props.name, selected });
|
|
|
+ return {
|
|
|
+ selected: selected,
|
|
|
+ };
|
|
|
+ },
|
|
|
+ getInitialState: function () {
|
|
|
+ return this.getStateFromStore();
|
|
|
+ },
|
|
|
+ componentDidMount: function () {
|
|
|
+ DBG && console.log('DBG::P5UI__TableAjaxSpecialFilterRelations::componentDidMount (name:'+this.props.name+')');
|
|
|
+ this.unsubscribe = this.props.store.subscribe(this.storeUpdated)
|
|
|
+ },
|
|
|
+ componentWillUnmount: function () {
|
|
|
+ this.unsubscribe()
|
|
|
+ },
|
|
|
+ storeUpdated: function () {
|
|
|
+ DBG && console.log('DBG::P5UI__TableAjaxSpecialFilterRelations::storeUpdated (name:'+this.props.name+')');
|
|
|
+ this.setState(this.getStateFromStore())
|
|
|
+ },
|
|
|
+ shouldComponentUpdate: function (nextProps, nextState) {
|
|
|
+ DBG && console.log('DBG::P5UI__TableAjaxSpecialFilterRelations::shouldComponentUpdate (name:'+this.props.name+')', { state: this.state, nextState});
|
|
|
+ return (
|
|
|
+ this.state.selected !== nextState.selected
|
|
|
+ );
|
|
|
+ },
|
|
|
+
|
|
|
+ handleRemoveFilter: function (event) {
|
|
|
+ this.props.store.dispatch( this.props.actions.setSpecialFilter(this.props.name, '') );
|
|
|
+ },
|
|
|
+ handleSetFilter: function (value) {
|
|
|
+ this.props.store.dispatch( this.props.actions.setSpecialFilter(this.props.name, value) );
|
|
|
+ },
|
|
|
+ handleCreate: function () {
|
|
|
+ // TODO: save swal reference to variable to avoid open twice?
|
|
|
+ var inputOptions = {};
|
|
|
+ if (this.props.availableBackRefs) this.props.availableBackRefs.forEach(function (instanceInfo) {
|
|
|
+ inputOptions[ 'From_' + instanceInfo.id ] = "z " + instanceInfo.label || instanceInfo.namespace;
|
|
|
+ });
|
|
|
+ if (this.props.availableChildRefs) this.props.availableChildRefs.forEach(function (instanceInfo) {
|
|
|
+ inputOptions[ 'To_' + instanceInfo.id ] = "do " + instanceInfo.label || instanceInfo.namespace;
|
|
|
+ });
|
|
|
+
|
|
|
+ swal({
|
|
|
+ title: "Wybierz rodzaj relacji",
|
|
|
+ input: 'select',
|
|
|
+ inputOptions: inputOptions,
|
|
|
+ inputPlaceholder: "Wybierz",
|
|
|
+ showCancelButton: true,
|
|
|
+ cancelButtonText: "Anuluj",
|
|
|
+ animation: false,
|
|
|
+ inputValidator: function (value) {
|
|
|
+ DBG && console.log('DBG::P5UI__TableAjaxSpecialFilterRelations::inputValidator', value);
|
|
|
+ return new Promise(function (resolve) {
|
|
|
+ if (!value) {
|
|
|
+ resolve('Nie wybrano obiektu');
|
|
|
+ } else {
|
|
|
+ resolve();
|
|
|
+ }
|
|
|
+ });
|
|
|
+ },
|
|
|
+ }).then(this.handleInstanceCreate) // args: { value: ... }
|
|
|
+ },
|
|
|
+ handleInstanceCreate: function (result) {
|
|
|
+ if (!result.value) return; // cancel when result = { dismiss: "cancel" }
|
|
|
+ var idInstance = '';
|
|
|
+ var type = '';
|
|
|
+ var instanceLabel = '';
|
|
|
+ if ('From_' === result.value.substr(0, 'From_'.length)) {
|
|
|
+ type = 'From';
|
|
|
+ idInstance = result.value.substr('From_'.length);
|
|
|
+ if (this.props.availableBackRefs) this.props.availableBackRefs.forEach(function (instanceInfo) {
|
|
|
+ if (idInstance == instanceInfo.id) instanceLabel = instanceInfo.label || instanceInfo.namespace;
|
|
|
+ });
|
|
|
+ }
|
|
|
+ else if ('To_' === result.value.substr(0, 'To_'.length)) {
|
|
|
+ type = 'To';
|
|
|
+ idInstance = result.value.substr('To_'.length);
|
|
|
+ if (this.props.availableChildRefs) this.props.availableChildRefs.forEach(function (instanceInfo) {
|
|
|
+ if (idInstance == instanceInfo.id) instanceLabel = instanceInfo.label || instanceInfo.namespace;
|
|
|
+ });
|
|
|
+ }
|
|
|
+ DBG && console.log('DBG::P5UI__TableAjaxSpecialFilterRelations::handleInstanceCreate (name:'+this.props.name+') selected instance('+idInstance+')', { result: result, state: this.state, props: this.props, availableBackRefs: this.props.availableBackRefs });
|
|
|
+
|
|
|
+ swal({
|
|
|
+ title: "Wybierz obiekt",
|
|
|
+ html: (instanceLabel) ? "typu: " + instanceLabel : "",
|
|
|
+ input: 'text',
|
|
|
+ inputPlaceholder: "Wybierz obiekt",
|
|
|
+ showCancelButton: true,
|
|
|
+ cancelButtonText: "Anuluj",
|
|
|
+ animation: false,
|
|
|
+ inputValidator: function (value) {
|
|
|
+ DBG && console.log('DBG::P5UI__TableAjaxSpecialFilterRelations::inputValidator', value);
|
|
|
+ return new Promise(function (resolve) {
|
|
|
+ if (!value) {
|
|
|
+ resolve('Nie podano obiektu');
|
|
|
+ } else {
|
|
|
+ resolve();
|
|
|
+ }
|
|
|
+ });
|
|
|
+ },
|
|
|
+ preConfirm: function (value) {
|
|
|
+ return {
|
|
|
+ type: type,
|
|
|
+ idInstance: idInstance,
|
|
|
+ primaryKey: value,
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }).then(this.handleInstancePrimaryKeySelected) // args: { value: { idInstance, primaryKey } }
|
|
|
+ },
|
|
|
+ handleInstancePrimaryKeySelected: function (result) {
|
|
|
+ if (!result.value) return; // cancel when result = { dismiss: "cancel" }
|
|
|
+ var type = result.value.type;
|
|
|
+ var idInstance = result.value.idInstance;
|
|
|
+ var primaryKey = result.value.primaryKey;
|
|
|
+ DBG && console.log('DBG::P5UI__TableAjaxSpecialFilterRelations::handleInstancePrimaryKeySelected (name:'+this.props.name+') selected featureID('+idInstance+'.'+primaryKey+')', { result: result, state: this.state, props: this.props, availableBackRefs: this.props.availableBackRefs });
|
|
|
+ this.props.store.dispatch( this.props.actions.setSpecialFilter('Ref_' + type + '_' + idInstance, primaryKey) );
|
|
|
+ },
|
|
|
+
|
|
|
+ renderButton: function (buttonKey) {
|
|
|
+ var option = buttonKey;
|
|
|
+ var props = this.props.values[option];
|
|
|
+ var value = props.value || '';
|
|
|
+ var state = this.props.store.getState();
|
|
|
+ DBG && console.warn('DBG:renderButton state', { state, props, value });
|
|
|
+ var active = (value === this.state.selected);
|
|
|
+ return h('button', {
|
|
|
+ className: "btn btn-xs btn-default" + ( active ? " active" : "" ),
|
|
|
+ onClick: function (event) {
|
|
|
+ DBG && console.warn('DBG:renderButton click', { value });
|
|
|
+ this.handleSetFilter(value);
|
|
|
+ }.bind(this),
|
|
|
+ }, option);
|
|
|
+ },
|
|
|
+ renderLabel: function () {
|
|
|
+ var label = this.props.label || this.props.name;
|
|
|
+ return h('button', {
|
|
|
+ className: "btn btn-xs btn-default",
|
|
|
+ title: label,
|
|
|
+ style: {
|
|
|
+ color: '#31708f',
|
|
|
+ backgroundColor: '#d9edf7',
|
|
|
+ }
|
|
|
+ }, [
|
|
|
+ h('i', { className: this.props.icon }),
|
|
|
+ " Filtr relacji: ",
|
|
|
+ ]);
|
|
|
+ },
|
|
|
+ renderListSelected: function () { // @return array of react nodes
|
|
|
+ DBG && console.log('DBG::P5UI__TableAjaxSpecialFilterRelations::this.props.availableBackRefs (name:'+this.props.name+')', { state: this.state, props: this.props, availableBackRefs: this.props.availableBackRefs });
|
|
|
+ return this.state.selected.map(this.renderSelected);
|
|
|
+ },
|
|
|
+ renderSelected: function (selected) { // @selected: { type: 'From' | 'To', filterKey, idInstance, primaryKey }, @return react node
|
|
|
+ var filterKey = selected.filterKey;
|
|
|
+ var type = selected.type; // From | To - backRef | childRef
|
|
|
+ var idInstance = selected.idInstance;
|
|
|
+ var primaryKey = selected.primaryKey;
|
|
|
+ var namespace = idInstance;
|
|
|
+ var label = "" + idInstance + "." + primaryKey + "";
|
|
|
+ if ('From' === type) {
|
|
|
+ var foundInstanceInfo = this.props.availableBackRefs.filter(function (instanceInfo) {
|
|
|
+ return ( parseInt(idInstance) === parseInt(instanceInfo.id) );
|
|
|
+ });
|
|
|
+ if (foundInstanceInfo.length > 0) label = foundInstanceInfo[0].label + "." + primaryKey;
|
|
|
+ if (foundInstanceInfo.length > 0) namespace = foundInstanceInfo[0].namespace;
|
|
|
+ } else if ('To' === type) {
|
|
|
+ var foundInstanceInfo = this.props.availableChildRefs.filter(function (instanceInfo) {
|
|
|
+ return ( parseInt(idInstance) === parseInt(instanceInfo.id) );
|
|
|
+ });
|
|
|
+ if (foundInstanceInfo.length > 0) label = foundInstanceInfo[0].label + "." + primaryKey;
|
|
|
+ if (foundInstanceInfo.length > 0) namespace = foundInstanceInfo[0].namespace;
|
|
|
+ }
|
|
|
+ return h(P5UI__TableAjaxSpecialFilterRelationFrom, {
|
|
|
+ filterKey: filterKey,
|
|
|
+ label: label,
|
|
|
+ namespace: namespace,
|
|
|
+ primaryKey: primaryKey,
|
|
|
+ store: this.props.store,
|
|
|
+ actions: this.props.actions,
|
|
|
+ });
|
|
|
+ },
|
|
|
+ renderBackRef: function () { // @return react node - button with dropdown to select primaryKey from parent instance + remove button if selected
|
|
|
+ return null;
|
|
|
+ },
|
|
|
+ renderCreateButton: function () {
|
|
|
+ return h('button', {
|
|
|
+ className: "btn btn-xs btn-default",
|
|
|
+ title: "Dodaj nowy filtr relacji",
|
|
|
+ onClick: this.handleCreate,
|
|
|
+ }, [
|
|
|
+ h('i', { className: 'glyphicon glyphicon-plus' })
|
|
|
+ ]);
|
|
|
+ },
|
|
|
+ render: function () {
|
|
|
+ DBG && console.log('DBG::P5UI__TableAjaxSpecialFilterRelations::render (name:'+this.props.name+')', { state: this.state, props: this.props });
|
|
|
+ return h('div', { className: "btn-group", style: { margin: '0 4px 0 0' } },
|
|
|
+ [
|
|
|
+ this.renderLabel(),
|
|
|
+ ].concat(
|
|
|
+ this.renderListSelected()
|
|
|
+ ).concat([
|
|
|
+ this.renderCreateButton()
|
|
|
+ ])
|
|
|
+ // Object.keys(this.props.values).map(this.renderButton)
|
|
|
+ // ).concat(
|
|
|
+ // [
|
|
|
+ // h('button', {
|
|
|
+ // className: "btn btn-xs btn-default",
|
|
|
+ // title: "Kasuj filtr",
|
|
|
+ // disabled: !this.state.selected,
|
|
|
+ // onClick: this.handleRemoveFilter,
|
|
|
+ // style: { color: !this.state.selected ? '#bbb' : '#f00' }
|
|
|
+ // }, [
|
|
|
+ // h('i', { className: "glyphicon glyphicon-remove" })
|
|
|
+ // ])
|
|
|
+ // ]
|
|
|
+ );
|
|
|
+ }
|
|
|
+});
|
|
|
+global['P5UI__TableAjaxSpecialFilterRelationFrom'] = createReactClass({
|
|
|
+ handleRemoveFilter: function (event) {
|
|
|
+ this.props.store.dispatch( this.props.actions.setSpecialFilter(this.props.filterKey, '') );
|
|
|
+ },
|
|
|
+
|
|
|
+ render: function () {
|
|
|
+ DBG && console.log('DBG::P5UI__TableAjaxSpecialFilterRelationFrom::render (filterKey:'+this.props.filterKey+')', { state: this.state, props: this.props });
|
|
|
+ return h('button', {
|
|
|
+ className: "btn btn-xs btn-default active",
|
|
|
+ title: "Powiązane z " + this.props.namespace + " " + this.props.primaryKey,
|
|
|
+ // onClick: this.handleUpdate, // TODO: paste param
|
|
|
+ }, [
|
|
|
+ this.props.label,
|
|
|
+ h('i', {
|
|
|
+ className: 'glyphicon glyphicon-remove',
|
|
|
+ style: {
|
|
|
+ color: '#f00',
|
|
|
+ opacity: 0.5,
|
|
|
+ marginLeft: "3px",
|
|
|
+ },
|
|
|
+ onClick: this.handleRemoveFilter,
|
|
|
+ })
|
|
|
+ ]);
|
|
|
+ }
|
|
|
+});
|
|
|
global['P5UI__TableAjaxSpecialFilters'] = createReactClass({
|
|
|
// props.store: Redux store with state: { isLoading bool, selected array of strings }
|
|
|
// props.actions: Redux store actions
|
|
|
@@ -683,6 +949,19 @@ global['P5UI__TableAjaxSpecialFilters'] = createReactClass({
|
|
|
// },
|
|
|
renderSpecialFilter: function (key) {
|
|
|
var props = this.props.specialFilters[key];
|
|
|
+ DBG && console.log('DBG::P5UI__TableAjaxSpecialFilters::renderSpecialFilter (ns:'+this.props.namespace+')', { key: key, props, state: this.state });
|
|
|
+ if ('RELATIONS' === props.type) {
|
|
|
+ DBG && console.warn('DBG::P5UI__TableAjaxSpecialFilters::renderSpecialFilter TODO render RELATIONS filter (ns:'+this.props.namespace+')', { props, state: this.state });
|
|
|
+ return h(P5UI__TableAjaxSpecialFilterRelations, {
|
|
|
+ store: this.props.store,
|
|
|
+ actions: this.props.actions,
|
|
|
+ name: key,
|
|
|
+ icon: props.icon,
|
|
|
+ label: props.label,
|
|
|
+ availableBackRefs: props.availableBackRefs,
|
|
|
+ availableChildRefs: props.availableChildRefs,
|
|
|
+ });
|
|
|
+ }
|
|
|
return h(P5UI__TableAjaxSpecialFilter, {
|
|
|
store: this.props.store,
|
|
|
actions: this.props.actions,
|
|
|
@@ -2484,6 +2763,21 @@ var TableAjax = function() {
|
|
|
node.attr('href', exportUrl);
|
|
|
};
|
|
|
|
|
|
+ priv.showFailFetchDataMsg = function () {
|
|
|
+ var clearAllFiltersBtn = jQuery('<button class="btn btn-xs btn-link" style="color:red">usunąć wszystkie filtry</button>')
|
|
|
+ clearAllFiltersBtn.on('click', function () {
|
|
|
+ priv.options.filterStore.dispatch( priv.options.filterActions.clearAllFilters() )
|
|
|
+ jQuery(this).parent().remove();
|
|
|
+ })
|
|
|
+ var msgNode = jQuery('<div class="alert alert-danger" style="clear:both; max-width:600px; margin: 10px auto">' +
|
|
|
+ 'Wystąpił błąd podczas pobierania danych ' +
|
|
|
+ '<a href="javascript:window.location.reload()" class="btn btn-xs btn-link">spróbuj ponownie</a>.' + '<br>' +
|
|
|
+ 'Jeśli problem się powtarza, spróbuj ' +
|
|
|
+ '</div>')
|
|
|
+ msgNode.append(clearAllFiltersBtn);
|
|
|
+ jQuery(_uiNodeCont).prepend(msgNode);
|
|
|
+ }
|
|
|
+
|
|
|
/*
|
|
|
calls the webservice(if defined).
|
|
|
used only inside priv.init
|
|
|
@@ -2514,12 +2808,10 @@ var TableAjax = function() {
|
|
|
}).then(function (data) {
|
|
|
if (priv.options.debug || DBG) console.log('loadDataAjax:fetch:update: request finished response data:', data);
|
|
|
if ('success' == data.type) {
|
|
|
- // p5UI__notifyAjaxCallback(data);
|
|
|
return data;
|
|
|
- } else if ('error' == data.type) {
|
|
|
- p5UI__notifyAjaxCallback(data);
|
|
|
} else {
|
|
|
p5UI__notifyAjaxCallback(data);
|
|
|
+ priv.showFailFetchDataMsg();
|
|
|
}
|
|
|
return null;
|
|
|
}).then(function (data) {
|
|
|
@@ -3590,10 +3882,9 @@ var TableAjax = function() {
|
|
|
state.filters = data.filters || {};
|
|
|
priv.setState(state);
|
|
|
_uiNode$Table.parent().parent().removeClass('AjaxTable-loading');
|
|
|
- } else if ('error' == data.type) {
|
|
|
- p5UI__notifyAjaxCallback(data);
|
|
|
} else {
|
|
|
p5UI__notifyAjaxCallback(data);
|
|
|
+ priv.showFailFetchDataMsg();
|
|
|
}
|
|
|
}).catch(function (e) {
|
|
|
console.log('loadDataAjax:fetch: ERR:', e);
|