feat(client): detail section with smart-table
gitea/salix/pipeline/head There was a failure building this commit
Details
gitea/salix/pipeline/head There was a failure building this commit
Details
This commit is contained in:
parent
f66e5fac9e
commit
a5e833af2c
|
@ -0,0 +1,3 @@
|
|||
INSERT INTO salix.defaultViewConfig (tableCode, columns)
|
||||
VALUES ('clientsDetail', '{"id":true,"phone":true,"city":true,"socialName":true,"salesPersonFk":true,"email":true}');
|
||||
|
|
@ -0,0 +1,202 @@
|
|||
|
||||
const ParameterizedSQL = require('loopback-connector').ParameterizedSQL;
|
||||
const buildFilter = require('vn-loopback/util/filter').buildFilter;
|
||||
const mergeFilters = require('vn-loopback/util/filter').mergeFilters;
|
||||
|
||||
module.exports = Self => {
|
||||
Self.remoteMethodCtx('detailFilter', {
|
||||
description: 'Find all instances of the model matched by filter from the data source.',
|
||||
accessType: 'READ',
|
||||
accepts: [
|
||||
{
|
||||
arg: 'filter',
|
||||
type: 'object',
|
||||
description: 'Filter defining where, order, offset, and limit - must be a JSON-encoded string',
|
||||
},
|
||||
{
|
||||
arg: 'tags',
|
||||
type: ['object'],
|
||||
description: 'List of tags to filter with',
|
||||
},
|
||||
{
|
||||
arg: 'search',
|
||||
type: 'string',
|
||||
description: `If it's and integer searchs by id, otherwise it searchs by name`,
|
||||
},
|
||||
{
|
||||
arg: 'id',
|
||||
type: 'integer',
|
||||
description: 'Item id',
|
||||
},
|
||||
{
|
||||
arg: 'categoryFk',
|
||||
type: 'integer',
|
||||
description: 'Category id',
|
||||
},
|
||||
{
|
||||
arg: 'typeFk',
|
||||
type: 'integer',
|
||||
description: 'Type id',
|
||||
},
|
||||
{
|
||||
arg: 'isActive',
|
||||
type: 'boolean',
|
||||
description: 'Whether the item is or not active',
|
||||
},
|
||||
{
|
||||
arg: 'buyerFk',
|
||||
type: 'integer',
|
||||
description: 'The buyer of the item',
|
||||
},
|
||||
{
|
||||
arg: 'supplierFk',
|
||||
type: 'integer',
|
||||
description: 'The supplier of the item',
|
||||
},
|
||||
{
|
||||
arg: 'description',
|
||||
type: 'string',
|
||||
description: 'The item description',
|
||||
},
|
||||
{
|
||||
arg: 'stemMultiplier',
|
||||
type: 'integer',
|
||||
description: 'The item multiplier',
|
||||
},
|
||||
{
|
||||
arg: 'landed',
|
||||
type: 'date',
|
||||
description: 'The item last buy landed date',
|
||||
},
|
||||
{
|
||||
arg: 'isFloramondo',
|
||||
type: 'boolean',
|
||||
description: 'Whether the the item is or not floramondo',
|
||||
}
|
||||
],
|
||||
returns: {
|
||||
type: ['object'],
|
||||
root: true
|
||||
},
|
||||
http: {
|
||||
path: `/detailFilter`,
|
||||
verb: 'GET'
|
||||
}
|
||||
});
|
||||
|
||||
Self.detailFilter = async(ctx, filter, options) => {
|
||||
const conn = Self.dataSource.connector;
|
||||
const myOptions = {};
|
||||
|
||||
if (typeof options == 'object')
|
||||
Object.assign(myOptions, options);
|
||||
|
||||
let codeWhere;
|
||||
|
||||
if (ctx.args.search) {
|
||||
const items = await Self.app.models.ItemBarcode.find({
|
||||
where: {code: ctx.args.search},
|
||||
fields: ['itemFk']
|
||||
}, myOptions);
|
||||
|
||||
const itemIds = [];
|
||||
|
||||
for (const item of items)
|
||||
itemIds.push(item.itemFk);
|
||||
|
||||
codeWhere = {'i.id': {inq: itemIds}};
|
||||
}
|
||||
|
||||
const where = buildFilter(ctx.args, (param, value) => {
|
||||
switch (param) {
|
||||
case 'search':
|
||||
return /^\d+$/.test(value)
|
||||
? {or: [{'i.id': value}, codeWhere]}
|
||||
: {or: [
|
||||
{'i.name': {like: `%${value}%`}},
|
||||
{'i.longName': {like: `%${value}%`}},
|
||||
codeWhere]};
|
||||
case 'id':
|
||||
case 'isActive':
|
||||
case 'typeFk':
|
||||
case 'isFloramondo':
|
||||
return {[`i.${param}`]: value};
|
||||
case 'multiplier':
|
||||
return {'i.stemMultiplier': value};
|
||||
case 'categoryFk':
|
||||
return {'ic.id': value};
|
||||
case 'buyerFk':
|
||||
return {'it.workerFk': value};
|
||||
case 'supplierFk':
|
||||
return {'s.id': value};
|
||||
case 'origin':
|
||||
return {'ori.code': value};
|
||||
case 'intrastat':
|
||||
return {'intr.description': value};
|
||||
case 'landed':
|
||||
return {'lb.landed': value};
|
||||
}
|
||||
});
|
||||
|
||||
filter = mergeFilters(filter, {where});
|
||||
|
||||
const stmts = [];
|
||||
const stmt = new ParameterizedSQL(
|
||||
`SELECT
|
||||
c.id,
|
||||
c.name,
|
||||
c.socialName,
|
||||
c.fi,
|
||||
c.credit,
|
||||
c.creditInsurance,
|
||||
c.phone,
|
||||
c.mobile,
|
||||
c.street,
|
||||
c.city,
|
||||
c.postcode,
|
||||
c.email,
|
||||
c.created,
|
||||
c.isActive,
|
||||
c.isVies,
|
||||
c.isTaxDataChecked,
|
||||
c.isEqualizated,
|
||||
c.isFreezed,
|
||||
c.hasToInvoice,
|
||||
c.hasToInvoiceByAddress,
|
||||
c.isToBeMailed,
|
||||
c.hasSepaVnl,
|
||||
c.hasLcr,
|
||||
c.hasCoreVnl,
|
||||
ct.id AS countryFk,
|
||||
ct.country,
|
||||
p.id AS provinceFk,
|
||||
p.name AS province,
|
||||
u.id AS salesPersonFk,
|
||||
u.name AS salesPerson,
|
||||
bt.code AS businessTypeFk,
|
||||
bt.description AS businessType,
|
||||
sti.CodigoIva AS sageTaxTypeFk,
|
||||
sti.Iva AS sageTaxType,
|
||||
stt.CodigoTransaccion AS sageTransactionTypeFk,
|
||||
stt.Transaccion AS sageTransactionType
|
||||
FROM client c
|
||||
LEFT JOIN account.user u ON u.id = c.salesPersonFk
|
||||
LEFT JOIN country ct ON ct.id = c.countryFk
|
||||
LEFT JOIN province p ON p.id = c.provinceFk
|
||||
LEFT JOIN businessType bt ON bt.code = c.businessTypeFk
|
||||
LEFT JOIN sage.TiposIva sti ON sti.CodigoIva = c.taxTypeSageFk
|
||||
LEFT JOIN sage.TiposTransacciones stt ON stt.CodigoTransaccion = c.transactionTypeSageFk
|
||||
|
||||
`
|
||||
);
|
||||
|
||||
stmt.merge(conn.makeWhere(filter.where));
|
||||
stmt.merge(conn.makePagination(filter));
|
||||
|
||||
const clientsIndex = stmts.push(stmt) - 1;
|
||||
const sql = ParameterizedSQL.join(stmts, ';');
|
||||
const result = await conn.executeStmt(sql, myOptions);
|
||||
|
||||
return clientsIndex === 0 ? result : result[clientsIndex];
|
||||
};
|
||||
};
|
|
@ -31,6 +31,7 @@ module.exports = Self => {
|
|||
require('../methods/client/createReceipt')(Self);
|
||||
require('../methods/client/updatePortfolio')(Self);
|
||||
require('../methods/client/checkDuplicated')(Self);
|
||||
require('../methods/client/detailFilter')(Self);
|
||||
|
||||
// Validations
|
||||
|
||||
|
|
|
@ -0,0 +1,335 @@
|
|||
<vn-crud-model
|
||||
vn-id="model"
|
||||
url="Clients/detailFilter"
|
||||
limit="20"
|
||||
auto-load="true">
|
||||
</vn-crud-model>
|
||||
<vn-portal slot="topbar">
|
||||
<vn-searchbar
|
||||
vn-focus
|
||||
placeholder="Search client"
|
||||
info="Search client by id or name"
|
||||
auto-state="false"
|
||||
model="model">
|
||||
</vn-searchbar>
|
||||
</vn-portal>
|
||||
<vn-card>
|
||||
<smart-table
|
||||
model="model"
|
||||
view-config-id="clientsDetail"
|
||||
options="$ctrl.smartTableOptions"
|
||||
expr-builder="$ctrl.exprBuilder(param, value)">
|
||||
<slot-table>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th field="id">
|
||||
<span translate>Identifier</span>
|
||||
</th>
|
||||
<th field="name">
|
||||
<span translate>Name</span>
|
||||
</th>
|
||||
<th field="socialName">
|
||||
<span translate>Social name</span>
|
||||
</th>
|
||||
<th field="fi">
|
||||
<span translate>Fiscal ID</span>
|
||||
</th>
|
||||
<th field="salesPersonFk">
|
||||
<span translate>Salesperson</span>
|
||||
</th>
|
||||
<th field="credit">
|
||||
<span translate>Credit</span>
|
||||
</th>
|
||||
<th field="creditInsurance">
|
||||
<span translate>Credit insurance</span>
|
||||
</th>
|
||||
<th field="phone">
|
||||
<span translate>Phone</span>
|
||||
</th>
|
||||
<th field="mobile">
|
||||
<span translate>Mobile</span>
|
||||
</th>
|
||||
<th field="street">
|
||||
<span translate>Street</span>
|
||||
</th>
|
||||
<th field="countryFk">
|
||||
<span translate>Country</span>
|
||||
</th>
|
||||
<th field="provinceFk">
|
||||
<span translate>Province</span>
|
||||
</th>
|
||||
<th field="city">
|
||||
<span translate>City</span>
|
||||
</th>
|
||||
<th field="postcode">
|
||||
<span translate>Postcode</span>
|
||||
</th>
|
||||
<th field="email">
|
||||
<span translate>Email</span>
|
||||
</th>
|
||||
<th field="created">
|
||||
<span translate>Created</span>
|
||||
</th>
|
||||
<th field="businessTypeFk">
|
||||
<span translate>Business type</span>
|
||||
</th>
|
||||
<th field="sageTransactionTypeFk">
|
||||
<span translate>Sage tax type</span>
|
||||
</th>
|
||||
<th field="sageTransactionTypeFk">
|
||||
<span translate>Sage tr. type</span>
|
||||
</th>
|
||||
<th field="isActive">
|
||||
<span translate>Active</span>
|
||||
</th>
|
||||
<th field="isVies">
|
||||
<span translate>Vies</span>
|
||||
</th>
|
||||
<th field="isTaxDataChecked">
|
||||
<span translate>Tax data checked</span>
|
||||
</th>
|
||||
<th field="isEqualizated">
|
||||
<span translate>Tax equalized</span>
|
||||
</th>
|
||||
<th field="isFreezed">
|
||||
<span translate>Freezed</span>
|
||||
</th>
|
||||
<th field="hasToInvoice">
|
||||
<span translate>Invoice</span>
|
||||
</th>
|
||||
<th field="hasToInvoiceByAddress">
|
||||
<span translate>Invoice by address</span>
|
||||
</th>
|
||||
<th field="isToBeMailed">
|
||||
<span translate>Mailing</span>
|
||||
</th>
|
||||
<th field="hasLcr">
|
||||
<span translate>Received LCR</span>
|
||||
</th>
|
||||
<th field="hasCoreVnl">
|
||||
<span translate>Received core VNL</span>
|
||||
</th>
|
||||
<th field="hasSepaVnl">
|
||||
<span translate>Received B2B VNL</span>
|
||||
</th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="client in model.data"
|
||||
vn-anchor="::{
|
||||
state: 'client.card.summary',
|
||||
params: {id: client.id}
|
||||
}">
|
||||
<td>
|
||||
<vn-icon-button ng-show="client.isActive == false"
|
||||
vn-tooltip="Client inactive"
|
||||
icon="icon-disabled">
|
||||
</vn-icon-button>
|
||||
<vn-icon-button ng-show="client.isActive && client.isFreezed == true"
|
||||
vn-tooltip="Client frozen"
|
||||
icon="icon-frozen">
|
||||
</vn-icon-button>
|
||||
</td>
|
||||
<td>
|
||||
<span
|
||||
vn-click-stop="clientDescriptor.show($event, client.id)"
|
||||
class="link">
|
||||
{{::client.id}}
|
||||
</span>
|
||||
</td>
|
||||
<td>{{::client.name}}</td>
|
||||
<td>{{::client.socialName}}</td>
|
||||
<td>{{::client.fi}}</td>
|
||||
<td>
|
||||
<span
|
||||
vn-click-stop="workerDescriptor.show($event, client.salesPersonFk)"
|
||||
ng-class="{'link': client.salesPersonFk}">
|
||||
{{::client.salesPerson | dashIfEmpty}}
|
||||
</span>
|
||||
</td>
|
||||
<td>{{::client.credit}}</td>
|
||||
<td>{{::client.creditInsurance | dashIfEmpty}}</td>
|
||||
<td>{{::client.phone | dashIfEmpty}}</td>
|
||||
<td>{{::client.mobile | dashIfEmpty}}</td>
|
||||
<td>{{::client.street | dashIfEmpty}}</td>
|
||||
<td>{{::client.country | dashIfEmpty}}</td>
|
||||
<td>{{::client.province | dashIfEmpty}}</td>
|
||||
<td>{{::client.city | dashIfEmpty}}</td>
|
||||
<td>{{::client.postcode | dashIfEmpty}}</td>
|
||||
<td>{{::client.email | dashIfEmpty}}</td>
|
||||
<td>{{::client.created | date:'dd/MM/yyyy'}}</td>
|
||||
<td>{{::client.businessType | dashIfEmpty}}</td>
|
||||
<td>{{::client.sageTaxType | dashIfEmpty}}</td>
|
||||
<td>{{::client.sageTransactionType | dashIfEmpty}}</td>
|
||||
<td>
|
||||
<vn-check
|
||||
disabled="true"
|
||||
ng-model="::client.isActive">
|
||||
</vn-check>
|
||||
</td>
|
||||
<td>
|
||||
<vn-check
|
||||
disabled="true"
|
||||
ng-model="::client.isVies">
|
||||
</vn-check>
|
||||
</td>
|
||||
<td>
|
||||
<vn-check
|
||||
disabled="true"
|
||||
ng-model="::client.isTaxDataChecked">
|
||||
</vn-check>
|
||||
</td>
|
||||
<td>
|
||||
<vn-check
|
||||
disabled="true"
|
||||
ng-model="::client.isEqualizated">
|
||||
</vn-check>
|
||||
</td>
|
||||
<td>
|
||||
<vn-check
|
||||
disabled="true"
|
||||
ng-model="::client.isFreezed">
|
||||
</vn-check>
|
||||
</td>
|
||||
<td>
|
||||
<vn-check
|
||||
disabled="true"
|
||||
ng-model="::client.hasToInvoice">
|
||||
</vn-check>
|
||||
</td>
|
||||
<td>
|
||||
<vn-check
|
||||
disabled="true"
|
||||
ng-model="::client.hasToInvoiceByAddress">
|
||||
</vn-check>
|
||||
</td>
|
||||
<td>
|
||||
<vn-check
|
||||
disabled="true"
|
||||
ng-model="::client.isToBeMailed">
|
||||
</vn-check>
|
||||
</td>
|
||||
<td>
|
||||
<vn-check
|
||||
disabled="true"
|
||||
ng-model="::client.hasLcr">
|
||||
</vn-check>
|
||||
</td>
|
||||
<td>
|
||||
<vn-check
|
||||
disabled="true"
|
||||
ng-model="::client.hasCoreVnl">
|
||||
</vn-check>
|
||||
</td>
|
||||
<td>
|
||||
<vn-check
|
||||
disabled="true"
|
||||
ng-model="::client.hasSepaVnl">
|
||||
</vn-check>
|
||||
</td>
|
||||
<!-- <td vn-fetched-tags>
|
||||
<div>
|
||||
<vn-one title="{{::item.name}}">{{::item.name}}</vn-one>
|
||||
<vn-one ng-if="::item.subName">
|
||||
<h3 title="{{::item.subName}}">{{::item.subName}}</h3>
|
||||
</vn-one>
|
||||
</div>
|
||||
<vn-fetched-tags
|
||||
max-length="6"
|
||||
item="item"
|
||||
tabindex="-1">
|
||||
</vn-fetched-tags>
|
||||
</td>
|
||||
<td>{{::item.stems}}</td>
|
||||
<td>{{::item.size}}</td>
|
||||
<td title="{{::item.typeName}}">
|
||||
{{::item.typeName}}
|
||||
</td>
|
||||
<td title="{{::item.category}}">
|
||||
{{::item.category}}
|
||||
</td>
|
||||
<td title="{{::item.intrastat}}">
|
||||
{{::item.intrastat}}
|
||||
</td>
|
||||
<td>{{::item.origin}}</td>
|
||||
<td title="{{::item.userName}}">
|
||||
<span
|
||||
class="link"
|
||||
vn-click-stop="workerDescriptor.show($event, item.buyerFk)">
|
||||
{{::item.userName}}
|
||||
</span>
|
||||
</td>
|
||||
<td>{{::item.density}}</td>
|
||||
<td>{{::item.stemMultiplier}}</td>
|
||||
<td>
|
||||
<vn-check
|
||||
disabled="true"
|
||||
ng-model="::item.isActive">
|
||||
</vn-check>
|
||||
</td>
|
||||
<td>{{::item.producer | dashIfEmpty}}</td>
|
||||
<td shrink-date>{{::item.landed | date:'dd/MM/yyyy'}}</td> -->
|
||||
<td shrink>
|
||||
<vn-horizontal class="buttons">
|
||||
<vn-icon-button vn-anchor="{state: 'ticket.index', params: {q: {clientFk: client.id} } }"
|
||||
vn-tooltip="Client tickets"
|
||||
icon="icon-ticket">
|
||||
</vn-icon-button>
|
||||
<vn-icon-button
|
||||
vn-click-stop="$ctrl.preview(client)"
|
||||
vn-tooltip="Preview"
|
||||
icon="preview">
|
||||
</vn-icon-button>
|
||||
</vn-horizontal>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</slot-table>
|
||||
</smart-table>
|
||||
</vn-card>
|
||||
<a ui-sref="item.create" vn-tooltip="New item" vn-bind="+" fixed-bottom-right>
|
||||
<vn-float-button icon="add"></vn-float-button>
|
||||
</a>
|
||||
<vn-client-descriptor-popover
|
||||
vn-id="client-descriptor">
|
||||
</vn-client-descriptor-popover>
|
||||
<vn-worker-descriptor-popover
|
||||
vn-id="worker-descriptor">
|
||||
</vn-worker-descriptor-popover>
|
||||
|
||||
<vn-popup vn-id="preview">
|
||||
<vn-client-summary
|
||||
client="$ctrl.clientSelected">
|
||||
</vn-client-summary>
|
||||
</vn-popup>
|
||||
<vn-contextmenu
|
||||
vn-id="contextmenu"
|
||||
targets="['smart-table']"
|
||||
model="model"
|
||||
expr-builder="$ctrl.exprBuilder(param, value)">
|
||||
<slot-menu>
|
||||
<vn-item translate
|
||||
ng-if="contextmenu.isFilterAllowed()"
|
||||
ng-click="contextmenu.filterBySelection()">
|
||||
Filter by selection
|
||||
</vn-item>
|
||||
<vn-item translate
|
||||
ng-if="contextmenu.isFilterAllowed()"
|
||||
ng-click="contextmenu.excludeSelection()">
|
||||
Exclude selection
|
||||
</vn-item>
|
||||
<vn-item translate
|
||||
ng-if="contextmenu.isFilterAllowed()"
|
||||
ng-click="contextmenu.removeFilter()">
|
||||
Remove filter
|
||||
</vn-item>
|
||||
<vn-item translate
|
||||
ng-click="contextmenu.removeAllFilters()">
|
||||
Remove all filters
|
||||
</vn-item>
|
||||
</slot-menu>
|
||||
</vn-contextmenu>
|
|
@ -0,0 +1,113 @@
|
|||
import ngModule from '../module';
|
||||
import Section from 'salix/components/section';
|
||||
import './style.scss';
|
||||
|
||||
class Controller extends Section {
|
||||
constructor($element, $) {
|
||||
super($element, $);
|
||||
|
||||
this.smartTableOptions = {
|
||||
activeButtons: {
|
||||
search: true,
|
||||
shownColumns: true,
|
||||
},
|
||||
columns: [
|
||||
{
|
||||
field: 'category',
|
||||
autocomplete: {
|
||||
url: 'ItemCategories',
|
||||
valueField: 'name',
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'origin',
|
||||
autocomplete: {
|
||||
url: 'Origins',
|
||||
showField: 'code',
|
||||
valueField: 'code'
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'typeFk',
|
||||
autocomplete: {
|
||||
url: 'ItemTypes',
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'intrastat',
|
||||
autocomplete: {
|
||||
url: 'Intrastats',
|
||||
showField: 'description',
|
||||
valueField: 'description'
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'buyerFk',
|
||||
autocomplete: {
|
||||
url: 'Workers/activeWithRole',
|
||||
where: `{role: {inq: ['logistic', 'buyer']}}`,
|
||||
searchFunction: '{firstName: $search}',
|
||||
showField: 'nickname',
|
||||
valueField: 'id',
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'active',
|
||||
searchable: false
|
||||
},
|
||||
{
|
||||
field: 'landed',
|
||||
searchable: false
|
||||
},
|
||||
]
|
||||
};
|
||||
}
|
||||
|
||||
exprBuilder(param, value) {
|
||||
switch (param) {
|
||||
case 'category':
|
||||
return {'ic.name': value};
|
||||
case 'buyerFk':
|
||||
return {'it.workerFk': value};
|
||||
case 'grouping':
|
||||
return {'b.grouping': value};
|
||||
case 'packing':
|
||||
return {'b.packing': value};
|
||||
case 'origin':
|
||||
return {'ori.code': value};
|
||||
case 'typeFk':
|
||||
return {'i.typeFk': value};
|
||||
case 'intrastat':
|
||||
return {'intr.description': value};
|
||||
case 'name':
|
||||
return {'i.name': {like: `%${value}%`}};
|
||||
case 'producer':
|
||||
return {'pr.name': {like: `%${value}%`}};
|
||||
case 'id':
|
||||
case 'size':
|
||||
case 'subname':
|
||||
case 'isActive':
|
||||
case 'density':
|
||||
case 'stemMultiplier':
|
||||
case 'stems':
|
||||
return {[`i.${param}`]: value};
|
||||
}
|
||||
}
|
||||
|
||||
onCloneAccept(itemFk) {
|
||||
return this.$http.post(`Items/${itemFk}/clone`)
|
||||
.then(res => {
|
||||
this.$state.go('item.card.tags', {id: res.data.id});
|
||||
});
|
||||
}
|
||||
|
||||
preview(client) {
|
||||
this.clientSelected = client;
|
||||
this.$.preview.show();
|
||||
}
|
||||
}
|
||||
|
||||
ngModule.vnComponent('vnClientDetail', {
|
||||
template: require('./index.html'),
|
||||
controller: Controller
|
||||
});
|
|
@ -0,0 +1,30 @@
|
|||
import './index.js';
|
||||
|
||||
describe('Item', () => {
|
||||
describe('Component vnItemIndex', () => {
|
||||
let controller;
|
||||
let $httpBackend;
|
||||
let $scope;
|
||||
|
||||
beforeEach(ngModule('item'));
|
||||
|
||||
beforeEach(inject(($componentController, _$httpBackend_, $rootScope) => {
|
||||
$httpBackend = _$httpBackend_;
|
||||
$scope = $rootScope.$new();
|
||||
const $element = angular.element('<vn-item-index></vn-item-index>');
|
||||
controller = $componentController('vnItemIndex', {$element, $scope});
|
||||
}));
|
||||
|
||||
describe('onCloneAccept()', () => {
|
||||
it('should perform a post query and then call go() then update itemSelected in the controller', () => {
|
||||
jest.spyOn(controller.$state, 'go');
|
||||
|
||||
$httpBackend.expectRoute('POST', `Items/:id/clone`).respond({id: 99});
|
||||
controller.onCloneAccept(1);
|
||||
$httpBackend.flush();
|
||||
|
||||
expect(controller.$state.go).toHaveBeenCalledWith('item.card.tags', {id: 99});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
|
@ -0,0 +1,2 @@
|
|||
picture: Foto
|
||||
Buy requests: Peticiones de compra
|
|
@ -0,0 +1,32 @@
|
|||
@import "variables";
|
||||
|
||||
vn-item-product {
|
||||
display: block;
|
||||
|
||||
.id {
|
||||
background-color: $color-main;
|
||||
color: $color-font-dark;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.image {
|
||||
height: 112px;
|
||||
width: 112px;
|
||||
|
||||
& > img {
|
||||
max-height: 100%;
|
||||
max-width: 100%;
|
||||
border-radius: 3px;
|
||||
}
|
||||
}
|
||||
vn-label-value:first-of-type section{
|
||||
margin-top: 9px;
|
||||
}
|
||||
}
|
||||
|
||||
table {
|
||||
img {
|
||||
border-radius: 50%;
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
}
|
||||
}
|
|
@ -47,3 +47,4 @@ import './consumption-search-panel';
|
|||
import './defaulter';
|
||||
import './notification';
|
||||
import './unpaid';
|
||||
import './detail';
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
"menus": {
|
||||
"main": [
|
||||
{"state": "client.index", "icon": "person"},
|
||||
{"state": "client.detail", "icon": "person"},
|
||||
{"state": "client.notification", "icon": "campaign"},
|
||||
{"state": "client.defaulter", "icon": "icon-defaulter"}
|
||||
],
|
||||
|
@ -381,6 +382,12 @@
|
|||
"component": "vn-client-unpaid",
|
||||
"acl": ["administrative"],
|
||||
"description": "Unpaid"
|
||||
},
|
||||
{
|
||||
"url": "/detail",
|
||||
"state": "client.detail",
|
||||
"component": "vn-client-detail",
|
||||
"description": "Detail"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue