Savepoint

This commit is contained in:
Juan Ferrer 2020-03-07 13:52:02 +01:00
parent eb0a9ceed0
commit c6b2db9a79
7 changed files with 148 additions and 136 deletions

View File

@ -13,8 +13,11 @@ import './style.scss';
*
* @property {Object} filter A key-value object with filter parameters
* @property {SearchPanel} panel The panel used for advanced searches
* @property {CrudModel} model The model used for searching
* @property {Function} exprBuilder If defined, is used to build each non-null param expresion
* @property {Function} onSearch Function to call when search is submited
*/
export default class Controller extends Component {
export default class Searchbar extends Component {
constructor($element, $) {
super($element, $);
this.searchState = '.';
@ -26,6 +29,9 @@ export default class Controller extends Component {
$postLink() {
this.onStateChange();
if (this.$state.is(this.searchState) && this.filter !== null)
this.doSearch();
}
$onDestroy() {
@ -58,8 +64,9 @@ export default class Controller extends Component {
onStateChange() {
let filter = null;
let isIndex = this.$state.is(this.searchState);
if (this.$state.is(this.searchState)) {
if (isIndex) {
if (this.$params.q) {
try {
filter = JSON.parse(this.$params.q);
@ -72,6 +79,11 @@ export default class Controller extends Component {
}
this.filter = filter;
if (isIndex)
this.doSearch();
else if (this.model)
this.model.clear();
}
openPanel(event) {
@ -100,25 +112,21 @@ export default class Controller extends Component {
this.$.popover.hide();
filter = compact(filter);
filter = filter != null ? filter : {};
this.doSearch(filter);
this.goSearch(filter);
}
onSubmit() {
this.doSearch(this.fromBar());
this.goSearch(this.fromBar());
}
removeParam(index) {
this.params.splice(index, 1);
this.doSearch(this.fromBar());
this.goSearch(this.fromBar());
}
doSearch(filter) {
goSearch(filter) {
this.filter = filter;
let opts = this.$state.is(this.searchState)
? {location: 'replace'} : null;
this.$state.go(this.searchState,
{q: JSON.stringify(filter)}, opts);
this.doSearch();
}
fromBar() {
@ -171,61 +179,6 @@ export default class Controller extends Component {
this.params.push({chip, key, value});
});
}
}
ngModule.vnComponent('vnSearchbar', {
controller: Controller,
template: require('./searchbar.html'),
bindings: {
searchState: '@?',
filter: '<?',
suggestedFilter: '<?',
panel: '@',
info: '@?'
}
});
/**
* @property {CrudModel} model The model used for searching
* @property {Function} exprBuilder If defined, is used to build each non-null param expresion
* @property {Function} onSearch Function to call when search is submited
*/
class AutoSearch {
constructor($state, $transitions) {
this.$state = $state;
this.$transitions = $transitions;
let criteria = {to: this.$state.current.name};
this.deregisterCallback = this.$transitions.onSuccess(criteria,
() => this.onStateChange());
this.fetchFilter();
}
$postLink() {
if (this.filter !== null)
this.doSearch();
}
$onDestroy() {
this.deregisterCallback();
}
fetchFilter() {
if (this.$state.params.q) {
try {
this.filter = JSON.parse(this.$state.params.q);
} catch (e) {
console.error(e);
}
} else
this.filter = null;
}
onStateChange() {
this.fetchFilter();
this.doSearch();
}
doSearch() {
let filter = this.filter;
@ -257,25 +210,81 @@ class AutoSearch {
this.model.applyFilter(
where ? {where} : null,
hasParams ? userParams : null
);
).then(() => this.onModelFilter());
} else
this.model.clear();
}
}
onModelFilter() {
let params;
let opts;
let data = this.model.data;
let currentState = this.$state.current.name;
let stateParts = currentState.split('.');
let baseState = stateParts[0];
let subState = stateParts[1];
if (this.goState && data && data.length == 1) {
switch (subState) {
case 'index':
subState = 'card.summary';
break;
case 'card':
subState += `.${stateParts[2]}`;
break;
}
if (this.goStateParams)
params = this.goStateParams({$row: data[0]});
} else {
if (subState == 'index')
opts = {location: 'replace'};
subState = `index`;
params = {q: JSON.stringify(this.filter)};
}
this.$state.go(`${baseState}.${subState}`, params, opts);
}
exprBuilder(param, value) {
return {[param]: value};
}
}
AutoSearch.$inject = ['$state', '$transitions'];
ngModule.vnComponent('vnSearchbar', {
controller: Searchbar,
template: require('./searchbar.html'),
bindings: {
searchState: '@?',
filter: '<?',
suggestedFilter: '<?',
panel: '@',
info: '@?',
model: '<?',
onSearch: '&?',
exprBuilder: '&?',
paramBuilder: '&?',
goState: '@?',
goStateParams: '&?'
}
});
class AutoSearch {
constructor(vnSlotService) {
let searchbar = vnSlotService.getContent('topbar');
if (searchbar && searchbar.$ctrl instanceof Searchbar) {
this.model = searchbar.$ctrl.model;
console.log(this.model.data);
}
}
}
AutoSearch.$inject = ['vnSlotService'];
ngModule.vnComponent('vnAutoSearch', {
controller: AutoSearch,
bindings: {
model: '<?',
onSearch: '&?',
exprBuilder: '&?',
paramBuilder: '&?'
model: '=?'
}
});

View File

@ -67,6 +67,12 @@ export class SlotService {
$content.remove();
}
getContent(slot) {
if (this.slots[slot])
return this.slots[slot].$element[0].firstElementChild;
return null;
}
refreshContent(slot) {
if (!this.slots[slot]) return;
let $content = this.stacks[slot][0];

View File

@ -63,9 +63,12 @@ export function config($translatePartialLoaderProvider, $httpProvider, $compileP
$httpProvider.interceptors.push('vnInterceptor');
$compileProvider
.debugInfoEnabled(false)
.commentDirectivesEnabled(false)
.cssClassDirectivesEnabled(false);
let env = process.env.NODE_ENV;
if (!env || env == 'development')
$compileProvider.debugInfoEnabled(false);
}
ngModule.config(config);

View File

@ -1,14 +1,5 @@
<vn-crud-model
vn-id="model"
url="Zones"
filter="::$ctrl.filter"
limit="20"
data="zones"
auto-load="false">
</vn-crud-model>
<vn-auto-search
model="model"
expr-builder="$ctrl.exprBuilder(param, value)">
model="model">
</vn-auto-search>
<vn-data-viewer
model="model"
@ -27,7 +18,7 @@
</vn-thead>
<vn-tbody>
<vn-tr
ng-repeat="zone in zones"
ng-repeat="zone in model.data"
ui-sref="zone.card.summary({id: zone.id})"
class="clickable search-result">
<vn-td number>{{::zone.id}}</vn-td>
@ -61,7 +52,7 @@
</vn-popup>
<vn-confirm
vn-id="clone"
on-response="$ctrl.onCloneAccept($response)"
on-accept="$ctrl.onCloneAccept()"
question="Do you want to clone this zone?"
message="All it's properties will be copied">
</vn-confirm>

View File

@ -1,55 +1,10 @@
import ngModule from '../module';
export default class Controller {
constructor($scope, $http, $state) {
this.$scope = $scope;
constructor($, $http, $state) {
this.$ = $;
this.$http = $http;
this.$state = $state;
this.filter = {
include: {
relation: 'agencyMode',
scope: {fields: ['name']}
}
};
}
exprBuilder(param, value) {
switch (param) {
case 'search':
return /^\d+$/.test(value)
? {id: value}
: {name: {like: `%${value}%`}};
case 'name':
return {[param]: {like: `%${value}%`}};
case 'agencyModeFk':
return {[param]: value};
}
}
/**
* Clones a zone and all its properties
* @param {Object} event - Event object
* @param {Object} zone - Selected item
*/
clone(event, zone) {
this.stopEvent(event);
this.selectedZone = zone;
this.$scope.clone.show();
}
/**
* Clone response callback
* @param {String} response - Response string (['accept', 'cancel'])
*/
onCloneAccept(response) {
if (!(response == 'accept' && this.selectedZone)) return;
const query = `Zones/${this.selectedZone.id}/clone`;
this.$http.post(query).then(res => {
if (res && res.data)
this.$state.go('zone.card.basicData', {id: res.data.id});
});
this.selectedZone = null;
}
/**
@ -60,13 +15,28 @@ export default class Controller {
preview(event, zone) {
this.stopEvent(event);
this.selectedZone = zone;
this.$scope.summary.show();
this.$.summary.show();
}
/**
* Prevents normal event propagation
* Clones a zone and all its properties
* @param {Object} event - Event object
* @param {Object} zone - Selected item
*/
clone(event, zone) {
this.stopEvent(event);
this.selectedZone = zone;
this.$.clone.show();
}
onCloneAccept() {
return this.$http.post(`Zones/${this.selectedZone.id}/clone`)
.then(res => {
this.selectedZone = null;
this.$state.go('zone.card.basicData', {id: res.data.id});
});
}
stopEvent(event) {
event.preventDefault();
event.stopImmediatePropagation();

View File

@ -1,8 +1,18 @@
<vn-crud-model
vn-id="model"
url="Zones"
filter="::$ctrl.filter"
limit="20">
</vn-crud-model>
<vn-portal slot="topbar">
<vn-searchbar
search-state="zone.index"
panel="vn-zone-search-panel"
info="Search zone by id or name">
info="Search zone by id or name"
model="model"
expr-builder="$ctrl.exprBuilder(param, value)"
go-state="zone.card.summary"
go-state-params="{id: $row.id}">
</vn-searchbar>
</vn-portal>
<vn-portal slot="menu">

View File

@ -1,7 +1,30 @@
import ngModule from '../module';
import ModuleMain from 'salix/components/module-main';
export default class Zone extends ModuleMain {}
export default class Zone extends ModuleMain {
constructor($element, $) {
super($element, $);
this.filter = {
include: {
relation: 'agencyMode',
scope: {fields: ['name']}
}
};
}
exprBuilder(param, value) {
switch (param) {
case 'search':
return /^\d+$/.test(value)
? {id: value}
: {name: {like: `%${value}%`}};
case 'name':
return {[param]: {like: `%${value}%`}};
case 'agencyModeFk':
return {[param]: value};
}
}
}
ngModule.vnComponent('vnZone', {
controller: Zone,