Merge branch 'dev' of https://gitea.verdnatura.es/verdnatura/salix into 1466-print_refactor
gitea/salix/1466-print_refactor This commit looks good
Details
gitea/salix/1466-print_refactor This commit looks good
Details
This commit is contained in:
commit
b099fe206b
|
@ -9,25 +9,31 @@ module.exports = Self => {
|
|||
{
|
||||
arg: 'warehouseId',
|
||||
type: 'Number',
|
||||
description: 'The warehouse id'
|
||||
description: 'The warehouse id',
|
||||
required: true
|
||||
}, {
|
||||
arg: 'companyId',
|
||||
type: 'Number',
|
||||
description: 'The company id'
|
||||
description: 'The company id',
|
||||
required: true
|
||||
}, {
|
||||
arg: 'dmsTypeId',
|
||||
type: 'Number',
|
||||
description: 'The dms type id'
|
||||
description: 'The dms type id',
|
||||
required: true
|
||||
}, {
|
||||
arg: 'reference',
|
||||
type: 'String'
|
||||
type: 'String',
|
||||
required: true
|
||||
}, {
|
||||
arg: 'description',
|
||||
type: 'String'
|
||||
type: 'String',
|
||||
required: true
|
||||
}, {
|
||||
arg: 'hasFile',
|
||||
type: 'Boolean',
|
||||
description: 'True if has an attached file'
|
||||
description: 'True if has an attached file',
|
||||
required: true
|
||||
}],
|
||||
returns: {
|
||||
type: 'Object',
|
||||
|
|
|
@ -52,6 +52,15 @@
|
|||
},
|
||||
"Postcode": {
|
||||
"dataSource": "vn"
|
||||
},
|
||||
"UserPhoneType": {
|
||||
"dataSource": "vn"
|
||||
},
|
||||
"UserPhone": {
|
||||
"dataSource": "vn"
|
||||
},
|
||||
"UserLog": {
|
||||
"dataSource": "vn"
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
let UserError = require('vn-loopback/util/user-error');
|
||||
|
||||
module.exports = Self => {
|
||||
Self.rewriteDbError(function(err) {
|
||||
if (err.code === 'ER_DUP_ENTRY')
|
||||
return new UserError(`This phone already exists`);
|
||||
return err;
|
||||
});
|
||||
};
|
|
@ -2,7 +2,8 @@
|
|||
"name": "UserPhone",
|
||||
"base": "Loggable",
|
||||
"log": {
|
||||
"model":"UserLog"
|
||||
"model":"UserLog",
|
||||
"relation": "user"
|
||||
},
|
||||
"options": {
|
||||
"mysql": {
|
||||
|
@ -12,11 +13,15 @@
|
|||
"properties": {
|
||||
"id": {
|
||||
"id": true,
|
||||
"type": "String"
|
||||
"type": "Number"
|
||||
},
|
||||
"phone": {
|
||||
"type": "Number",
|
||||
"required": true
|
||||
},
|
||||
"typeFk": {
|
||||
"type": "String",
|
||||
"required": true
|
||||
}
|
||||
},
|
||||
"relations": {
|
|
@ -1,6 +1,6 @@
|
|||
CREATE TABLE `vn`.`userLog` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`originFk` int(11) NOT NULL,
|
||||
`originFk` int(10) unsigned NOT NULL,
|
||||
`userFk` int(10) unsigned DEFAULT NULL,
|
||||
`action` set('insert','update','delete') COLLATE utf8_unicode_ci NOT NULL,
|
||||
`creationDate` timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
@ -13,6 +13,6 @@ CREATE TABLE `vn`.`userLog` (
|
|||
PRIMARY KEY (`id`),
|
||||
KEY `originFk` (`originFk`),
|
||||
KEY `userFk` (`userFk`),
|
||||
CONSTRAINT `userLog_ibfk_1` FOREIGN KEY (`originFk`) REFERENCES `client` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||
CONSTRAINT `userLog_ibfk_1` FOREIGN KEY (`originFk`) REFERENCES `account`.`user` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
|
||||
CONSTRAINT `userLog_ibfk_2` FOREIGN KEY (`userFk`) REFERENCES `account`.`user` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
|
|
@ -2,7 +2,7 @@ CREATE TABLE `vn`.`userPhone` (
|
|||
`id` INT NOT NULL AUTO_INCREMENT,
|
||||
`userFk` INT(10) UNSIGNED NOT NULL,
|
||||
`typeFk` VARCHAR(45) NOT NULL,
|
||||
`phone` INT(15) NOT NULL,
|
||||
`phone` VARCHAR(15) NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE INDEX `UserFK_Phone` (`userFk` ASC, `phone` ASC));
|
||||
|
||||
|
@ -22,7 +22,7 @@ ADD CONSTRAINT `fgnUserFk`
|
|||
ON UPDATE CASCADE;
|
||||
|
||||
insert into vn.userPhone(userFk,typeFk,phone)
|
||||
select id,'PersonalPhone', phone
|
||||
select id,'personalPhone', phone
|
||||
from vn.client
|
||||
where phone is not null;
|
||||
|
||||
|
|
|
@ -351,16 +351,6 @@ INSERT INTO `vn`.`creditInsurance`(`id`, `creditClassification`, `credit`, `crea
|
|||
(2, 2, 6000, DATE_ADD(CURDATE(), INTERVAL -2 MONTH), NULL),
|
||||
(3, 3, 10000, DATE_ADD(CURDATE(), INTERVAL -3 MONTH), NULL);
|
||||
|
||||
INSERT INTO `vn`.`route`(`id`, `time`, `workerFk`, `created`, `vehicleFk`, `agencyModeFk`, `description`, `m3`, `cost`, `started`, `finished`)
|
||||
VALUES
|
||||
(1, '1899-12-30 12:15:00', 56, CURDATE(), 1, 7, 'first route', 2.7, 10, CURDATE(), CURDATE()),
|
||||
(2, '1899-12-30 13:20:00', 56, CURDATE(), 1, 7, 'second route', 0.9, 20, CURDATE(), CURDATE()),
|
||||
(3, '1899-12-30 14:30:00', 56, CURDATE(), 2, 7, 'third route', 1.1, 30, CURDATE(), CURDATE()),
|
||||
(4, '1899-12-30 15:45:00', 56, CURDATE(), 3, 7, 'fourth route', 0.1, 40, CURDATE(), CURDATE()),
|
||||
(5, '1899-12-30 16:00:00', 56, CURDATE(), 4, 8, 'fifth route', NULL, 50, CURDATE(), CURDATE()),
|
||||
(6, NULL, 57, CURDATE(), 5, 8, 'sixth route', NULL, 60, CURDATE(), CURDATE()),
|
||||
(7, NULL, 57, CURDATE(), 6, NULL, 'seventh route', NULL, 70, CURDATE(), CURDATE());
|
||||
|
||||
INSERT INTO `vn2008`.`empresa_grupo`(`empresa_grupo_id`, `grupo`)
|
||||
VALUES
|
||||
(1, 'Wayne Industries');
|
||||
|
@ -456,32 +446,42 @@ INSERT INTO `vn`.`zone` (`id`, `name`, `hour`, `warehouseFk`, `agencyModeFk`, `t
|
|||
(12, 'Zone entanglement', CONCAT(CURRENT_DATE(), ' ', TIME('22:00')), 4, 4, 0, 0, 0),
|
||||
(13, 'Zone quantum break', CONCAT(CURRENT_DATE(), ' ', TIME('22:00')), 5, 5, 0, 0, 0);
|
||||
|
||||
INSERT INTO `vn`.`route`(`id`, `time`, `workerFk`, `created`, `vehicleFk`, `agencyModeFk`, `description`, `m3`, `cost`, `started`, `finished`, `zoneFk`)
|
||||
VALUES
|
||||
(1, '1899-12-30 12:15:00', 56, CURDATE(), 1, 1, 'first route', 1.8, 10, CURDATE(), CURDATE(), 1),
|
||||
(2, '1899-12-30 13:20:00', 56, CURDATE(), 1, 2, 'second route', 0.2, 20, CURDATE(), CURDATE(), 9),
|
||||
(3, '1899-12-30 14:30:00', 56, CURDATE(), 2, 3, 'third route', 0.5, 30, CURDATE(), CURDATE(), 10),
|
||||
(4, '1899-12-30 15:45:00', 56, CURDATE(), 3, 4, 'fourth route', 0, 40, CURDATE(), CURDATE(), 12),
|
||||
(5, '1899-12-30 16:00:00', 56, CURDATE(), 4, 5, 'fifth route', 0.1, 50, CURDATE(), CURDATE(), 13),
|
||||
(6, NULL, 57, CURDATE(), 5, 7, 'sixth route', 1.7, 60, CURDATE(), CURDATE(), 3),
|
||||
(7, NULL, 57, CURDATE(), 6, 8, 'seventh route', 0, 70, CURDATE(), CURDATE(), 5);
|
||||
|
||||
INSERT INTO `vn`.`ticket`(`id`, `priority`, `agencyModeFk`,`warehouseFk`,`routeFk`, `shipped`, `landed`, `clientFk`,`nickname`, `addressFk`, `refFk`, `isDeleted`, `zoneFk`, `created`)
|
||||
VALUES
|
||||
(1 , 3, 1, 1, 1, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), DATE_ADD(DATE_ADD(CURDATE(),INTERVAL -1 MONTH), INTERVAL +1 DAY), 101, 'Bat cave', 121, 'T1111111', 0, 1, DATE_ADD(CURDATE(), INTERVAL -1 MONTH)),
|
||||
(2 , 1, 1, 1, 1, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), DATE_ADD(DATE_ADD(CURDATE(),INTERVAL -1 MONTH), INTERVAL +1 DAY), 104, 'Stark tower', 124, 'T1111111', 0, 1, DATE_ADD(CURDATE(), INTERVAL -1 MONTH)),
|
||||
(3 , 1, 7, 1, 1, DATE_ADD(CURDATE(), INTERVAL -2 MONTH), DATE_ADD(DATE_ADD(CURDATE(),INTERVAL -2 MONTH), INTERVAL +1 DAY), 104, 'Stark tower', 124, 'T2222222', 0, 3, DATE_ADD(CURDATE(), INTERVAL -2 MONTH)),
|
||||
(4 , 3, 2, 1, 1, DATE_ADD(CURDATE(), INTERVAL -3 MONTH), DATE_ADD(DATE_ADD(CURDATE(),INTERVAL -3 MONTH), INTERVAL +1 DAY), 104, 'Stark tower', 124, 'T3333333', 0, 9, DATE_ADD(CURDATE(), INTERVAL -3 MONTH)),
|
||||
(5 , 3, 3, 3, 1, DATE_ADD(CURDATE(), INTERVAL -4 MONTH), DATE_ADD(DATE_ADD(CURDATE(),INTERVAL -4 MONTH), INTERVAL +1 DAY), 104, 'Stark tower', 124, 'T4444444', 0, 10, DATE_ADD(CURDATE(), INTERVAL -4 MONTH)),
|
||||
(6 , 1, 3, 3, 1, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), DATE_ADD(DATE_ADD(CURDATE(),INTERVAL -1 MONTH), INTERVAL +1 DAY), 101, 'Mountain Drive Gotham', 1, 'A1111111', 0, 10, DATE_ADD(CURDATE(), INTERVAL -1 MONTH)),
|
||||
(7 , NULL, 7, 1, 2, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 101, 'Mountain Drive Gotham', 1, NULL, 0, 3, CURDATE()),
|
||||
(8 , NULL, 7, 1, 2, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 101, 'Bat cave', 121, NULL, 0, 3, CURDATE()),
|
||||
(9 , NULL, 7, 1, 2, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 104, 'Stark tower', 124, NULL, 0, 3, CURDATE()),
|
||||
(10, 1, 1, 5, 3, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 102, 'Ingram Street', 2, NULL, 0, 11, CURDATE()),
|
||||
(11, 1, 7, 1, 3, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 102, 'NY roofs', 122, NULL, 0, 3, CURDATE()),
|
||||
(12, 1, 1, 1, 3, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 103, 'Phone Box', 123, NULL, 0, 1, CURDATE()),
|
||||
(13, 1, 7, 1, 2, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 103, 'Phone Box', 123, NULL, 0, 1, CURDATE()),
|
||||
(14, 1, 2, 1, 3, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 104, 'Malibu Point', 4, NULL, 0, 9, CURDATE()),
|
||||
(15, 1, 7, 1, 3, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 105, 'Plastic Cell', 125, NULL, 0, 3, CURDATE()),
|
||||
(16, 1, 7, 1, 3, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 106, 'Many Places', 126, NULL, 0, 3, CURDATE()),
|
||||
(17, 1, 7, 2, 3, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 106, 'Many Places', 126, NULL, 0, 3, CURDATE()),
|
||||
(18, 1, 4, 4, 3, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 108, 'Cerebro', 128, NULL, 0, 12, CURDATE()),
|
||||
(19, 1, 5, 5, 3, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 109, 'Somewhere in Thailand', 129, NULL, 1, 13, CURDATE()),
|
||||
(20, 1, 5, 5, 3, DATE_ADD(CURDATE(), INTERVAL +1 MONTH), DATE_ADD(DATE_ADD(CURDATE(),INTERVAL +1 MONTH), INTERVAL +1 DAY), 109, 'Somewhere in Thailand', 129, NULL, 0, 13, DATE_ADD(CURDATE(), INTERVAL +1 MONTH)),
|
||||
(21, NULL, 5, 5, NULL, DATE_ADD(CURDATE(), INTERVAL +1 MONTH), DATE_ADD(DATE_ADD(CURDATE(),INTERVAL +1 MONTH), INTERVAL +1 DAY), 109, 'Somewhere in Holland', 102, NULL, 0, 13, DATE_ADD(CURDATE(), INTERVAL +1 MONTH)),
|
||||
(22, NULL, 5, 5, NULL, DATE_ADD(CURDATE(), INTERVAL +1 MONTH), DATE_ADD(DATE_ADD(CURDATE(),INTERVAL +1 MONTH), INTERVAL +1 DAY), 109, 'Somewhere in Japan', 103, NULL, 0, 13, DATE_ADD(CURDATE(), INTERVAL +1 MONTH)),
|
||||
(23, NULL, 10, 1, NULL, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 101, 'address 21', 121, NULL, 0, 8, CURDATE()),
|
||||
(24 ,NULL, 10, 1, NULL, CURDATE(), CURDATE(), 101, 'Bruce Wayne', 1, NULL, 0, 8, CURDATE());
|
||||
(1 , 3, 1, 1, 1, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), DATE_ADD(DATE_ADD(CURDATE(),INTERVAL -1 MONTH), INTERVAL +1 DAY), 101, 'Bat cave', 121, 'T1111111', 0, 1, DATE_ADD(CURDATE(), INTERVAL -1 MONTH)),
|
||||
(2 , 1, 1, 1, 1, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), DATE_ADD(DATE_ADD(CURDATE(),INTERVAL -1 MONTH), INTERVAL +1 DAY), 104, 'Stark tower', 124, 'T1111111', 0, 1, DATE_ADD(CURDATE(), INTERVAL -1 MONTH)),
|
||||
(3 , 1, 7, 1, 6, DATE_ADD(CURDATE(), INTERVAL -2 MONTH), DATE_ADD(DATE_ADD(CURDATE(),INTERVAL -2 MONTH), INTERVAL +1 DAY), 104, 'Stark tower', 124, 'T2222222', 0, 3, DATE_ADD(CURDATE(), INTERVAL -2 MONTH)),
|
||||
(4 , 3, 2, 1, 2, DATE_ADD(CURDATE(), INTERVAL -3 MONTH), DATE_ADD(DATE_ADD(CURDATE(),INTERVAL -3 MONTH), INTERVAL +1 DAY), 104, 'Stark tower', 124, 'T3333333', 0, 9, DATE_ADD(CURDATE(), INTERVAL -3 MONTH)),
|
||||
(5 , 3, 3, 3, 3, DATE_ADD(CURDATE(), INTERVAL -4 MONTH), DATE_ADD(DATE_ADD(CURDATE(),INTERVAL -4 MONTH), INTERVAL +1 DAY), 104, 'Stark tower', 124, 'T4444444', 0, 10, DATE_ADD(CURDATE(), INTERVAL -4 MONTH)),
|
||||
(6 , 1, 3, 3, 3, DATE_ADD(CURDATE(), INTERVAL -1 MONTH), DATE_ADD(DATE_ADD(CURDATE(),INTERVAL -1 MONTH), INTERVAL +1 DAY), 101, 'Mountain Drive Gotham', 1, 'A1111111', 0, 10, DATE_ADD(CURDATE(), INTERVAL -1 MONTH)),
|
||||
(7 , NULL, 7, 1, 6, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 101, 'Mountain Drive Gotham', 1, NULL, 0, 3, CURDATE()),
|
||||
(8 , NULL, 7, 1, 6, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 101, 'Bat cave', 121, NULL, 0, 3, CURDATE()),
|
||||
(9 , NULL, 7, 1, 6, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 104, 'Stark tower', 124, NULL, 0, 3, CURDATE()),
|
||||
(10, 1, 1, 5, 1, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 102, 'Ingram Street', 2, NULL, 0, 1, CURDATE()),
|
||||
(11, 1, 7, 1, 6, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 102, 'NY roofs', 122, NULL, 0, 3, CURDATE()),
|
||||
(12, 1, 1, 1, 1, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 103, 'Phone Box', 123, NULL, 0, 1, CURDATE()),
|
||||
(13, 1, 7, 1, 6, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 103, 'Phone Box', 123, NULL, 0, 3, CURDATE()),
|
||||
(14, 1, 2, 1, NULL, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 104, 'Malibu Point', 4, NULL, 0, 9, CURDATE()),
|
||||
(15, 1, 7, 1, 6, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 105, 'Plastic Cell', 125, NULL, 0, 3, CURDATE()),
|
||||
(16, 1, 7, 1, 6, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 106, 'Many Places', 126, NULL, 0, 3, CURDATE()),
|
||||
(17, 1, 7, 2, 6, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 106, 'Many Places', 126, NULL, 0, 3, CURDATE()),
|
||||
(18, 1, 4, 4, 4, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 108, 'Cerebro', 128, NULL, 0, 12, CURDATE()),
|
||||
(19, 1, 5, 5, 3, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 109, 'Somewhere in Thailand', 129, NULL, 1, 13, CURDATE()),
|
||||
(20, 1, 5, 5, 3, DATE_ADD(CURDATE(), INTERVAL +1 MONTH), DATE_ADD(DATE_ADD(CURDATE(),INTERVAL +1 MONTH), INTERVAL +1 DAY), 109, 'Somewhere in Thailand', 129, NULL, 0, 13, DATE_ADD(CURDATE(), INTERVAL +1 MONTH)),
|
||||
(21, NULL, 5, 5, 5, DATE_ADD(CURDATE(), INTERVAL +1 MONTH), DATE_ADD(DATE_ADD(CURDATE(),INTERVAL +1 MONTH), INTERVAL +1 DAY), 109, 'Somewhere in Holland', 102, NULL, 0, 13, DATE_ADD(CURDATE(), INTERVAL +1 MONTH)),
|
||||
(22, NULL, 5, 5, 5, DATE_ADD(CURDATE(), INTERVAL +1 MONTH), DATE_ADD(DATE_ADD(CURDATE(),INTERVAL +1 MONTH), INTERVAL +1 DAY), 109, 'Somewhere in Japan', 103, NULL, 0, 13, DATE_ADD(CURDATE(), INTERVAL +1 MONTH)),
|
||||
(23, NULL, 8, 1, 7, CURDATE(), DATE_ADD(CURDATE(), INTERVAL + 1 DAY), 101, 'address 21', 121, NULL, 0, 5, CURDATE()),
|
||||
(24 ,NULL, 8, 1, 7, CURDATE(), CURDATE(), 101, 'Bruce Wayne', 1, NULL, 0, 5, CURDATE());
|
||||
|
||||
INSERT INTO `vn`.`ticketObservation`(`id`, `ticketFk`, `observationTypeFk`, `description`)
|
||||
VALUES
|
||||
|
@ -1862,4 +1862,67 @@ INSERT INTO `vn`.`queuePriority`(`id`, `priority`)
|
|||
VALUES
|
||||
(1, 'Alta'),
|
||||
(2, 'Normal'),
|
||||
(3, 'Baja');
|
||||
(3, 'Baja');
|
||||
|
||||
INSERT INTO `vn`.`userPhone`(`id`, `userFk`, `typeFk`, `phone`)
|
||||
VALUES
|
||||
(1, 101, 'personalPhone', 1111111111),
|
||||
(2, 102, 'personalPhone', 1111111111),
|
||||
(3, 103, 'personalPhone', 1111111111),
|
||||
(4, 104, 'personalPhone', 1111111111),
|
||||
(5, 105, 'personalPhone', 1111111111),
|
||||
(6, 106, 'personalPhone', 1111111111),
|
||||
(7, 107, 'personalPhone', 1111111111),
|
||||
(8, 108, 'personalPhone', 1111111111),
|
||||
(9, 109, 'personalPhone', 1111111111),
|
||||
(10, 110, 'personalPhone', 1111111111),
|
||||
(11, 111, 'personalPhone', 1111111111),
|
||||
(12, 112, 'personalPhone', 1111111111),
|
||||
(13, 1, 'personalPhone', 623111111),
|
||||
(14, 2, 'personalPhone', 623111111),
|
||||
(15, 3, 'personalPhone', 623111111),
|
||||
(16, 5, 'personalPhone', 623111111),
|
||||
(17, 6, 'personalPhone', 623111111),
|
||||
(18, 9, 'personalPhone', 623111111),
|
||||
(19, 13, 'personalPhone', 623111111),
|
||||
(20, 15, 'personalPhone', 623111111),
|
||||
(21, 16, 'personalPhone', 623111111),
|
||||
(22, 17, 'personalPhone', 623111111),
|
||||
(23, 18, 'personalPhone', 623111111),
|
||||
(24, 19, 'personalPhone', 623111111),
|
||||
(25, 20, 'personalPhone', 623111111),
|
||||
(26, 21, 'personalPhone', 623111111),
|
||||
(27, 22, 'personalPhone', 623111111),
|
||||
(28, 30, 'personalPhone', 623111111),
|
||||
(29, 31, 'personalPhone', 623111111),
|
||||
(30, 32, 'personalPhone', 623111111),
|
||||
(31, 34, 'personalPhone', 623111111),
|
||||
(32, 35, 'personalPhone', 623111111),
|
||||
(33, 36, 'personalPhone', 623111111),
|
||||
(34, 37, 'personalPhone', 623111111),
|
||||
(35, 38, 'personalPhone', 623111111),
|
||||
(36, 39, 'personalPhone', 623111111),
|
||||
(37, 40, 'personalPhone', 623111111),
|
||||
(38, 41, 'personalPhone', 623111111),
|
||||
(39, 42, 'personalPhone', 623111111),
|
||||
(40, 43, 'personalPhone', 623111111),
|
||||
(41, 44, 'personalPhone', 623111111),
|
||||
(42, 45, 'personalPhone', 623111111),
|
||||
(43, 47, 'personalPhone', 623111111),
|
||||
(44, 48, 'personalPhone', 623111111),
|
||||
(45, 50, 'personalPhone', 623111111),
|
||||
(46, 51, 'personalPhone', 623111111),
|
||||
(47, 52, 'personalPhone', 623111111),
|
||||
(48, 54, 'personalPhone', 623111111),
|
||||
(49, 55, 'personalPhone', 623111111),
|
||||
(50, 56, 'personalPhone', 623111111),
|
||||
(51, 57, 'personalPhone', 623111111),
|
||||
(52, 58, 'personalPhone', 623111111),
|
||||
(53, 59, 'personalPhone', 623111111),
|
||||
(54, 60, 'personalPhone', 623111111),
|
||||
(55, 61, 'personalPhone', 623111111),
|
||||
(56, 65, 'personalPhone', 623111111),
|
||||
(57, 66, 'personalPhone', 623111111),
|
||||
(65, 107, 'businessPhone', 700987987),
|
||||
(67, 106, 'businessPhone', 1111111112),
|
||||
(68, 106, 'personalPhone', 1111111113);
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
export default {
|
||||
vnTextfield: 'vn-textfield input',
|
||||
vnInputNumber: 'vn-input-number input',
|
||||
vnSubmit: 'vn-submit > input',
|
||||
vnFloatButton: 'vn-float-button > button'
|
||||
};
|
|
@ -6,6 +6,121 @@ import config from './config.js';
|
|||
|
||||
let currentUser;
|
||||
|
||||
let asyncActions = {
|
||||
// Generic extensions
|
||||
|
||||
clickIfExists: async function(selector) {
|
||||
let exists = await this.exists(selector);
|
||||
if (exists) await this.click(selector);
|
||||
return exists;
|
||||
},
|
||||
|
||||
hasClass: async function(selector, className) {
|
||||
return await this.evaluate((selector, className) => {
|
||||
document.querySelector(selector).classList.contains(className);
|
||||
}, selector, className);
|
||||
},
|
||||
|
||||
parsedUrl: async function() {
|
||||
return new URL(await this.url());
|
||||
},
|
||||
|
||||
// Salix specific extensions
|
||||
|
||||
changeLanguageToEnglish: async function() {
|
||||
let langSelector = '.user-popover vn-autocomplete[ng-model="$ctrl.lang"]';
|
||||
|
||||
let lang = await this.waitToClick('#user')
|
||||
.wait(langSelector)
|
||||
.waitToGetProperty(`${langSelector} input`, 'value');
|
||||
|
||||
if (lang !== 'English')
|
||||
await this.autocompleteSearch(langSelector, 'English');
|
||||
},
|
||||
|
||||
doLogin: async function(userName, password) {
|
||||
if (password == null) password = 'nightmare';
|
||||
await this.wait(`vn-login [name=user]`)
|
||||
.clearInput(`vn-login [name=user]`)
|
||||
.write(`vn-login [name=user]`, userName)
|
||||
.write(`vn-login [name=password]`, password)
|
||||
.click(`vn-login button[type=submit]`);
|
||||
},
|
||||
|
||||
login: async function(userName) {
|
||||
if (currentUser !== userName) {
|
||||
let logoutClicked = await this.clickIfExists('#logout');
|
||||
|
||||
if (logoutClicked) {
|
||||
let buttonSelector = '.vn-dialog.shown button[response=ACCEPT]';
|
||||
this.wait(buttonSelector => {
|
||||
return document.querySelector(buttonSelector) != null
|
||||
|| location.hash == '#!/login';
|
||||
}, buttonSelector);
|
||||
await this.clickIfExists(buttonSelector);
|
||||
}
|
||||
|
||||
try {
|
||||
await this.waitForURL('#!/login');
|
||||
} catch (e) {
|
||||
this.goto(`${config.url}/#!/login`);
|
||||
}
|
||||
|
||||
await this.doLogin(userName, null)
|
||||
.waitForURL('#!/')
|
||||
.changeLanguageToEnglish();
|
||||
|
||||
currentUser = userName;
|
||||
} else
|
||||
await this.waitToClick('vn-topbar a[ui-sref="home"]');
|
||||
},
|
||||
|
||||
waitForLogin: async function(userName) {
|
||||
await this.login(userName);
|
||||
},
|
||||
|
||||
selectModule: async function(moduleName) {
|
||||
let snakeName = moduleName.replace(/[\w]([A-Z])/g, m => {
|
||||
return m[0] + '-' + m[1];
|
||||
}).toLowerCase();
|
||||
|
||||
await this.waitToClick(`vn-home a[ui-sref="${moduleName}.index"]`)
|
||||
.waitForURL(snakeName);
|
||||
},
|
||||
|
||||
loginAndModule: async function(userName, moduleName) {
|
||||
await this.login(userName)
|
||||
.selectModule(moduleName);
|
||||
},
|
||||
|
||||
datePicker: async function(selector, changeMonth, day) {
|
||||
let date = new Date();
|
||||
if (changeMonth) date.setMonth(date.getMonth() + changeMonth);
|
||||
date.setDate(day ? day : 16);
|
||||
date = date.toISOString().substr(0, 10);
|
||||
|
||||
await this.wait(selector)
|
||||
.evaluate((selector, date) => {
|
||||
let input = document.querySelector(selector).$ctrl.input;
|
||||
input.value = date;
|
||||
input.dispatchEvent(new Event('change'));
|
||||
}, selector, date);
|
||||
},
|
||||
|
||||
pickTime: async function(selector, time) {
|
||||
await this.wait(selector)
|
||||
.evaluate((selector, time) => {
|
||||
let input = document.querySelector(selector).$ctrl.input;
|
||||
input.value = time;
|
||||
input.dispatchEvent(new Event('change'));
|
||||
}, selector, time);
|
||||
},
|
||||
|
||||
isDisabled: async function(selector) {
|
||||
return await this.hasClass(selector, 'disabled');
|
||||
}
|
||||
};
|
||||
|
||||
let actions = {
|
||||
clearTextarea: function(selector, done) {
|
||||
this.wait(selector)
|
||||
|
@ -28,98 +143,6 @@ let actions = {
|
|||
.catch(done);
|
||||
},
|
||||
|
||||
login: function(userName, done) {
|
||||
if (currentUser)
|
||||
this.waitToClick('#logout');
|
||||
|
||||
let doLogin = () => {
|
||||
this.wait(`vn-login input[name=user]`)
|
||||
.clearInput(`vn-login input[name=user]`)
|
||||
.write(`vn-login input[name=user]`, userName)
|
||||
.write(`vn-login input[name=password]`, 'nightmare')
|
||||
.click(`vn-login input[type=submit]`)
|
||||
.then(() => {
|
||||
currentUser = userName;
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
};
|
||||
|
||||
this.waitForURL('#!/login')
|
||||
.then(doLogin)
|
||||
.catch(() => {
|
||||
this.goto(`${config.url}/#!/login`)
|
||||
.then(doLogin)
|
||||
.catch(done);
|
||||
});
|
||||
},
|
||||
|
||||
waitForLogin: function(userName, done) {
|
||||
if (currentUser === userName) {
|
||||
return this.waitToClick('vn-topbar a[ui-sref="home"]')
|
||||
.waitForURL('#!/')
|
||||
.changeLanguageToEnglish()
|
||||
.then(done)
|
||||
.catch(done);
|
||||
}
|
||||
return this.login(userName)
|
||||
.waitForURL('#!/')
|
||||
.url()
|
||||
.changeLanguageToEnglish()
|
||||
.then(done)
|
||||
.catch(done);
|
||||
},
|
||||
|
||||
resetLogin: function(done) {
|
||||
this.then(() => {
|
||||
currentUser = undefined;
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
},
|
||||
|
||||
changeLanguageToEnglish: function(done) {
|
||||
let langSelector = '.user-popover vn-autocomplete[ng-model="$ctrl.lang"]';
|
||||
|
||||
this.waitToClick('#user')
|
||||
.wait(langSelector)
|
||||
.waitToGetProperty(`${langSelector} input`, 'value')
|
||||
.then(lang => {
|
||||
if (lang === 'English') {
|
||||
this.then(done)
|
||||
.catch(done);
|
||||
} else {
|
||||
this.autocompleteSearch(langSelector, 'English')
|
||||
.then(done)
|
||||
.catch(done);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
selectModule: function(moduleName, done) {
|
||||
let snakeName = moduleName.replace(/[\w]([A-Z])/g, m => {
|
||||
return m[0] + '-' + m[1];
|
||||
}).toLowerCase();
|
||||
this.waitToClick(`vn-home a[ui-sref="${moduleName}.index"]`)
|
||||
.waitForURL(snakeName)
|
||||
.then(done)
|
||||
.catch(done);
|
||||
},
|
||||
|
||||
loginAndModule: function(userName, moduleName, done) {
|
||||
this.waitForLogin(userName)
|
||||
.selectModule(moduleName)
|
||||
.then(done)
|
||||
.catch(done);
|
||||
},
|
||||
|
||||
parsedUrl: function(done) {
|
||||
this.url()
|
||||
.then(url => {
|
||||
done(null, new URL(url));
|
||||
}).catch(done);
|
||||
},
|
||||
|
||||
getProperty: function(selector, property, done) {
|
||||
this.evaluate_now((selector, property) => {
|
||||
return document.querySelector(selector)[property].replace(/\s+/g, ' ').trim();
|
||||
|
@ -419,51 +442,6 @@ let actions = {
|
|||
});
|
||||
},
|
||||
|
||||
pickTime: function(selector, time, done) {
|
||||
this.wait(selector)
|
||||
.evaluate((selector, time) => {
|
||||
let input = document.querySelector(selector);
|
||||
input.value = time;
|
||||
input.dispatchEvent(new Event('change'));
|
||||
}, selector, time)
|
||||
.then(done)
|
||||
.catch(done);
|
||||
},
|
||||
|
||||
datePicker: function(selector, changeMonth, day, done) {
|
||||
this.wait(selector)
|
||||
.mousedown(`${selector} input`)
|
||||
.wait('.flatpickr-calendar.open');
|
||||
|
||||
if (changeMonth > 0)
|
||||
this.mousedown(`.flatpickr-calendar.open .flatpickr-next-month`);
|
||||
if (changeMonth < 0)
|
||||
this.mousedown(`.flatpickr-calendar.open .flatpickr-prev-month`);
|
||||
|
||||
let daySelector;
|
||||
|
||||
if (!day)
|
||||
daySelector = `.flatpickr-calendar.open .flatpickr-day:nth-child(16)`;
|
||||
if (day)
|
||||
daySelector = `.flatpickr-calendar.open .flatpickr-day[aria-label~="${day},"]:not(.prevMonthDay):not(.nextMonthDay)`;
|
||||
|
||||
this.wait(selector => {
|
||||
return document.querySelector(selector);
|
||||
}, daySelector)
|
||||
.evaluate(selector => {
|
||||
let event = new MouseEvent('mousedown', {
|
||||
bubbles: true,
|
||||
cancelable: true,
|
||||
view: window
|
||||
});
|
||||
document.querySelector(selector).dispatchEvent(event);
|
||||
}, daySelector)
|
||||
.then(done)
|
||||
.catch(() => {
|
||||
done(new Error(`.datePicker(), for ${daySelector} timed out`));
|
||||
});
|
||||
},
|
||||
|
||||
reloadSection: function(sectionRoute, done) {
|
||||
this.waitToClick('vn-icon[icon="desktop_windows"]')
|
||||
.wait('vn-card.summary')
|
||||
|
@ -516,6 +494,16 @@ let actions = {
|
|||
},
|
||||
};
|
||||
|
||||
for (let name in asyncActions) {
|
||||
let fn = asyncActions[name];
|
||||
|
||||
Nightmare.action(name, function(...args) {
|
||||
let done = args[args.length - 1];
|
||||
fn.apply(this, args)
|
||||
.then(res => done(null, res), done);
|
||||
});
|
||||
}
|
||||
|
||||
Object.keys(actions).forEach(function(name) {
|
||||
let fn = actions[name];
|
||||
Nightmare.action(name, fn);
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
const Nightmare = require('nightmare');
|
||||
const config = require('./config.js');
|
||||
|
||||
let nightmare;
|
||||
|
||||
module.exports = function createNightmare(width = 1280, height = 720) {
|
||||
|
@ -25,5 +27,5 @@ module.exports = function createNightmare(width = 1280, height = 720) {
|
|||
});
|
||||
|
||||
nightmare.header('Accept-Language', 'en');
|
||||
return nightmare;
|
||||
return nightmare.goto(config.url);
|
||||
};
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import components from './components_selectors.js';
|
||||
|
||||
export default {
|
||||
globalItems: {
|
||||
|
@ -22,29 +21,29 @@ export default {
|
|||
acceptButton: 'vn-confirm button[response=ACCEPT]'
|
||||
},
|
||||
clientsIndex: {
|
||||
searchClientInput: `${components.vnTextfield}`,
|
||||
searchClientInput: `vn-textfield input`,
|
||||
searchButton: 'vn-searchbar vn-icon[icon="search"]',
|
||||
searchResult: 'vn-client-index .vn-list-item',
|
||||
createClientButton: `${components.vnFloatButton}`,
|
||||
createClientButton: `vn-float-button`,
|
||||
othersButton: 'vn-left-menu li[name="Others"] > a'
|
||||
},
|
||||
createClientView: {
|
||||
name: `${components.vnTextfield}[name="name"]`,
|
||||
taxNumber: `${components.vnTextfield}[name="fi"]`,
|
||||
socialName: `${components.vnTextfield}[name="socialName"]`,
|
||||
street: `${components.vnTextfield}[name="street"]`,
|
||||
postcode: `${components.vnTextfield}[name="postcode"]`,
|
||||
city: `${components.vnTextfield}[name="city"]`,
|
||||
name: `vn-textfield input[name="name"]`,
|
||||
taxNumber: `vn-textfield input[name="fi"]`,
|
||||
socialName: `vn-textfield input[name="socialName"]`,
|
||||
street: `vn-textfield input[name="street"]`,
|
||||
postcode: `vn-textfield input[name="postcode"]`,
|
||||
city: `vn-textfield input[name="city"]`,
|
||||
province: `vn-autocomplete[ng-model="$ctrl.client.provinceFk"]`,
|
||||
country: `vn-autocomplete[ng-model="$ctrl.client.countryFk"]`,
|
||||
userName: `${components.vnTextfield}[name="userName"]`,
|
||||
email: `${components.vnTextfield}[name="email"]`,
|
||||
userName: `vn-textfield input[name="userName"]`,
|
||||
email: `vn-textfield input[name="email"]`,
|
||||
salesPersonAutocomplete: `vn-autocomplete[ng-model="$ctrl.client.salesPersonFk"]`,
|
||||
createButton: `${components.vnSubmit}`,
|
||||
createButton: `button[type=submit]`,
|
||||
cancelButton: 'vn-button[href="#!/client/index"]'
|
||||
},
|
||||
clientDescriptor: {
|
||||
moreMenu: 'vn-client-descriptor vn-icon-menu > div > vn-icon',
|
||||
moreMenu: 'vn-client-descriptor vn-icon-menu[icon=more_vert]',
|
||||
simpleTicketButton: '.vn-popover.shown .vn-drop-down li'
|
||||
},
|
||||
clientBasicData: {
|
||||
|
@ -56,17 +55,17 @@ export default {
|
|||
emailInput: 'vn-textfield[ng-model="$ctrl.client.email"] input',
|
||||
salesPersonAutocomplete: 'vn-autocomplete[ng-model="$ctrl.client.salesPersonFk"]',
|
||||
channelAutocomplete: 'vn-autocomplete[ng-model="$ctrl.client.contactChannelFk"]',
|
||||
saveButton: `${components.vnSubmit}`
|
||||
saveButton: `button[type=submit]`
|
||||
},
|
||||
clientFiscalData: {
|
||||
fiscalDataButton: 'vn-left-menu a[ui-sref="client.card.fiscalData"]',
|
||||
socialNameInput: `${components.vnTextfield}[name="socialName"]`,
|
||||
fiscalIdInput: `${components.vnTextfield}[name="fi"]`,
|
||||
equalizationTaxCheckbox: 'vn-check[label="Is equalizated"]',
|
||||
socialNameInput: `vn-textfield input[name="socialName"]`,
|
||||
fiscalIdInput: `vn-textfield input[name="fi"]`,
|
||||
equalizationTaxCheckbox: 'vn-check[ng-model="$ctrl.client.isEqualizated"]',
|
||||
acceptPropagationButton: 'vn-client-fiscal-data > vn-confirm button[response=ACCEPT]',
|
||||
addressInput: `${components.vnTextfield}[name="street"]`,
|
||||
postcodeInput: `${components.vnTextfield}[name="postcode"]`,
|
||||
cityInput: `${components.vnTextfield}[name="city"]`,
|
||||
addressInput: `vn-textfield input[name="street"]`,
|
||||
postcodeInput: `vn-textfield input[name="postcode"]`,
|
||||
cityInput: `vn-textfield input[name="city"]`,
|
||||
provinceAutocomplete: 'vn-autocomplete[ng-model="$ctrl.client.provinceFk"]',
|
||||
countryAutocomplete: 'vn-autocomplete[ng-model="$ctrl.client.countryFk"]',
|
||||
activeCheckbox: 'vn-check[label="Active"]',
|
||||
|
@ -76,12 +75,12 @@ export default {
|
|||
hasToInvoiceCheckbox: 'vn-check[label="Has to invoice"]',
|
||||
invoiceByMailCheckbox: 'vn-check[label="Invoice by mail"]',
|
||||
viesCheckbox: 'vn-check[label="Vies"]',
|
||||
saveButton: `${components.vnSubmit}`
|
||||
saveButton: `button[type=submit]`
|
||||
},
|
||||
clientBillingData: {
|
||||
payMethodAutocomplete: 'vn-client-billing-data vn-autocomplete[ng-model="$ctrl.client.payMethodFk"]',
|
||||
IBANInput: `vn-client-billing-data ${components.vnTextfield}[name="iban"]`,
|
||||
dueDayInput: `vn-client-billing-data ${components.vnInputNumber}[name="dueDay"]`,
|
||||
IBANInput: `vn-client-billing-data vn-textfield input[name="iban"]`,
|
||||
dueDayInput: `vn-client-billing-data vn-input-number input[name="dueDay"]`,
|
||||
receivedCoreLCRCheckbox: 'vn-client-billing-data vn-check[label="Received LCR"]',
|
||||
receivedCoreVNLCheckbox: 'vn-client-billing-data vn-check[label="Received core VNL"]',
|
||||
receivedB2BVNLCheckbox: 'vn-client-billing-data vn-check[label="Received B2B VNL"]',
|
||||
|
@ -92,20 +91,20 @@ export default {
|
|||
newBankEntityBIC: 'vn-client-billing-data > vn-dialog vn-textfield[label="Swift / BIC"] input',
|
||||
newBankEntityCode: 'vn-client-billing-data > vn-dialog vn-textfield[label="Entity Code"] input',
|
||||
acceptBankEntityButton: 'vn-client-billing-data > vn-dialog button[response="ACCEPT"]',
|
||||
saveButton: `${components.vnSubmit}`
|
||||
saveButton: `button[type=submit]`
|
||||
},
|
||||
clientAddresses: {
|
||||
addressesButton: 'vn-left-menu a[ui-sref="client.card.address.index"]',
|
||||
createAddress: `vn-client-address-index ${components.vnFloatButton}`,
|
||||
createAddress: `vn-client-address-index vn-float-button`,
|
||||
defaultCheckboxInput: 'vn-check[label="Default"]',
|
||||
consigneeInput: `${components.vnTextfield}[name="nickname"]`,
|
||||
streetAddressInput: `${components.vnTextfield}[name="street"]`,
|
||||
postcodeInput: `${components.vnTextfield}[name="postalCode"]`,
|
||||
cityInput: `${components.vnTextfield}[name="city"]`,
|
||||
consigneeInput: `vn-textfield input[name="nickname"]`,
|
||||
streetAddressInput: `vn-textfield input[name="street"]`,
|
||||
postcodeInput: `vn-textfield input[name="postalCode"]`,
|
||||
cityInput: `vn-textfield input[name="city"]`,
|
||||
provinceAutocomplete: 'vn-autocomplete[ng-model="$ctrl.address.provinceFk"]',
|
||||
agencyAutocomplete: 'vn-autocomplete[ng-model="$ctrl.address.agencyModeFk"]',
|
||||
phoneInput: `${components.vnTextfield}[name="phone"]`,
|
||||
mobileInput: `${components.vnTextfield}[name="mobile"]`,
|
||||
phoneInput: `vn-textfield input[name="phone"]`,
|
||||
mobileInput: `vn-textfield input[name="mobile"]`,
|
||||
defaultAddress: 'vn-client-address-index div:nth-child(1) div[name="street"]',
|
||||
secondMakeDefaultStar: 'vn-client-address-index vn-card div:nth-child(2) vn-icon-button[icon="star_border"]',
|
||||
firstEditAddress: 'vn-client-address-index div:nth-child(1) > a',
|
||||
|
@ -117,34 +116,34 @@ export default {
|
|||
secondObservationTypeAutocomplete: 'vn-client-address-edit [name=observations] :nth-child(2) [ng-model="observation.observationTypeFk"]',
|
||||
secondObservationDescriptionInput: 'vn-client-address-edit [name=observations] :nth-child(2) [ng-model="observation.description"] input',
|
||||
addObservationButton: 'vn-client-address-edit div[name="observations"] vn-icon-button[icon="add_circle"]',
|
||||
saveButton: `${components.vnSubmit}`,
|
||||
saveButton: `button[type=submit]`,
|
||||
cancelCreateAddressButton: 'button[ui-sref="client.card.address.index"]',
|
||||
cancelEditAddressButton: 'vn-client-address-edit > form > vn-button-bar > vn-button > button'
|
||||
},
|
||||
clientWebAccess: {
|
||||
webAccessButton: 'vn-left-menu a[ui-sref="client.card.webAccess"]',
|
||||
enableWebAccessCheckbox: 'vn-check[label="Enable web access"]',
|
||||
userNameInput: `${components.vnTextfield}[name="name"]`,
|
||||
saveButton: `${components.vnSubmit}`
|
||||
userNameInput: `vn-textfield input[name="name"]`,
|
||||
saveButton: `button[type=submit]`
|
||||
},
|
||||
clientNotes: {
|
||||
addNoteFloatButton: `${components.vnFloatButton}`,
|
||||
addNoteFloatButton: `vn-float-button`,
|
||||
noteInput: 'vn-textarea[label="Note"]',
|
||||
saveButton: `${components.vnSubmit}`,
|
||||
saveButton: `button[type=submit]`,
|
||||
firstNoteText: 'vn-client-note .text'
|
||||
},
|
||||
clientCredit: {
|
||||
addCreditFloatButton: `${components.vnFloatButton}`,
|
||||
creditInput: `${components.vnInputNumber}[name="credit"]`,
|
||||
saveButton: `${components.vnSubmit}`,
|
||||
addCreditFloatButton: `vn-float-button`,
|
||||
creditInput: `vn-input-number input[name="credit"]`,
|
||||
saveButton: `button[type=submit]`,
|
||||
firstCreditText: 'vn-client-credit-index vn-card > div vn-table vn-tbody > vn-tr'
|
||||
},
|
||||
clientGreuge: {
|
||||
addGreugeFloatButton: `${components.vnFloatButton}`,
|
||||
amountInput: `${components.vnInputNumber}[name="amount"]`,
|
||||
descriptionInput: `${components.vnTextfield}[name="description"]`,
|
||||
addGreugeFloatButton: `vn-float-button`,
|
||||
amountInput: `vn-input-number input[name="amount"]`,
|
||||
descriptionInput: `vn-textfield input[name="description"]`,
|
||||
typeAutocomplete: 'vn-autocomplete[ng-model="$ctrl.greuge.greugeTypeFk"]',
|
||||
saveButton: `${components.vnSubmit}`,
|
||||
saveButton: `button[type=submit]`,
|
||||
firstGreugeText: 'vn-client-greuge-index vn-card > div vn-table vn-tbody > vn-tr'
|
||||
},
|
||||
clientMandate: {
|
||||
|
@ -163,7 +162,7 @@ export default {
|
|||
clientBalance: {
|
||||
balanceButton: 'vn-left-menu a[ui-sref="client.card.balance.index"]',
|
||||
companyAutocomplete: 'vn-client-balance-index vn-autocomplete[ng-model="$ctrl.companyFk"]',
|
||||
newPaymentButton: `${components.vnFloatButton}`,
|
||||
newPaymentButton: `vn-float-button`,
|
||||
newPaymentBank: 'vn-client-balance-create vn-autocomplete[ng-model="$ctrl.receipt.bankFk"]',
|
||||
newPaymentAmountInput: 'vn-client-balance-create vn-input-number[ng-model="$ctrl.receipt.amountPaid"] input',
|
||||
saveButton: 'vn-client-balance-create vn-button[label="Save"]',
|
||||
|
@ -182,7 +181,7 @@ export default {
|
|||
},
|
||||
itemsIndex: {
|
||||
searchIcon: 'vn-item-index vn-searchbar vn-icon[icon="search"]',
|
||||
createItemButton: `${components.vnFloatButton}`,
|
||||
createItemButton: `vn-float-button`,
|
||||
searchResult: 'vn-item-index a.vn-tr',
|
||||
searchResultPreviewButton: 'vn-item-index .buttons > [icon="desktop_windows"]',
|
||||
searchResultCloneButton: 'vn-item-index .buttons > [icon="icon-clone"]',
|
||||
|
@ -208,16 +207,16 @@ export default {
|
|||
saveFieldsButton: 'vn-item-index vn-dialog vn-horizontal:nth-child(16) > vn-button > button'
|
||||
},
|
||||
itemCreateView: {
|
||||
temporalName: `${components.vnTextfield}[name="provisionalName"]`,
|
||||
temporalName: `vn-textfield input[name="provisionalName"]`,
|
||||
typeAutocomplete: 'vn-autocomplete[ng-model="$ctrl.item.typeFk"]',
|
||||
intrastatAutocomplete: 'vn-autocomplete[ng-model="$ctrl.item.intrastatFk"]',
|
||||
originAutocomplete: 'vn-autocomplete[ng-model="$ctrl.item.originFk"]',
|
||||
createButton: `${components.vnSubmit}`,
|
||||
cancelButton: 'button[ui-sref="item.index"]'
|
||||
createButton: `button[type=submit]`,
|
||||
cancelButton: 'vn-button[ui-sref="item.index"]'
|
||||
},
|
||||
itemDescriptor: {
|
||||
goBackToModuleIndexButton: 'vn-item-descriptor a[href="#!/item/index"]',
|
||||
moreMenu: 'vn-item-descriptor vn-icon-menu > div > vn-icon',
|
||||
moreMenu: 'vn-item-descriptor vn-icon-menu[icon=more_vert]',
|
||||
moreMenuRegularizeButton: '.vn-popover.shown .vn-drop-down li[name="Regularize stock"]',
|
||||
regularizeQuantityInput: 'vn-item-descriptor vn-dialog tpl-body > div > vn-textfield input',
|
||||
regularizeWarehouseAutocomplete: 'vn-item-descriptor vn-dialog vn-autocomplete[ng-model="$ctrl.warehouseFk"]',
|
||||
|
@ -238,7 +237,7 @@ export default {
|
|||
longNameInput: 'vn-textfield[ng-model="$ctrl.item.longName"] input',
|
||||
isActiveCheckbox: 'vn-check[label="Active"]',
|
||||
priceInKgCheckbox: 'vn-check[label="Price in kg"]',
|
||||
submitBasicDataButton: `${components.vnSubmit}`
|
||||
submitBasicDataButton: `button[type=submit]`
|
||||
},
|
||||
itemTags: {
|
||||
goToItemIndexButton: 'vn-item-descriptor [ui-sref="item.index"]',
|
||||
|
@ -257,19 +256,19 @@ export default {
|
|||
seventhValueInput: 'vn-item-tags vn-horizontal:nth-child(7) > vn-textfield[label="Value"] input',
|
||||
seventhRelevancyInput: 'vn-item-tags vn-horizontal:nth-child(7) > vn-textfield[label="Relevancy"] input',
|
||||
addItemTagButton: 'vn-item-tags vn-icon-button[icon="add_circle"]',
|
||||
submitItemTagsButton: `vn-item-tags ${components.vnSubmit}`
|
||||
submitItemTagsButton: `vn-item-tags button[type=submit]`
|
||||
},
|
||||
itemTax: {
|
||||
undoChangesButton: 'vn-item-tax vn-button-bar > vn-button[label="Undo changes"]',
|
||||
firstClassAutocomplete: 'vn-item-tax vn-horizontal:nth-child(1) > vn-autocomplete[ng-model="tax.taxClassFk"]',
|
||||
secondClassAutocomplete: 'vn-item-tax vn-horizontal:nth-child(2) > vn-autocomplete[ng-model="tax.taxClassFk"]',
|
||||
thirdClassAutocomplete: 'vn-item-tax vn-horizontal:nth-child(3) > vn-autocomplete[ng-model="tax.taxClassFk"]',
|
||||
submitTaxButton: `vn-item-tax ${components.vnSubmit}`
|
||||
submitTaxButton: `vn-item-tax button[type=submit]`
|
||||
},
|
||||
itemBarcodes: {
|
||||
addBarcodeButton: 'vn-item-barcode vn-icon[icon="add_circle"]',
|
||||
thirdCodeInput: `vn-item-barcode vn-horizontal:nth-child(3) > ${components.vnTextfield}`,
|
||||
submitBarcodesButton: `vn-item-barcode ${components.vnSubmit}`,
|
||||
thirdCodeInput: `vn-item-barcode vn-horizontal:nth-child(3) > vn-textfield input`,
|
||||
submitBarcodesButton: `vn-item-barcode button[type=submit]`,
|
||||
firstCodeRemoveButton: 'vn-item-barcode vn-horizontal vn-none vn-icon[icon="delete"]'
|
||||
},
|
||||
itemNiches: {
|
||||
|
@ -281,13 +280,13 @@ export default {
|
|||
secondNicheRemoveButton: 'vn-item-niche vn-horizontal:nth-child(2) > vn-none > vn-icon-button[icon="delete"]',
|
||||
thirdWarehouseAutocomplete: 'vn-item-niche vn-horizontal:nth-child(3) > vn-autocomplete[ng-model="niche.warehouseFk"]',
|
||||
thirdCodeInput: 'vn-item-niche vn-horizontal:nth-child(3) > vn-textfield[label="Code"] input',
|
||||
submitNichesButton: `vn-item-niche ${components.vnSubmit}`
|
||||
submitNichesButton: `vn-item-niche button[type=submit]`
|
||||
},
|
||||
itemBotanical: {
|
||||
botanicalInput: `vn-item-botanical vn-horizontal:nth-child(1) > ${components.vnTextfield}`,
|
||||
botanicalInput: `vn-item-botanical vn-horizontal:nth-child(1) > vn-textfield input`,
|
||||
genusAutocomplete: 'vn-item-botanical vn-autocomplete[ng-model="$ctrl.botanical.genusFk"]',
|
||||
speciesAutocomplete: 'vn-item-botanical vn-autocomplete[ng-model="$ctrl.botanical.specieFk"]',
|
||||
submitBotanicalButton: `vn-item-botanical ${components.vnSubmit}`
|
||||
submitBotanicalButton: `vn-item-botanical button[type=submit]`
|
||||
},
|
||||
itemSummary: {
|
||||
basicData: 'vn-item-summary [name="basicData"]',
|
||||
|
@ -330,13 +329,13 @@ export default {
|
|||
searchResult: 'vn-ticket-index vn-card > div > vn-table > div > vn-tbody > a.vn-tr',
|
||||
searchWeeklyResult: 'vn-ticket-weekly-index vn-table vn-tbody > vn-tr',
|
||||
searchResultDate: 'vn-ticket-index vn-table vn-tbody > a:nth-child(1) > vn-td:nth-child(5)',
|
||||
searchTicketInput: `vn-ticket-index ${components.vnTextfield}`,
|
||||
searchWeeklyTicketInput: `vn-ticket-weekly-index ${components.vnTextfield}`,
|
||||
searchTicketInput: `vn-ticket-index vn-textfield input`,
|
||||
searchWeeklyTicketInput: `vn-ticket-weekly-index vn-textfield input`,
|
||||
searchWeeklyClearInput: 'vn-ticket-weekly-index vn-searchbar vn-icon[icon=clear]',
|
||||
advancedSearchButton: 'vn-ticket-search-panel vn-submit[label="Search"] input',
|
||||
advancedSearchButton: 'vn-ticket-search-panel button[type=submit]',
|
||||
searchButton: 'vn-ticket-index vn-searchbar vn-icon[icon="search"]',
|
||||
searchWeeklyButton: 'vn-ticket-weekly-index vn-searchbar vn-icon[icon="search"]',
|
||||
moreMenu: 'vn-ticket-index vn-icon-menu[vn-id="more-button"] > div > vn-icon',
|
||||
moreMenu: 'vn-ticket-index vn-icon-menu[icon=more_vert]',
|
||||
moreMenuWeeklyTickets: '.vn-popover.shown .vn-drop-down li:nth-child(2)',
|
||||
sixthWeeklyTicket: 'vn-ticket-weekly-index vn-table vn-tr:nth-child(6) vn-autocomplete[ng-model="weekly.weekDay"] input',
|
||||
weeklyTicket: 'vn-ticket-weekly-index vn-table > div > vn-tbody > vn-tr',
|
||||
|
@ -349,13 +348,13 @@ export default {
|
|||
deliveryDateInput: 'vn-ticket-create vn-date-picker[ng-model="$ctrl.landed"]',
|
||||
warehouseAutocomplete: 'vn-ticket-create vn-autocomplete[ng-model="$ctrl.warehouseFk"]',
|
||||
agencyAutocomplete: 'vn-ticket-create vn-autocomplete[ng-model="$ctrl.ticket.agencyModeFk"]',
|
||||
createButton: `${components.vnSubmit}`
|
||||
createButton: `button[type=submit]`
|
||||
},
|
||||
ticketDescriptor: {
|
||||
idLabelValue: 'vn-ticket-descriptor vn-label-value[label="Id"]',
|
||||
stateLabelValue: 'vn-ticket-descriptor vn-label-value[label="State"]',
|
||||
goBackToModuleIndexButton: 'vn-ticket-descriptor a[ui-sref="ticket.index"]',
|
||||
moreMenu: 'vn-ticket-descriptor vn-icon-menu > div > vn-icon',
|
||||
moreMenu: 'vn-ticket-descriptor vn-icon-menu[icon=more_vert]',
|
||||
moreMenuAddStowaway: '.vn-popover.shown .vn-drop-down li[name="Add stowaway"]',
|
||||
moreMenuDeleteStowawayButton: '.vn-popover.shown .vn-drop-down li[name="Remove stowaway"]',
|
||||
moreMenuAddToTurn: '.vn-popover.shown .vn-drop-down li[name="Add turn"]',
|
||||
|
@ -363,9 +362,9 @@ export default {
|
|||
moreMenuMakeInvoice: '.vn-popover.shown .vn-drop-down li[name="Make invoice"]',
|
||||
moreMenuChangeShippedHour: '.vn-popover.shown .vn-drop-down li[name="Change shipped hour"]',
|
||||
changeShippedHourDialog: 'vn-ticket-descriptor vn-dialog[vn-id="changeShippedDialog"]',
|
||||
changeShippedHourInput: 'vn-ticket-descriptor vn-dialog[vn-id="changeShippedDialog"] vn-input-time[vn-id="newShipped"]',
|
||||
changeShippedHourInput: 'vn-dialog[vn-id="changeShippedDialog"] [ng-model="$ctrl.newShipped"]',
|
||||
addStowawayDialogFirstTicket: 'vn-ticket-descriptor > vn-add-stowaway > vn-dialog vn-table vn-tbody vn-tr',
|
||||
shipButton: 'vn-ticket-descriptor > div > div.body > div.quicklinks vn-icon[icon="icon-stowaway"]',
|
||||
shipButton: 'vn-ticket-descriptor vn-icon[icon="icon-stowaway"]',
|
||||
thursdayButton: 'vn-ticket-descriptor > vn-dialog > div > form > div.body > tpl-body > div > vn-tool-bar > vn-button:nth-child(4)',
|
||||
saturdayButton: 'vn-ticket-descriptor > vn-dialog > div > form > div.body > tpl-body > div > vn-tool-bar > vn-button:nth-child(6)',
|
||||
closeStowawayDialog: 'vn-ticket-descriptor > vn-add-stowaway > vn-dialog > div > button[class="close"]',
|
||||
|
@ -380,7 +379,7 @@ export default {
|
|||
addNoteButton: 'vn-icon[icon="add_circle"]',
|
||||
firstNoteTypeAutocomplete: 'vn-autocomplete[ng-model="observation.observationTypeFk"]',
|
||||
firstDescriptionInput: 'vn-textfield[label="Description"] input',
|
||||
submitNotesButton: `${components.vnSubmit}`
|
||||
submitNotesButton: `button[type=submit]`
|
||||
},
|
||||
ticketExpedition: {
|
||||
expeditionButton: 'vn-left-menu a[ui-sref="ticket.card.expedition"]',
|
||||
|
@ -395,7 +394,7 @@ export default {
|
|||
firstRemovePackageButton: 'vn-icon-button[vn-tooltip="Remove package"]',
|
||||
addPackageButton: 'vn-icon-button[vn-tooltip="Add package"]',
|
||||
clearPackageAutocompleteButton: 'vn-autocomplete[label="Package"] .icons > vn-icon[icon=clear]',
|
||||
savePackagesButton: `${components.vnSubmit}`
|
||||
savePackagesButton: `button[type=submit]`
|
||||
},
|
||||
ticketSales: {
|
||||
saleButton: 'vn-left-menu a[ui-sref="ticket.card.sale"]',
|
||||
|
@ -421,7 +420,6 @@ export default {
|
|||
firstSaleQuantity: 'vn-input-number[ng-model="sale.quantity"]:nth-child(1) input',
|
||||
firstSaleQuantityCell: 'vn-ticket-sale vn-tr:nth-child(1) > vn-td-editable:nth-child(5)',
|
||||
firstSaleQuantityClearInput: 'vn-textfield[ng-model="sale.quantity"] div.suffix > i',
|
||||
firstSaleIdInput: 'vn-ticket-sale vn-table vn-tbody > vn-tr:nth-child(1) > vn-td:nth-child(4) > vn-autocomplete input',
|
||||
firstSaleIdAutocomplete: 'vn-ticket-sale vn-table vn-tbody > vn-tr:nth-child(1) > vn-td:nth-child(4) > vn-autocomplete',
|
||||
idAutocompleteFirstResult: '.vn-popover.shown .vn-drop-down li',
|
||||
firstSalePrice: 'vn-ticket-sale vn-table vn-tr:nth-child(1) > vn-td:nth-child(7) > span',
|
||||
|
@ -461,9 +459,9 @@ export default {
|
|||
},
|
||||
ticketTracking: {
|
||||
trackingButton: 'vn-left-menu a[ui-sref="ticket.card.tracking.index"]',
|
||||
createStateButton: `${components.vnFloatButton}`,
|
||||
createStateButton: `vn-float-button`,
|
||||
stateAutocomplete: 'vn-ticket-tracking-edit vn-autocomplete[ng-model="$ctrl.stateFk"]',
|
||||
saveButton: `${components.vnSubmit}`,
|
||||
saveButton: `button[type=submit]`,
|
||||
cancelButton: 'vn-ticket-tracking-edit vn-button[ui-sref="ticket.card.tracking.index"]'
|
||||
},
|
||||
ticketBasicData: {
|
||||
|
@ -472,8 +470,8 @@ export default {
|
|||
addressAutocomplete: 'vn-autocomplete[ng-model="$ctrl.ticket.addressFk"]',
|
||||
agencyAutocomplete: 'vn-autocomplete[ng-model="$ctrl.agencyModeId"]',
|
||||
zoneAutocomplete: 'vn-autocomplete[ng-model="$ctrl.zoneId"]',
|
||||
nextStepButton: 'vn-step-control > section > section.buttons > section:nth-child(2) > vn-button',
|
||||
finalizeButton: 'vn-step-control > section > section.buttons > section:nth-child(2) > vn-submit',
|
||||
nextStepButton: 'vn-step-control .buttons > section:last-child vn-button',
|
||||
finalizeButton: 'vn-step-control .buttons > section:last-child button[type=submit]',
|
||||
stepTwoTotalPriceDif: 'vn-ticket-basic-data-step-two > form > vn-card > div > vn-horizontal > table > tfoot > tr > td:nth-child(4)',
|
||||
chargesReasonAutocomplete: 'vn-autocomplete[ng-model="$ctrl.ticket.option"]',
|
||||
},
|
||||
|
@ -484,11 +482,11 @@ export default {
|
|||
addRequestButton: 'vn-ticket-request-index > a > vn-float-button > button',
|
||||
request: 'vn-ticket-request-index vn-table vn-tr',
|
||||
descriptionInput: 'vn-ticket-request-create > form > div > vn-card > div > vn-horizontal:nth-child(1) > vn-textfield input',
|
||||
atenderAutocomplete: 'vn-ticket-request-create vn-autocomplete[ng-model="$ctrl.ticketRequest.atenderFk"]',
|
||||
atenderAutocomplete: 'vn-ticket-request-create vn-autocomplete[ng-model="$ctrl.ticketRequest.attenderFk"]',
|
||||
quantityInput: 'vn-ticket-request-create vn-input-number input[name=quantity]',
|
||||
priceInput: 'vn-ticket-request-create vn-input-number input[name=price]',
|
||||
firstRemoveRequestButton: 'vn-ticket-request-index vn-icon[icon="delete"]:nth-child(1)',
|
||||
saveButton: 'vn-ticket-request-create > form > div > vn-button-bar > vn-submit[label="Create"] input',
|
||||
saveButton: 'vn-ticket-request-create button[type=submit]',
|
||||
firstDescription: 'vn-ticket-request-index vn-table vn-tr:nth-child(1) > vn-td:nth-child(2)',
|
||||
|
||||
},
|
||||
|
@ -500,7 +498,7 @@ export default {
|
|||
},
|
||||
ticketService: {
|
||||
addServiceButton: 'vn-ticket-service vn-icon-button[vn-tooltip="Add service"] > button',
|
||||
firstAddDescriptionButton: 'vn-ticket-service vn-icon-button[vn-tooltip="New service type"] > button',
|
||||
firstAddDescriptionButton: 'vn-ticket-service vn-icon-button[vn-tooltip="New service type"]',
|
||||
firstDescriptionAutocomplete: 'vn-ticket-service vn-autocomplete[ng-model="service.description"]',
|
||||
firstQuantityInput: 'vn-ticket-service vn-input-number[label="Quantity"] input',
|
||||
firstPriceInput: 'vn-ticket-service vn-input-number[label="Price"] input',
|
||||
|
@ -508,22 +506,22 @@ export default {
|
|||
fistDeleteServiceButton: 'vn-ticket-service form vn-horizontal:nth-child(1) vn-icon-button[icon="delete"]',
|
||||
newDescriptionInput: 'vn-ticket-service > vn-dialog vn-textfield[ng-model="$ctrl.newServiceType.name"] input',
|
||||
serviceLine: 'vn-ticket-service > form > vn-card > div > vn-one:nth-child(2) > vn-horizontal',
|
||||
saveServiceButton: `${components.vnSubmit}`,
|
||||
saveServiceButton: `button[type=submit]`,
|
||||
saveDescriptionButton: 'vn-ticket-service > vn-dialog[vn-id="createServiceTypeDialog"] > div > form > div.buttons > tpl-buttons > button'
|
||||
},
|
||||
createStateView: {
|
||||
stateAutocomplete: 'vn-autocomplete[ng-model="$ctrl.stateFk"]',
|
||||
workerAutocomplete: 'vn-autocomplete[ng-model="$ctrl.workerFk"]',
|
||||
clearStateInputButton: 'vn-autocomplete[ng-model="$ctrl.stateFk"] .icons > vn-icon[icon=clear]',
|
||||
saveStateButton: `${components.vnSubmit}`
|
||||
saveStateButton: `button[type=submit]`
|
||||
},
|
||||
claimsIndex: {
|
||||
searchClaimInput: `vn-claim-index ${components.vnTextfield}`,
|
||||
searchClaimInput: `vn-claim-index vn-textfield input`,
|
||||
searchResult: 'vn-claim-index vn-card > div > vn-table > div > vn-tbody > a',
|
||||
searchButton: 'vn-claim-index vn-searchbar vn-icon[icon="search"]'
|
||||
},
|
||||
claimDescriptor: {
|
||||
moreMenu: 'vn-claim-descriptor vn-icon-menu[vn-id="more-button"]',
|
||||
moreMenu: 'vn-claim-descriptor vn-icon-menu[icon=more_vert]',
|
||||
moreMenuDeleteClaim: '.vn-popover.shown .vn-drop-down li[name="Delete claim"]',
|
||||
acceptDeleteClaim: 'vn-claim-descriptor > vn-confirm[vn-id="confirm-delete-claim"] button[response="ACCEPT"]'
|
||||
},
|
||||
|
@ -531,20 +529,20 @@ export default {
|
|||
header: 'vn-claim-summary > vn-card > div > h5',
|
||||
state: 'vn-claim-summary vn-label-value[label="State"] > section > span',
|
||||
observation: 'vn-claim-summary vn-textarea[ng-model="$ctrl.summary.claim.observation"] textarea',
|
||||
firstSaleItemId: 'vn-claim-summary vn-horizontal > vn-auto:nth-child(4) > vn-table > div > vn-tbody > vn-tr:nth-child(1) > vn-td:nth-child(1) > span',
|
||||
firstSaleItemId: 'vn-claim-summary vn-horizontal > vn-auto:nth-child(4) vn-table > div > vn-tbody > vn-tr:nth-child(1) > vn-td:nth-child(1) > span',
|
||||
firstSaleDescriptorImage: '.vn-popover.shown vn-item-descriptor img',
|
||||
itemDescriptorPopover: '.vn-popover.shown vn-item-descriptor',
|
||||
itemDescriptorPopoverItemDiaryButton: '.vn-popover.shown vn-item-descriptor a[href="#!/item/2/diary"]',
|
||||
firstDevelopmentWorker: 'vn-claim-summary vn-horizontal > vn-auto:nth-child(5) > vn-table > div > vn-tbody > vn-tr:nth-child(1) > vn-td:nth-child(4) > span',
|
||||
firstDevelopmentWorkerGoToClientButton: '.vn-popover.shown vn-worker-descriptor div.quicklinks > a[href="#!/client/21/summary"]',
|
||||
firstActionTicketId: 'vn-claim-summary > vn-card > div > vn-horizontal > vn-auto:nth-child(6) > vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(2) > span',
|
||||
firstDevelopmentWorker: 'vn-claim-summary vn-horizontal > vn-auto:nth-child(5) vn-table > div > vn-tbody > vn-tr:nth-child(1) > vn-td:nth-child(4) > span',
|
||||
firstDevelopmentWorkerGoToClientButton: '.vn-popover.shown vn-worker-descriptor vn-quick-links > a[href="#!/client/21/summary"]',
|
||||
firstActionTicketId: 'vn-claim-summary > vn-card > div > vn-horizontal > vn-auto:nth-child(6) vn-table > div > vn-tbody > vn-tr > vn-td:nth-child(2) > span',
|
||||
firstActionTicketDescriptor: '.vn-popover.shown vn-ticket-descriptor'
|
||||
},
|
||||
claimBasicData: {
|
||||
claimStateAutocomplete: 'vn-claim-basic-data vn-autocomplete[ng-model="$ctrl.claim.claimStateFk"]',
|
||||
responsabilityInputRange: 'vn-input-range',
|
||||
responsabilityInputRange: 'vn-range',
|
||||
observationInput: 'vn-textarea[ng-model="$ctrl.claim.observation"] textarea',
|
||||
saveButton: `${components.vnSubmit}`
|
||||
saveButton: `button[type=submit]`
|
||||
},
|
||||
claimDetail: {
|
||||
secondItemDiscount: 'vn-claim-detail > vn-vertical > vn-card > div > vn-vertical > vn-table > div > vn-tbody > vn-tr:nth-child(2) > vn-td:nth-child(6) > span',
|
||||
|
@ -570,7 +568,7 @@ export default {
|
|||
secondClaimResponsibleAutocomplete: 'vn-claim-development vn-horizontal:nth-child(2) vn-autocomplete[ng-model="claimDevelopment.claimResponsibleFk"]',
|
||||
secondClaimWorkerAutocomplete: 'vn-claim-development vn-horizontal:nth-child(2) vn-autocomplete[ng-model="claimDevelopment.workerFk"]',
|
||||
secondClaimRedeliveryAutocomplete: 'vn-claim-development vn-horizontal:nth-child(2) vn-autocomplete[ng-model="claimDevelopment.claimRedeliveryFk"]',
|
||||
saveDevelopmentButton: `${components.vnSubmit}`
|
||||
saveDevelopmentButton: `button[type=submit]`
|
||||
},
|
||||
claimAction: {
|
||||
importClaimButton: 'vn-claim-action vn-button[label="Import claim"]',
|
||||
|
@ -585,9 +583,9 @@ export default {
|
|||
searchResult: 'vn-order-index vn-card > div > vn-table > div > vn-tbody > a.vn-tr',
|
||||
searchResultDate: 'vn-order-index vn-table vn-tbody > a:nth-child(1) > vn-td:nth-child(4)',
|
||||
searchResultAddress: 'vn-order-index vn-table vn-tbody > a:nth-child(1) > vn-td:nth-child(6)',
|
||||
searchOrderInput: `vn-order-index ${components.vnTextfield}`,
|
||||
searchOrderInput: `vn-order-index vn-textfield input`,
|
||||
searchButton: 'vn-order-index vn-searchbar vn-icon[icon="search"]',
|
||||
createOrderButton: `${components.vnFloatButton}`,
|
||||
createOrderButton: `vn-float-button`,
|
||||
},
|
||||
orderDescriptor: {
|
||||
returnToModuleIndexButton: 'vn-order-descriptor a[ui-sref="order.index"]',
|
||||
|
@ -598,7 +596,7 @@ export default {
|
|||
addressAutocomplete: 'vn-autocomplete[label="Address"]',
|
||||
agencyAutocomplete: 'vn-autocomplete[label="Agency"]',
|
||||
landedDatePicker: 'vn-date-picker[label="Landed"]',
|
||||
createButton: `${components.vnSubmit}`,
|
||||
createButton: `button[type=submit]`,
|
||||
cancelButton: 'vn-button[href="#!/client/index"]'
|
||||
},
|
||||
orderCatalog: {
|
||||
|
@ -610,16 +608,16 @@ export default {
|
|||
openTagSearch: 'vn-catalog-filter > div > vn-vertical > vn-textfield[ng-model="$ctrl.value"] .append i',
|
||||
tagAutocomplete: 'vn-order-catalog-search-panel vn-autocomplete[ng-model="filter.tagFk"]',
|
||||
tagValueInput: 'vn-order-catalog-search-panel vn-textfield[ng-model="filter.value"] input',
|
||||
searchTagButton: 'vn-order-catalog-search-panel > div > form > vn-horizontal:nth-child(3) > vn-submit > input',
|
||||
thirdFilterRemoveButton: 'vn-catalog-filter > div > vn-horizontal.chips > vn-chip:nth-child(3) button',
|
||||
fourthFilterRemoveButton: 'vn-catalog-filter > div > vn-horizontal.chips > vn-chip:nth-child(4) button',
|
||||
searchTagButton: 'vn-order-catalog-search-panel button[type=submit]',
|
||||
thirdFilterRemoveButton: 'vn-catalog-filter .chips > vn-chip:nth-child(3) vn-icon[icon=cancel]',
|
||||
fourthFilterRemoveButton: 'vn-catalog-filter .chips > vn-chip:nth-child(4) vn-icon[icon=cancel]',
|
||||
},
|
||||
orderBasicData: {
|
||||
clientAutocomplete: 'vn-autocomplete[label="Client"]',
|
||||
addressAutocomplete: 'vn-autocomplete[label="Address"]',
|
||||
agencyAutocomplete: 'vn-autocomplete[label="Agency"]',
|
||||
observationInput: 'vn-textarea[label="Observation"] textarea',
|
||||
saveButton: `${components.vnSubmit}`,
|
||||
saveButton: `button[type=submit]`,
|
||||
acceptButton: 'vn-order-basic-data vn-confirm[vn-id="confirm"] button[response="ACCEPT"]'
|
||||
},
|
||||
orderLine: {
|
||||
|
@ -637,7 +635,7 @@ export default {
|
|||
vehicleAutoComplete: 'vn-route-create vn-autocomplete[ng-model="$ctrl.route.vehicleFk"]',
|
||||
agencyAutoComplete: 'vn-route-create vn-autocomplete[ng-model="$ctrl.route.agencyModeFk"]',
|
||||
descriptionInput: 'vn-route-create vn-textfield[ng-model="$ctrl.route.description"] input',
|
||||
submitButton: 'vn-route-create vn-submit > input[type="submit"]'
|
||||
submitButton: 'vn-route-create button[type=submit]'
|
||||
},
|
||||
routeDescriptor: {
|
||||
volume: 'vn-route-descriptor vn-label-value[label="Volume"] > section > span'
|
||||
|
@ -654,7 +652,7 @@ export default {
|
|||
createdDateInput: 'vn-route-basic-data vn-date-picker[ng-model="$ctrl.route.created"]',
|
||||
startedHourInput: 'vn-route-basic-data vn-input-time[ng-model="$ctrl.route.started"] input',
|
||||
finishedHourInput: 'vn-route-basic-data vn-input-time[ng-model="$ctrl.route.finished"] input',
|
||||
saveButton: 'vn-route-basic-data vn-submit[label="Save"] input'
|
||||
saveButton: 'vn-route-basic-data button[type=submit]'
|
||||
},
|
||||
routeTickets: {
|
||||
firstTicketPriority: 'vn-route-tickets vn-tr:nth-child(1) vn-textfield[ng-model="ticket.priority"] input',
|
||||
|
@ -669,10 +667,10 @@ export default {
|
|||
},
|
||||
workerPbx: {
|
||||
extensionInput: 'vn-worker-pbx vn-textfield[ng-model="$ctrl.worker.sip.extension"] input',
|
||||
saveButton: 'vn-worker-pbx vn-submit[label="Save"] input'
|
||||
saveButton: 'vn-worker-pbx button[type=submit]'
|
||||
},
|
||||
workerTimeControl: {
|
||||
timeDialogInput: 'vn-worker-time-control > vn-dialog input',
|
||||
timeDialogInput: '.vn-dialog.shown [ng-model="$ctrl.newTime"]',
|
||||
mondayAddTimeButton: 'vn-worker-time-control > div > vn-card > div > vn-horizontal > vn-table > div > vn-tfoot > vn-tr:nth-child(2) > vn-td:nth-child(1) > vn-icon-button > button > vn-icon',
|
||||
tuesdayAddTimeButton: 'vn-worker-time-control > div > vn-card > div > vn-horizontal > vn-table > div > vn-tfoot > vn-tr:nth-child(2) > vn-td:nth-child(2) > vn-icon-button > button > vn-icon',
|
||||
wednesdayAddTimeButton: 'vn-worker-time-control > div > vn-card > div > vn-horizontal > vn-table > div > vn-tfoot > vn-tr:nth-child(2) > vn-td:nth-child(3) > vn-icon-button > button > vn-icon',
|
||||
|
@ -721,12 +719,12 @@ export default {
|
|||
navigateBackToIndex: 'vn-worker-descriptor vn-icon[icon="chevron_left"]'
|
||||
},
|
||||
invoiceOutIndex: {
|
||||
searchInvoiceOutInput: `vn-invoice-out-index ${components.vnTextfield}`,
|
||||
searchInvoiceOutInput: `vn-invoice-out-index vn-textfield input`,
|
||||
searchButton: 'vn-invoice-out-index vn-searchbar vn-icon[icon="search"]',
|
||||
searchResult: 'vn-invoice-out-index vn-card > div > vn-table > div > vn-tbody > a.vn-tr',
|
||||
},
|
||||
invoiceOutDescriptor: {
|
||||
moreMenu: 'vn-invoice-out-descriptor vn-icon-menu[vn-id="more-button"]',
|
||||
moreMenu: 'vn-invoice-out-descriptor vn-icon-menu[icon=more_vert]',
|
||||
moreMenuDeleteInvoiceOut: '.vn-popover.shown .vn-drop-down li[name="Delete Invoice"]',
|
||||
moreMenuBookInvoiceOut: '.vn-popover.shown .vn-drop-down li[name="Book invoice"]',
|
||||
moreMenuShowInvoiceOutPdf: '.vn-popover.shown .vn-drop-down li[name="Show invoice PDF"]',
|
||||
|
|
|
@ -1,58 +1,35 @@
|
|||
import createNightmare from '../../helpers/nightmare';
|
||||
import config from '../../helpers/config.js';
|
||||
|
||||
|
||||
describe('Login path', () => {
|
||||
const nightmare = createNightmare();
|
||||
|
||||
it('should receive an error when the username is incorrect', async() => {
|
||||
const username = 'nobody';
|
||||
const password = 'nightmare';
|
||||
|
||||
const result = await nightmare
|
||||
.goto(`${config.url}/#!/login`)
|
||||
.wait(`vn-login input[name=user]`)
|
||||
.write(`vn-login input[name=user]`, username)
|
||||
.write(`vn-login input[name=password]`, password)
|
||||
.click(`vn-login input[type=submit]`)
|
||||
.doLogin('badUser', null)
|
||||
.waitForLastSnackbar();
|
||||
|
||||
expect(result.length).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
it('should receive an error when the username is blank', async() => {
|
||||
const password = 'nightmare';
|
||||
|
||||
const result = await nightmare
|
||||
.clearInput(`vn-login input[name=user]`)
|
||||
.write(`vn-login input[name=password]`, password)
|
||||
.click(`vn-login input[type=submit]`)
|
||||
.doLogin('', null)
|
||||
.waitForLastSnackbar();
|
||||
|
||||
expect(result.length).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
it('should receive an error when the password is incorrect', async() => {
|
||||
const username = 'employee';
|
||||
const password = 'badpassword';
|
||||
|
||||
const result = await nightmare
|
||||
.write(`vn-login input[name=user]`, username)
|
||||
.write(`vn-login input[name=password]`, password)
|
||||
.click(`vn-login input[type=submit]`)
|
||||
.doLogin('employee', 'badPassword')
|
||||
.waitForLastSnackbar();
|
||||
|
||||
expect(result.length).toBeGreaterThan(0);
|
||||
});
|
||||
|
||||
it('should log in', async() => {
|
||||
const username = 'employee';
|
||||
const password = 'nightmare';
|
||||
|
||||
const url = await nightmare
|
||||
.write(`vn-login input[name=user]`, username)
|
||||
.write(`vn-login input[name=password]`, password)
|
||||
.click(`vn-login input[type=submit]`)
|
||||
.doLogin('employee', null)
|
||||
.wait('#logout')
|
||||
.parsedUrl();
|
||||
|
||||
|
|
|
@ -42,9 +42,7 @@ describe('Client Edit fiscalData path', () => {
|
|||
it('should not be able to edit the verified data checkbox', async() => {
|
||||
const result = await nightmare
|
||||
.wait(selectors.clientFiscalData.verifiedDataCheckbox)
|
||||
.evaluate(selector => {
|
||||
return document.querySelector(selector).getAttribute('disabled');
|
||||
}, selectors.clientFiscalData.verifiedDataCheckbox);
|
||||
.isDisabled(selectors.clientFiscalData.verifiedDataCheckbox);
|
||||
|
||||
expect(result).toBeTruthy();
|
||||
});
|
||||
|
|
|
@ -16,9 +16,7 @@ describe('Client lock verified data path', () => {
|
|||
const result = await nightmare
|
||||
.wait(200)
|
||||
.wait(selectors.clientFiscalData.verifiedDataCheckbox)
|
||||
.evaluate(selector => {
|
||||
return document.querySelector(selector).getAttribute('disabled');
|
||||
}, selectors.clientFiscalData.verifiedDataCheckbox);
|
||||
.isDisabled(selectors.clientFiscalData.verifiedDataCheckbox);
|
||||
|
||||
expect(result).toBeTruthy();
|
||||
});
|
||||
|
|
|
@ -358,7 +358,7 @@ describe('Worker time control path', () => {
|
|||
it(`should check Hank Pym doesn't have hours set on the next months first week`, async() => {
|
||||
const wholeWeekHours = await nightmare
|
||||
.waitToClick(selectors.workerTimeControl.nextMonthButton)
|
||||
.waitToClick(selectors.workerTimeControl.nextMonthButton)
|
||||
.waitForTextInElement(selectors.workerTimeControl.weekWorkedHours, '00:00 Hours')
|
||||
.waitToGetProperty(selectors.workerTimeControl.weekWorkedHours, 'innerText');
|
||||
|
||||
expect(wholeWeekHours).toEqual('00:00 Hours');
|
||||
|
|
|
@ -30,6 +30,7 @@ describe('Ticket Edit basic data path', () => {
|
|||
|
||||
it(`should confirm the zone autocomplete is enabled for the role productionBoss`, async() => {
|
||||
const disabled = await nightmare
|
||||
.waitForSpinnerLoad()
|
||||
.wait(selectors.ticketBasicData.zoneAutocomplete)
|
||||
.evaluate(selector => {
|
||||
return document.querySelector(selector).disabled;
|
||||
|
|
|
@ -34,7 +34,7 @@ describe('Ticket descriptor path', () => {
|
|||
const result = await nightmare
|
||||
.waitToClick(selectors.ticketDescriptor.moreMenu)
|
||||
.waitToClick(selectors.ticketDescriptor.moreMenuChangeShippedHour)
|
||||
.write(selectors.ticketDescriptor.changeShippedHourInput, '08:15')
|
||||
.pickTime(selectors.ticketDescriptor.changeShippedHourInput, '08:15')
|
||||
.waitToClick(selectors.ticketDescriptor.acceptChangeHourButton)
|
||||
.waitForLastSnackbar();
|
||||
|
||||
|
|
|
@ -17,9 +17,7 @@ describe('Ticket services path', () => {
|
|||
const result = await nightmare
|
||||
.waitToClick(selectors.ticketService.addServiceButton)
|
||||
.wait(selectors.ticketService.firstAddDescriptionButton)
|
||||
.evaluate(selector => {
|
||||
return document.querySelector(selector).disabled;
|
||||
}, selectors.ticketService.firstAddDescriptionButton);
|
||||
.isDisabled(selectors.ticketService.firstAddDescriptionButton);
|
||||
|
||||
expect(result).toBeTruthy();
|
||||
});
|
||||
|
|
|
@ -66,7 +66,7 @@ describe('Order catalog', () => {
|
|||
const result = await nightmare
|
||||
.waitToClick(selectors.orderCatalog.fourthFilterRemoveButton)
|
||||
.waitToClick(selectors.orderCatalog.thirdFilterRemoveButton)
|
||||
.waitForNumberOfElements('section.product', 4)
|
||||
.waitForNumberOfElements('.product', 4)
|
||||
.countElement('section.product');
|
||||
|
||||
expect(result).toEqual(4);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<div
|
||||
class="container"
|
||||
ng-click="$ctrl.onContainerMouseDown($event)"
|
||||
ng-click="$ctrl.onContainerClick($event)"
|
||||
ng-keydown="$ctrl.onContainerKeyDown($event)">
|
||||
<div
|
||||
ng-transclude="prepend"
|
||||
|
@ -48,5 +48,5 @@
|
|||
vn-id="drop-down"
|
||||
on-select="$ctrl.onDropDownSelect(item)"
|
||||
on-data-ready="$ctrl.onDataReady()"
|
||||
on-close="$ctrl.focus()">
|
||||
on-close-start="$ctrl.focus()">
|
||||
</vn-drop-down>
|
|
@ -228,7 +228,7 @@ export default class Autocomplete extends Field {
|
|||
event.preventDefault();
|
||||
}
|
||||
|
||||
onContainerMouseDown(event) {
|
||||
onContainerClick(event) {
|
||||
if (event.defaultPrevented) return;
|
||||
event.preventDefault();
|
||||
this.showDropDown();
|
||||
|
@ -260,6 +260,7 @@ export default class Autocomplete extends Field {
|
|||
}
|
||||
|
||||
showDropDown(search) {
|
||||
if (this.readonly) return;
|
||||
this.assignDropdownProps();
|
||||
this.$.dropDown.show(this.container, search);
|
||||
}
|
||||
|
|
|
@ -20,4 +20,7 @@ vn-autocomplete.vn-field {
|
|||
}
|
||||
}
|
||||
}
|
||||
&.readonly > .container > .icons.post {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
<div class="button-menu">
|
||||
<button
|
||||
class="mdl-button mdl-js-button mdl-button--raised mdl-button--colored button-menu__button">
|
||||
<vn-label vn-none translate>{{::$ctrl.label}}</vn-label>
|
||||
<vn-icon vn-none icon="{{::$ctrl.icon}}"></vn-icon>
|
||||
<vn-icon vn-none class="button-menu__arrow_down" icon="keyboard_arrow_down"></vn-icon>
|
||||
</button>
|
||||
<vn-drop-down
|
||||
vn-id="drop-down"
|
||||
on-select="$ctrl.onDropDownSelect(item)"
|
||||
ng-click="$ctrl.onDropDownClick($event)">
|
||||
</vn-drop-down>
|
||||
</div>
|
|
@ -0,0 +1,20 @@
|
|||
<button>
|
||||
<span
|
||||
ng-if="::$ctrl.label"
|
||||
translate>
|
||||
{{::$ctrl.label}}
|
||||
</span>
|
||||
<vn-icon
|
||||
ng-if="::$ctrl.icon"
|
||||
icon="{{::$ctrl.icon}}">
|
||||
</vn-icon>
|
||||
<vn-icon
|
||||
class="button-menu__arrow_down"
|
||||
icon="keyboard_arrow_down">
|
||||
</vn-icon>
|
||||
</button>
|
||||
<vn-drop-down
|
||||
vn-id="drop-down"
|
||||
on-select="$ctrl.onDropDownSelect(item)"
|
||||
ng-click="$ctrl.onDropDownClick($event)">
|
||||
</vn-drop-down>
|
|
@ -1,17 +1,13 @@
|
|||
import ngModule from '../../module';
|
||||
import Input from '../../lib/input';
|
||||
import Button from '../button';
|
||||
import assignProps from '../../lib/assign-props';
|
||||
import './style.scss';
|
||||
|
||||
export default class ButtonMenu extends Input {
|
||||
export default class ButtonMenu extends Button {
|
||||
constructor($element, $scope, $transclude) {
|
||||
super($element, $scope);
|
||||
this.$transclude = $transclude;
|
||||
this.input = this.element.querySelector('.mdl-button');
|
||||
$element.on('click', e => {
|
||||
if (!this.disabled)
|
||||
this.onClick(e);
|
||||
});
|
||||
$element.on('click', e => this.onClick(e));
|
||||
}
|
||||
|
||||
get model() {
|
||||
|
@ -46,6 +42,7 @@ export default class ButtonMenu extends Input {
|
|||
}
|
||||
|
||||
onClick(event) {
|
||||
if (this.disabled) return;
|
||||
if (event.defaultPrevented) return;
|
||||
event.preventDefault();
|
||||
this.emit('open');
|
||||
|
@ -85,15 +82,14 @@ export default class ButtonMenu extends Input {
|
|||
}
|
||||
ButtonMenu.$inject = ['$element', '$scope', '$transclude'];
|
||||
|
||||
ngModule.component('vnButtonMenu', {
|
||||
template: require('./button-menu.html'),
|
||||
ngModule.vnComponent('vnButtonMenu', {
|
||||
template: require('./index.html'),
|
||||
controller: ButtonMenu,
|
||||
bindings: {
|
||||
label: '@',
|
||||
showField: '@?',
|
||||
selection: '<?',
|
||||
valueField: '@?',
|
||||
selectFields: '<?',
|
||||
disabled: '<?',
|
||||
initialData: '<?',
|
||||
showFilter: '<?',
|
||||
field: '=?',
|
||||
|
@ -104,12 +100,10 @@ ngModule.component('vnButtonMenu', {
|
|||
limit: '<?',
|
||||
multiple: '<?',
|
||||
onChange: '&?',
|
||||
icon: '@?',
|
||||
translateFields: '<?',
|
||||
onOpen: '&?'
|
||||
},
|
||||
transclude: {
|
||||
tplItem: '?tplItem'
|
||||
},
|
||||
controller: ButtonMenu
|
||||
}
|
||||
});
|
|
@ -1,19 +1,3 @@
|
|||
vn-button-menu {
|
||||
position: relative;
|
||||
cursor: pointer;
|
||||
|
||||
.button-menu__button {
|
||||
padding: 0 10px;
|
||||
}
|
||||
vn-label {
|
||||
float: left;
|
||||
margin-top: 1px;
|
||||
}
|
||||
vn-icon {
|
||||
float: left;
|
||||
margin-top: 3px;
|
||||
}
|
||||
vn-icon.button-menu__arrow_down {
|
||||
margin: 6px 0 0 5px;
|
||||
}
|
||||
}
|
|
@ -1,6 +0,0 @@
|
|||
<button type="{{::$ctrl.type}}" class="mdl-button mdl-js-button mdl-button--raised mdl-button--colored">
|
||||
<span translate>{{$ctrl.label}}</span>
|
||||
<vn-icon
|
||||
icon="{{::$ctrl.icon}}">
|
||||
</vn-icon>
|
||||
</button>
|
|
@ -1,34 +0,0 @@
|
|||
import ngModule from '../../module';
|
||||
import Input from '../../lib/input';
|
||||
import './style.scss';
|
||||
|
||||
export default class Button extends Input {
|
||||
constructor($element) {
|
||||
super($element);
|
||||
this.$element = $element;
|
||||
this.input = this.element.querySelector('.mdl-button');
|
||||
|
||||
$element[0].addEventListener('click', event => {
|
||||
if (this.disabled)
|
||||
event.stopImmediatePropagation();
|
||||
});
|
||||
}
|
||||
|
||||
$onInit() {
|
||||
if (!this.type)
|
||||
this.type = 'button';
|
||||
}
|
||||
}
|
||||
Button.$inject = ['$element'];
|
||||
|
||||
ngModule.component('vnButton', {
|
||||
controller: Button,
|
||||
template: require('./button.html'),
|
||||
bindings: {
|
||||
label: '@?',
|
||||
disabled: '<?',
|
||||
icon: '@?',
|
||||
type: '@?'
|
||||
}
|
||||
});
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
<button type="{{::$ctrl.type}}" tabindex="-1">
|
||||
<span
|
||||
ng-if="::$ctrl.label"
|
||||
translate>
|
||||
{{::$ctrl.label}}
|
||||
</span>
|
||||
<vn-icon
|
||||
ng-if="::$ctrl.icon"
|
||||
icon="{{::$ctrl.icon}}">
|
||||
</vn-icon>
|
||||
</button>
|
|
@ -0,0 +1,46 @@
|
|||
import ngModule from '../../module';
|
||||
import FormInput from '../form-input';
|
||||
import './style.scss';
|
||||
|
||||
export default class Button extends FormInput {
|
||||
constructor($element, $scope) {
|
||||
super($element, $scope);
|
||||
this.design = 'colored';
|
||||
this.input = this.element.querySelector('button');
|
||||
|
||||
let element = this.element;
|
||||
element.tabIndex = 0;
|
||||
element.classList.add('vn-button');
|
||||
this.element.addEventListener('keyup', e => this.onKeyup(e));
|
||||
this.element.addEventListener('click', e => this.onClick(e));
|
||||
}
|
||||
|
||||
$onInit() {
|
||||
this.element.classList.add(this.design);
|
||||
if (!this.type) this.type = 'button';
|
||||
}
|
||||
|
||||
onKeyup(event) {
|
||||
if (event.code == 'Space')
|
||||
this.onClick(event);
|
||||
}
|
||||
|
||||
onClick(event) {
|
||||
if (event.defaultPrevented) return;
|
||||
// event.preventDefault();
|
||||
|
||||
// FIXME: Don't stop event propagation
|
||||
if (this.disabled) event.stopImmediatePropagation();
|
||||
}
|
||||
}
|
||||
Button.$inject = ['$element', '$scope'];
|
||||
|
||||
ngModule.vnComponent('vnButton', {
|
||||
controller: Button,
|
||||
template: require('./index.html'),
|
||||
bindings: {
|
||||
icon: '@?',
|
||||
type: '@?'
|
||||
}
|
||||
});
|
||||
|
|
@ -1,5 +1,83 @@
|
|||
vn-button {
|
||||
& > button > vn-icon {
|
||||
vertical-align: middle;
|
||||
@import "variables";
|
||||
|
||||
.vn-button {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 36px;
|
||||
border: none;
|
||||
border-radius: .1em;
|
||||
font-family: vn-font-bold;
|
||||
text-transform: uppercase;
|
||||
font-size: 14px;
|
||||
cursor: pointer;
|
||||
box-sizing: border-box;
|
||||
outline: none;
|
||||
|
||||
& > button {
|
||||
width: 100%;
|
||||
padding: 0 12px;
|
||||
box-sizing: border-box;
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
height: inherit;
|
||||
color: inherit;
|
||||
font: inherit;
|
||||
display: block;
|
||||
text-transform: inherit;
|
||||
cursor: inherit;
|
||||
outline: none;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
& > vn-icon {
|
||||
vertical-align: middle;
|
||||
color: inherit;
|
||||
font-size: 1.7em;
|
||||
}
|
||||
}
|
||||
}
|
||||
&.colored {
|
||||
color: white;
|
||||
background-color: $color-main;
|
||||
box-shadow: 0 .15em .15em 0 rgba(0, 0, 0, .3);
|
||||
transition: background 200ms ease-in-out;
|
||||
|
||||
&:not(.disabled) {
|
||||
&:hover,
|
||||
&:focus {
|
||||
background-color: lighten($color-main, 10%);
|
||||
}
|
||||
}
|
||||
}
|
||||
&.flat {
|
||||
color: $color-main;
|
||||
background-color: transparent;
|
||||
box-shadow: none;
|
||||
transition: background 200ms ease-in-out;
|
||||
|
||||
&:not(.disabled) {
|
||||
&:hover,
|
||||
&:focus {
|
||||
background-color: $color-hover-cd;
|
||||
}
|
||||
}
|
||||
}
|
||||
&:hover,
|
||||
&:focus {
|
||||
outline: none;
|
||||
}
|
||||
&.round {
|
||||
border-radius: 50%;
|
||||
height: 3.8em;
|
||||
width: 3.8em;
|
||||
|
||||
& > button > span {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
&.disabled {
|
||||
opacity: .7;
|
||||
cursor: initial;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ export default function directive() {
|
|||
transclude: true,
|
||||
template: require('./card.html'),
|
||||
link: function($scope, $element, $attrs, $ctrl, $transclude) {
|
||||
$element.addClass('demo-card-wide mdl-shadow--2dp bg-panel');
|
||||
$element.addClass('demo-card-wide vn-shadow bg-panel');
|
||||
|
||||
$transclude($scope, function(clone) {
|
||||
angular.element($element[0].querySelector('div')).append(clone);
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
vn-card {
|
||||
display: block;
|
||||
box-sizing: border-box;
|
||||
}
|
|
@ -1,8 +1,7 @@
|
|||
<vn-one>
|
||||
<span ng-class="{'mdl-chip--deletable': !$ctrl.disabled}" class="mdl-chip">
|
||||
<span class="mdl-chip__text ellipsize" ng-transclude></span>
|
||||
<button ng-click="$ctrl.remove()" ng-show="!$ctrl.disabled" type="button" class="mdl-chip__action">
|
||||
<i class="material-icons">cancel</i>
|
||||
</button>
|
||||
</span>
|
||||
</vn-one>
|
||||
<div ng-transclude></div>
|
||||
<vn-icon
|
||||
ng-click="$ctrl.onRemove()"
|
||||
ng-if="$ctrl.removable"
|
||||
icon="cancel"
|
||||
tabindex="0">
|
||||
</vn-icon>
|
|
@ -1,17 +1,12 @@
|
|||
import ngModule from '../../module';
|
||||
import Component from '../../lib/component';
|
||||
import './style.scss';
|
||||
|
||||
export default class Chip {
|
||||
|
||||
/**
|
||||
* Remove chip event
|
||||
*/
|
||||
remove() {
|
||||
if (this.onRemove)
|
||||
this.onRemove();
|
||||
export default class Chip extends Component {
|
||||
onRemove() {
|
||||
if (!this.disabled) this.emit('remove');
|
||||
}
|
||||
}
|
||||
|
||||
Chip.$inject = ['$element', '$scope', '$transclude'];
|
||||
|
||||
ngModule.component('vnChip', {
|
||||
|
@ -20,6 +15,6 @@ ngModule.component('vnChip', {
|
|||
transclude: true,
|
||||
bindings: {
|
||||
disabled: '<?',
|
||||
onRemove: '&?'
|
||||
removable: '<?'
|
||||
}
|
||||
});
|
||||
|
|
|
@ -16,13 +16,13 @@ describe('Component vnChip', () => {
|
|||
controller = $componentController('vnChip', {$element, $scope, $transclude: () => {}});
|
||||
}));
|
||||
|
||||
describe('remove()', () => {
|
||||
it(`should call onRemove()`, () => {
|
||||
controller.onRemove = () => {};
|
||||
spyOn(controller, 'onRemove');
|
||||
controller.remove();
|
||||
describe('onRemove()', () => {
|
||||
it(`should emit remove event`, () => {
|
||||
controller.emit = () => {};
|
||||
spyOn(controller, 'emit');
|
||||
controller.onRemove();
|
||||
|
||||
expect(controller.onRemove).toHaveBeenCalledWith();
|
||||
expect(controller.emit).toHaveBeenCalledWith('remove');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,18 +1,53 @@
|
|||
@import "variables";
|
||||
|
||||
vn-chip {
|
||||
border-radius: 16px;
|
||||
background-color: $color-bg;
|
||||
margin: 0 0.5em 0.5em 0;
|
||||
color: $color-font;
|
||||
font-size: 14px;
|
||||
margin: .25em;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
height: 28px;
|
||||
padding: 0 .7em;
|
||||
overflow: hidden;
|
||||
|
||||
.mdl-chip {
|
||||
background-color: rgba($color-main, 0.9);
|
||||
color: #FFF
|
||||
&.colored {
|
||||
background-color: $color-main;
|
||||
color: $color-font-dark;
|
||||
}
|
||||
|
||||
.mdl-chip:active {
|
||||
background-color: $color-main
|
||||
}
|
||||
|
||||
& > vn-one > span > span {
|
||||
& > div {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
max-width: 100%;
|
||||
height: 100%;
|
||||
|
||||
& > vn-avatar {
|
||||
margin-left: -0.7em;
|
||||
margin-right: .4em;
|
||||
}
|
||||
}
|
||||
& > vn-icon {
|
||||
margin-left: .2em;
|
||||
margin-right: -0.3em;
|
||||
vertical-align: middle;
|
||||
opacity: .6;
|
||||
cursor: pointer;
|
||||
transition: opacity 250ms ease-out;
|
||||
|
||||
&:hover,
|
||||
&:focus {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vn-avatar {
|
||||
display: inline-block;
|
||||
height: 28px;
|
||||
width: 28px;
|
||||
border-radius: 50%;
|
||||
}
|
|
@ -1,8 +0,0 @@
|
|||
<span
|
||||
ng-class="{'pointer': $ctrl.$attrs['onClick']}"
|
||||
class="mdl-chip mdl-chip--contact"
|
||||
ng-repeat="legend in $ctrl.data track by $index"
|
||||
ng-click="$ctrl.onClick(legend)">
|
||||
<span class="mdl-chip__contact" ng-style="{backgroundColor: legend.color}"></span>
|
||||
<span class="mdl-chip__text">{{legend.name}}</span>
|
||||
</span>
|
|
@ -1,24 +0,0 @@
|
|||
import ngModule from '../../module';
|
||||
import Component from '../../lib/component';
|
||||
import './style.scss';
|
||||
|
||||
export default class Controller extends Component {
|
||||
constructor($element, $scope, $attrs) {
|
||||
super($element, $scope);
|
||||
this.$attrs = $attrs;
|
||||
}
|
||||
|
||||
onClick(legend) {
|
||||
this.emit('click', {legend});
|
||||
}
|
||||
}
|
||||
|
||||
Controller.$inject = ['$element', '$scope', '$attrs'];
|
||||
|
||||
ngModule.component('vnColorLegend', {
|
||||
template: require('./index.html'),
|
||||
controller: Controller,
|
||||
bindings: {
|
||||
data: '<?'
|
||||
}
|
||||
});
|
|
@ -1,13 +0,0 @@
|
|||
@import "variables";
|
||||
|
||||
.mdl-chip--contact {
|
||||
margin-left: 5px;
|
||||
height: 20px;
|
||||
line-height: 5px;
|
||||
float: left
|
||||
}
|
||||
|
||||
.mdl-chip--contact .mdl-chip__contact {
|
||||
height: 20px;
|
||||
width: 20px
|
||||
}
|
|
@ -1,15 +1,40 @@
|
|||
import ngModule from '../../module';
|
||||
import Field from '../field';
|
||||
import {Flatpickr} from '../../vendor';
|
||||
import './style.scss';
|
||||
|
||||
class DatePicker extends Field {
|
||||
constructor($element, $scope, $compile, $translate) {
|
||||
constructor($element, $scope, $compile, $translate, $filter) {
|
||||
super($element, $scope, $compile);
|
||||
this.$translate = $translate;
|
||||
this.$filter = $filter;
|
||||
|
||||
this.input = $compile(`<input type="text"></input>`)($scope)[0];
|
||||
this.initPicker();
|
||||
this.input = $compile(`<input type="date"></input>`)($scope)[0];
|
||||
this.input.addEventListener('change', () => this.onValueUpdate());
|
||||
}
|
||||
|
||||
onValueUpdate() {
|
||||
let date = null;
|
||||
let value = this.input.value;
|
||||
|
||||
if (value) {
|
||||
date = new Date(value);
|
||||
|
||||
if (this.field) {
|
||||
let orgDate = this.field instanceof Date
|
||||
? this.field
|
||||
: new Date(this.field);
|
||||
|
||||
date.setHours(
|
||||
orgDate.getHours(),
|
||||
orgDate.getMinutes(),
|
||||
orgDate.getSeconds(),
|
||||
orgDate.getMilliseconds()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
super.field = date;
|
||||
this.$.$applyAsync();
|
||||
}
|
||||
|
||||
get field() {
|
||||
|
@ -18,69 +43,10 @@ class DatePicker extends Field {
|
|||
|
||||
set field(value) {
|
||||
super.field = value;
|
||||
|
||||
let date = value;
|
||||
if (date && !(date instanceof Date))
|
||||
date = new Date(date);
|
||||
|
||||
this.picker.setDate(fixDate(date));
|
||||
}
|
||||
|
||||
set options(value) {
|
||||
let selectedDates = this.picker.selectedDates || [];
|
||||
this._options = value;
|
||||
this.initPicker();
|
||||
this.picker.setDate(selectedDates[0]);
|
||||
}
|
||||
|
||||
get options() {
|
||||
return this._options;
|
||||
}
|
||||
|
||||
initPicker() {
|
||||
let locale = this.$translate.use();
|
||||
let format = locale == 'es' ? 'd-m-Y' : 'Y-m-d';
|
||||
|
||||
let options = this.options || {};
|
||||
let defaultOptions = {
|
||||
locale: locale,
|
||||
dateFormat: format,
|
||||
enableTime: false,
|
||||
disableMobile: true,
|
||||
onValueUpdate: () => this.onValueUpdate()
|
||||
};
|
||||
|
||||
if (options.enableTime) {
|
||||
Object.assign(defaultOptions, {
|
||||
dateFormat: `${format} h:i`,
|
||||
time_24hr: true
|
||||
});
|
||||
}
|
||||
|
||||
let mergedOptions = Object.assign({},
|
||||
defaultOptions,
|
||||
options
|
||||
);
|
||||
|
||||
if (this.picker) this.picker.destroy();
|
||||
this.picker = new Flatpickr(this.input, mergedOptions);
|
||||
}
|
||||
|
||||
onValueUpdate() {
|
||||
let date = null;
|
||||
|
||||
if (this.picker.selectedDates.length)
|
||||
date = this.picker.selectedDates[0];
|
||||
|
||||
super.field = fixDate(date, -1);
|
||||
this.$.$applyAsync();
|
||||
}
|
||||
|
||||
$onDestroy() {
|
||||
this.picker.destroy();
|
||||
this.input.value = this.$filter('date')(value, 'yyyy-MM-dd');
|
||||
}
|
||||
}
|
||||
DatePicker.$inject = ['$element', '$scope', '$compile', '$translate'];
|
||||
DatePicker.$inject = ['$element', '$scope', '$compile', '$translate', '$filter'];
|
||||
|
||||
ngModule.vnComponent('vnDatePicker', {
|
||||
controller: DatePicker,
|
||||
|
@ -88,12 +54,3 @@ ngModule.vnComponent('vnDatePicker', {
|
|||
options: '<?'
|
||||
}
|
||||
});
|
||||
|
||||
function fixDate(date, mult = 1) {
|
||||
if (date) {
|
||||
let offset = date.getTimezoneOffset() * 60000;
|
||||
date.setTime(date.getTime() + (offset * mult));
|
||||
}
|
||||
|
||||
return date;
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@ describe('Component vnDatePicker', () => {
|
|||
let $filter;
|
||||
let $element;
|
||||
let $ctrl;
|
||||
let today;
|
||||
|
||||
beforeEach(angular.mock.module('vnCore', $translateProvider => {
|
||||
$translateProvider.translations('en', {});
|
||||
|
@ -13,9 +12,6 @@ describe('Component vnDatePicker', () => {
|
|||
|
||||
$element = $compile(`<vn-date-picker></vn-date-picker>`)($rootScope);
|
||||
$ctrl = $element.controller('vnDatePicker');
|
||||
|
||||
today = new Date();
|
||||
today.setUTCHours(0, 0, 0, 0);
|
||||
}));
|
||||
|
||||
afterEach(() => {
|
||||
|
@ -24,20 +20,12 @@ describe('Component vnDatePicker', () => {
|
|||
|
||||
describe('field() setter', () => {
|
||||
it(`should display the formated the date`, () => {
|
||||
let today;
|
||||
today = new Date();
|
||||
today.setHours(0, 0, 0, 0);
|
||||
|
||||
$ctrl.field = today;
|
||||
|
||||
let displayed = $filter('dateTime')(today, 'yyyy-MM-dd');
|
||||
|
||||
expect($ctrl.value).toEqual(displayed);
|
||||
});
|
||||
});
|
||||
|
||||
describe('options() setter', () => {
|
||||
it(`should display the date with the new format`, () => {
|
||||
$ctrl.options = {dateFormat: 'Y-m'};
|
||||
$ctrl.field = today;
|
||||
|
||||
let displayed = $filter('dateTime')(today, 'yyyy-MM');
|
||||
let displayed = $filter('date')(today, 'yyyy-MM-dd');
|
||||
|
||||
expect($ctrl.value).toEqual(displayed);
|
||||
});
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
<vn-popover
|
||||
vn-id="popover"
|
||||
on-open="$ctrl.onOpen()"
|
||||
on-close="$ctrl.onClose()">
|
||||
on-close="$ctrl.onClose()"
|
||||
on-close-start="$ctrl.emit('closeStart')">
|
||||
<div class="vn-drop-down">
|
||||
<div ng-show="$ctrl.showFilter" class="filter">
|
||||
<vn-textfield
|
||||
|
|
|
@ -193,7 +193,7 @@ export default class DropDown extends Component {
|
|||
onOpen() {
|
||||
this.document.addEventListener('keydown', this.docKeyDownHandler);
|
||||
this.$.list.scrollTop = 0;
|
||||
this.$.input.focus();
|
||||
setTimeout(() => this.$.input.focus());
|
||||
this.emit('open');
|
||||
}
|
||||
|
||||
|
|
|
@ -11,7 +11,6 @@ export default class Field extends FormInput {
|
|||
this.suffix = null;
|
||||
|
||||
this.control = this.element.querySelector('.control');
|
||||
this.classList = this.element.classList;
|
||||
this.classList.add('vn-field');
|
||||
this.element.addEventListener('click', e => this.onClick(e));
|
||||
|
||||
|
@ -43,9 +42,11 @@ export default class Field extends FormInput {
|
|||
}
|
||||
|
||||
set input(value) {
|
||||
if (this.input) this.control.removeChild(this.input);
|
||||
if (this.input)
|
||||
this.control.removeChild(this.input);
|
||||
this._input = value;
|
||||
this.control.appendChild(value);
|
||||
if (value)
|
||||
this.control.appendChild(value);
|
||||
}
|
||||
|
||||
get input() {
|
||||
|
@ -84,36 +85,8 @@ export default class Field extends FormInput {
|
|||
return this.input.placeholder;
|
||||
}
|
||||
|
||||
set tabIndex(value) {
|
||||
this.input.tabIndex = value;
|
||||
}
|
||||
|
||||
get tabIndex() {
|
||||
return this.input.tabIndex;
|
||||
}
|
||||
|
||||
set disabled(value) {
|
||||
this._disabled = boolTag(value);
|
||||
this.input.disabled = this._disabled;
|
||||
this.classList.toggle('disabled', this._disabled);
|
||||
}
|
||||
|
||||
get disabled() {
|
||||
return this._disabled;
|
||||
}
|
||||
|
||||
set readonly(value) {
|
||||
this._readonly = boolTag(value);
|
||||
this.input.readOnly = this._readonly;
|
||||
this.classList.toggle('readonly', this._readonly);
|
||||
}
|
||||
|
||||
get readonly() {
|
||||
return this._readonly;
|
||||
}
|
||||
|
||||
set required(value) {
|
||||
this._required = boolTag(value);
|
||||
this._required = value;
|
||||
let required = this.element.querySelector('.required');
|
||||
display(required, this._required);
|
||||
}
|
||||
|
@ -180,9 +153,13 @@ export default class Field extends FormInput {
|
|||
fix.innerText = text || '';
|
||||
}
|
||||
|
||||
refreshTabIndex() {
|
||||
this.input.tabIndex = this.disabled ? -1 : this.tabIndex;
|
||||
}
|
||||
|
||||
onClick() {
|
||||
if (event.defaultPrevented) return;
|
||||
event.preventDefault();
|
||||
// if (event.defaultPrevented) return;
|
||||
// event.preventDefault();
|
||||
|
||||
if (this.input !== document.activeElement)
|
||||
this.focus();
|
||||
|
@ -250,15 +227,10 @@ ngModule.vnComponent('vnField', {
|
|||
suffix: '@?',
|
||||
hint: '@?',
|
||||
error: '<?',
|
||||
tabIndex: '<?',
|
||||
rule: '@?'
|
||||
}
|
||||
});
|
||||
|
||||
function boolTag(value) {
|
||||
return Boolean(value || value === '');
|
||||
}
|
||||
|
||||
function display(element, display) {
|
||||
element.style.display = display ? 'initial' : 'none';
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
& > .fix {
|
||||
padding-top: 24px;
|
||||
line-height: 24px;
|
||||
font-size: $input-font-size;
|
||||
font-size: $font-size;
|
||||
opacity: 0;
|
||||
transition: opacity 200ms ease-in-out;
|
||||
|
||||
|
@ -58,18 +58,39 @@
|
|||
border: none;
|
||||
font-family: Arial, sans-serif;
|
||||
display: block;
|
||||
font-size: $input-font-size;
|
||||
font-size: $font-size;
|
||||
width: 100%;
|
||||
background: 0;
|
||||
color: inherit;
|
||||
box-sizing: border-box;
|
||||
min-height: 56px;
|
||||
|
||||
}
|
||||
& > input {
|
||||
position: relative;
|
||||
|
||||
&[type=time],
|
||||
&[type=date],
|
||||
&[type=password] {
|
||||
opacity: 0;
|
||||
transition: opacity 200ms ease-in-out;
|
||||
cursor: pointer;
|
||||
}
|
||||
&[type=time],
|
||||
&[type=date] {
|
||||
clip-path: inset(0 20px 0 0);
|
||||
opacity: 0;
|
||||
transition: opacity 200ms ease-in-out;
|
||||
|
||||
&::-webkit-inner-spin-button,
|
||||
&::-webkit-clear-button {
|
||||
display: none;
|
||||
-webkit-appearance: none;
|
||||
}
|
||||
&::-webkit-calendar-picker-indicator {
|
||||
position: absolute;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
opacity: 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
&[type=number] {
|
||||
-moz-appearance: textfield;
|
||||
|
@ -83,6 +104,15 @@
|
|||
&:invalid {
|
||||
box-shadow: none;
|
||||
}
|
||||
&:-internal-autofill-selected {
|
||||
&,
|
||||
&:hover,
|
||||
&:focus,
|
||||
&:active,
|
||||
&:valid {
|
||||
box-shadow: 0 0 0 40px $color-bg-panel inset;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -172,7 +202,8 @@
|
|||
}
|
||||
& > .control > * {
|
||||
&[type=time],
|
||||
&[type=date] {
|
||||
&[type=date],
|
||||
&[type=password] {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
@ -214,7 +245,6 @@
|
|||
}
|
||||
}
|
||||
& > .hint {
|
||||
z-index: -1;
|
||||
padding: 4px 0;
|
||||
height: 12px;
|
||||
color: rgba(0, 0, 0, .4);
|
||||
|
@ -224,11 +254,12 @@
|
|||
transition-duration: 200ms;
|
||||
transition-timing-function: ease-in-out;
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
|
||||
&.filled {
|
||||
z-index: 0;
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
visibility: visible;
|
||||
}
|
||||
}
|
||||
&.invalid {
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
<button class="mdl-button mdl-js-button mdl-button--fab mdl-js-ripple-effect mdl-button--colored">
|
||||
<vn-icon icon="{{::$ctrl.icon}}"></vn-icon>
|
||||
</button>
|
|
@ -1,8 +0,0 @@
|
|||
import ngModule from '../../module';
|
||||
|
||||
ngModule.component('vnFloatButton', {
|
||||
template: require('./float-button.html'),
|
||||
bindings: {
|
||||
icon: '@'
|
||||
}
|
||||
});
|
|
@ -0,0 +1,13 @@
|
|||
import ngModule from '../../module';
|
||||
import Button from '../button';
|
||||
|
||||
export default class FloatButton extends Button {
|
||||
constructor($element, $scope) {
|
||||
super($element, $scope);
|
||||
this.element.classList.add('round');
|
||||
}
|
||||
}
|
||||
|
||||
ngModule.vnComponent('vnFloatButton', {
|
||||
controller: FloatButton
|
||||
});
|
|
@ -9,6 +9,11 @@ import Component from '../../lib/component';
|
|||
* @property {Boolean} disabled Put component in disabled mode
|
||||
*/
|
||||
export default class FormInput extends Component {
|
||||
constructor($element, $scope) {
|
||||
super($element, $scope);
|
||||
this.classList = this.element.classList;
|
||||
}
|
||||
|
||||
$onInit() {
|
||||
// XXX: Compatibility with old inputs
|
||||
let attrs = this.$element[0].attributes;
|
||||
|
@ -41,6 +46,48 @@ export default class FormInput extends Component {
|
|||
get name() {
|
||||
return this.element.getAttribute('name');
|
||||
}
|
||||
|
||||
set disabled(value) {
|
||||
this._disabled = boolTag(value);
|
||||
this.input.disabled = this._disabled;
|
||||
this.classList.toggle('disabled', this._disabled);
|
||||
this.refreshTabIndex();
|
||||
}
|
||||
|
||||
get disabled() {
|
||||
return this._disabled;
|
||||
}
|
||||
|
||||
set readonly(value) {
|
||||
this._readonly = boolTag(value);
|
||||
this.input.readOnly = this._readonly;
|
||||
this.classList.toggle('readonly', this._readonly);
|
||||
}
|
||||
|
||||
get readonly() {
|
||||
return this._readonly;
|
||||
}
|
||||
|
||||
set tabIndex(value) {
|
||||
this._tabIndex = value;
|
||||
this.refreshTabIndex();
|
||||
}
|
||||
|
||||
get tabIndex() {
|
||||
return this._tabIndex;
|
||||
}
|
||||
|
||||
select() {
|
||||
this.input.select();
|
||||
}
|
||||
|
||||
focus() {
|
||||
this.input.focus();
|
||||
}
|
||||
|
||||
refreshTabIndex() {
|
||||
this.element.tabIndex = this.disabled ? -1 : this.tabIndex;
|
||||
}
|
||||
}
|
||||
|
||||
ngModule.vnComponent('vnFormInput', {
|
||||
|
@ -50,9 +97,14 @@ ngModule.vnComponent('vnFormInput', {
|
|||
field: '=?',
|
||||
name: '@?',
|
||||
disabled: '<?',
|
||||
readonly: '<?'
|
||||
readonly: '<?',
|
||||
tabIndex: '<?'
|
||||
},
|
||||
require: {
|
||||
ngModel: '?ngModel'
|
||||
}
|
||||
});
|
||||
|
||||
function boolTag(value) {
|
||||
return Boolean(value || value === '');
|
||||
}
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
<button type="button" ng-disabled="$ctrl.disabled">
|
||||
<vn-icon icon="{{::$ctrl.icon}}">
|
||||
</button>
|
|
@ -1,39 +0,0 @@
|
|||
import ngModule from '../../module';
|
||||
import './style.scss';
|
||||
|
||||
export default class IconButton {
|
||||
constructor($element) {
|
||||
this.element = $element[0];
|
||||
|
||||
if (this.element.getAttribute('tabindex') == null)
|
||||
this.element.tabIndex = 0;
|
||||
|
||||
this.element.addEventListener('keyup', e => this.onKeyup(e));
|
||||
this.element.addEventListener('click', e => this.onClick(e));
|
||||
}
|
||||
|
||||
onKeyup(event) {
|
||||
if (event.code == 'Space')
|
||||
this.onClick(event);
|
||||
}
|
||||
|
||||
onClick(event) {
|
||||
if (event.defaultPrevented) return;
|
||||
event.preventDefault();
|
||||
|
||||
// FIXME: Don't use Event.stopPropagation()
|
||||
let button = this.element.querySelector('button');
|
||||
if (this.disabled || button.disabled)
|
||||
event.stopImmediatePropagation();
|
||||
}
|
||||
}
|
||||
|
||||
IconButton.$inject = ['$element'];
|
||||
ngModule.component('vnIconButton', {
|
||||
controller: IconButton,
|
||||
template: require('./icon-button.html'),
|
||||
bindings: {
|
||||
icon: '@',
|
||||
disabled: '<?'
|
||||
}
|
||||
});
|
|
@ -0,0 +1,14 @@
|
|||
import ngModule from '../../module';
|
||||
import Button from '../button';
|
||||
import './style.scss';
|
||||
|
||||
export default class IconButton extends Button {
|
||||
constructor($element, $scope) {
|
||||
super($element, $scope);
|
||||
this.design = null;
|
||||
}
|
||||
}
|
||||
|
||||
ngModule.vnComponent('vnIconButton', {
|
||||
controller: IconButton
|
||||
});
|
|
@ -2,27 +2,12 @@
|
|||
|
||||
vn-icon-button {
|
||||
@extend %clickable-light;
|
||||
outline: 0;
|
||||
color: $color-main;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
font-size: 18pt;
|
||||
padding: .25em;
|
||||
|
||||
& > button {
|
||||
background-color: transparent;
|
||||
display: block;
|
||||
color: inherit;
|
||||
border: 0;
|
||||
padding: 0;
|
||||
font-size: inherit;
|
||||
|
||||
&:hover {
|
||||
background-color: initial;
|
||||
}
|
||||
& > vn-icon {
|
||||
display: block;
|
||||
font-size: inherit;
|
||||
}
|
||||
& > button {
|
||||
padding: .2em !important;
|
||||
}
|
||||
&:focus {
|
||||
opacity: .6;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
<vn-icon icon="{{::$ctrl.icon}}"></vn-icon>
|
|
@ -1,29 +0,0 @@
|
|||
import ngModule from '../../module';
|
||||
import './style.scss';
|
||||
|
||||
export default class IconFocusable {
|
||||
constructor($element) {
|
||||
$element[0].tabIndex = 0;
|
||||
$element.on("keyup", event => this.onKeyDown(event, $element));
|
||||
}
|
||||
|
||||
onKeyDown(event, $element) {
|
||||
if (event.defaultPrevented) return;
|
||||
if (event.keyCode == 32 || event.keyCode == 13) {
|
||||
event.preventDefault();
|
||||
$element.triggerHandler('click');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IconFocusable.$inject = ['$element'];
|
||||
ngModule.component('vnIconFocusable', {
|
||||
controller: IconFocusable,
|
||||
template: require('./icon-focusable.html'),
|
||||
bindings: {
|
||||
icon: '@',
|
||||
className: '@?',
|
||||
enabled: '<?',
|
||||
label: '@?'
|
||||
}
|
||||
});
|
|
@ -1,10 +0,0 @@
|
|||
vn-icon-focusable {
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
|
||||
& > i,
|
||||
& > i.material-icons {
|
||||
display: block;
|
||||
font-size: inherit;
|
||||
}
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
<div class="icon-menu">
|
||||
<vn-icon
|
||||
class="button"
|
||||
icon="{{::$ctrl.icon}}">
|
||||
</vn-icon>
|
||||
<vn-drop-down
|
||||
vn-id="drop-down"
|
||||
on-select="$ctrl.onDropDownSelect(item)"
|
||||
ng-click="$ctrl.onDropDownClick($event)">
|
||||
</vn-drop-down>
|
||||
</div>
|
|
@ -1,41 +0,0 @@
|
|||
import ngModule from '../../module';
|
||||
import ButtonMenu from '../button-menu/button-menu';
|
||||
import './style.scss';
|
||||
|
||||
export default class IconMenu extends ButtonMenu {
|
||||
constructor($element, $scope, $transclude) {
|
||||
super($element, $scope);
|
||||
this.$transclude = $transclude;
|
||||
this.input = this.element.querySelector('.button');
|
||||
}
|
||||
}
|
||||
IconMenu.$inject = ['$element', '$scope', '$transclude'];
|
||||
|
||||
ngModule.component('vnIconMenu', {
|
||||
template: require('./icon-menu.html'),
|
||||
bindings: {
|
||||
label: '@',
|
||||
showField: '@?',
|
||||
selection: '<?',
|
||||
valueField: '@?',
|
||||
selectFields: '<?',
|
||||
disabled: '<?',
|
||||
initialData: '<?',
|
||||
showFilter: '<?',
|
||||
field: '=?',
|
||||
url: '@?',
|
||||
data: '<?',
|
||||
where: '@?',
|
||||
order: '@?',
|
||||
limit: '<?',
|
||||
multiple: '<?',
|
||||
onChange: '&?',
|
||||
icon: '@?',
|
||||
translateFields: '<?',
|
||||
onOpen: '&?'
|
||||
},
|
||||
transclude: {
|
||||
tplItem: '?tplItem'
|
||||
},
|
||||
controller: IconMenu
|
||||
});
|
|
@ -0,0 +1,11 @@
|
|||
<button>
|
||||
<vn-icon
|
||||
class="button"
|
||||
icon="{{::$ctrl.icon}}">
|
||||
</vn-icon>
|
||||
</button>
|
||||
<vn-drop-down
|
||||
vn-id="drop-down"
|
||||
on-select="$ctrl.onDropDownSelect(item)"
|
||||
ng-click="$ctrl.onDropDownClick($event)">
|
||||
</vn-drop-down>
|
|
@ -0,0 +1,14 @@
|
|||
import ngModule from '../../module';
|
||||
import ButtonMenu from '../button-menu';
|
||||
|
||||
export default class IconMenu extends ButtonMenu {
|
||||
constructor($element, $scope) {
|
||||
super($element, $scope);
|
||||
this.element.classList.add('flat');
|
||||
}
|
||||
}
|
||||
|
||||
ngModule.vnComponent('vnIconMenu', {
|
||||
template: require('./index.html'),
|
||||
controller: IconMenu
|
||||
});
|
|
@ -1,8 +0,0 @@
|
|||
vn-icon-menu {
|
||||
cursor: pointer;
|
||||
|
||||
vn-drop-down {
|
||||
font-family: 'vn-font';
|
||||
outline: 0
|
||||
}
|
||||
}
|
|
@ -10,36 +10,35 @@ import './subtitle/subtitle';
|
|||
import './spinner/spinner';
|
||||
import './snackbar/snackbar';
|
||||
import './tooltip/tooltip';
|
||||
import './icon-menu/icon-menu';
|
||||
import './button-menu/button-menu';
|
||||
import './popover/popover';
|
||||
import './drop-down/drop-down';
|
||||
import './menu/menu';
|
||||
import './multi-check/multi-check';
|
||||
import './button/button';
|
||||
import './icon-button/icon-button';
|
||||
import './submit/submit';
|
||||
import './card/card';
|
||||
import './float-button/float-button';
|
||||
import './step-control/step-control';
|
||||
import './label-value/label-value';
|
||||
import './pagination/pagination';
|
||||
import './searchbar/searchbar';
|
||||
import './scroll-up/scroll-up';
|
||||
import './autocomplete';
|
||||
import './button';
|
||||
import './button-menu';
|
||||
import './calendar';
|
||||
import './check';
|
||||
import './chip';
|
||||
import './color-legend';
|
||||
import './data-viewer';
|
||||
import './date-picker';
|
||||
import './field';
|
||||
import './float-button';
|
||||
import './icon-menu';
|
||||
import './icon-button';
|
||||
import './input-number';
|
||||
import './input-range';
|
||||
import './range';
|
||||
import './input-time';
|
||||
import './input-file';
|
||||
import './list';
|
||||
import './radio';
|
||||
import './submit';
|
||||
import './table';
|
||||
import './td-editable';
|
||||
import './textarea';
|
||||
|
|
|
@ -1,42 +1,53 @@
|
|||
<div class="container"
|
||||
ng-class="{selected: $ctrl.hasFocus}">
|
||||
<div class="textField">
|
||||
<div class="leftIcons" ng-transclude="leftIcons"></div>
|
||||
<div class="infix">
|
||||
<section class="value" ng-click="$ctrl.openFileSelector()" translate>
|
||||
<div class="container">
|
||||
<div
|
||||
ng-transclude="prepend"
|
||||
class="prepend">
|
||||
</div>
|
||||
<div class="infix">
|
||||
<div class="fix prefix"></div>
|
||||
<div class="control">
|
||||
<section
|
||||
class="value"
|
||||
ng-click="$ctrl.openFileSelector()"
|
||||
translate>
|
||||
{{$ctrl.value}}
|
||||
</section>
|
||||
<input
|
||||
class="mdl-textfield__input"
|
||||
type="file"
|
||||
name="{{::$ctrl.name}}"
|
||||
ng-model="$ctrl.files"
|
||||
vn-validation="{{$ctrl.rule}}"
|
||||
ng-disabled="$ctrl.disabled"
|
||||
ng-readonly="$ctrl.readonly"
|
||||
ng-focus="$ctrl.hasFocus = true"
|
||||
ng-blur="$ctrl.hasFocus = false"
|
||||
tabindex="{{$ctrl.input.tabindex}}"
|
||||
accept="{{$ctrl.accept}}"/>
|
||||
<label class="label">
|
||||
<span translate>{{::$ctrl.label}}</span>
|
||||
<span translate ng-show="::$ctrl.required">*</span>
|
||||
</label>
|
||||
type="file"
|
||||
ng-model="$ctrl.files"
|
||||
accept="{{$ctrl.accept}}">
|
||||
</input>
|
||||
</div>
|
||||
<div class="underline"></div>
|
||||
<div class="selected underline"></div>
|
||||
<div class="suffix">
|
||||
<i class="material-icons"
|
||||
ng-if="::$ctrl.hasInfo"
|
||||
vn-tooltip="{{::$ctrl.info}}">
|
||||
info_outline
|
||||
</i>
|
||||
<vn-icon-button
|
||||
icon="cloud_upload"
|
||||
vn-tooltip="Select a file"
|
||||
ng-click="$ctrl.openFileSelector()">
|
||||
</vn-icon-button>
|
||||
</div>
|
||||
<div class="rightIcons" ng-transclude="rightIcons"></div>
|
||||
<div class="fix suffix"></div>
|
||||
<label>
|
||||
<span translate>{{::$ctrl.label}}</span>
|
||||
<span class="required">*</span>
|
||||
</label>
|
||||
</div>
|
||||
<div class="icons pre">
|
||||
<vn-icon
|
||||
icon="clear"
|
||||
translate-attr="{title: 'Clear'}"
|
||||
ng-click="$ctrl.onClear($event)">
|
||||
</vn-icon>
|
||||
<vn-icon
|
||||
icon="cloud_upload"
|
||||
vn-tooltip="Select a file"
|
||||
ng-click="$ctrl.openFileSelector()">
|
||||
</vn-icon>
|
||||
<vn-icon
|
||||
ng-if="::$ctrl.info"
|
||||
icon="info_outline"
|
||||
vn-tooltip="{{::$ctrl.info}}">
|
||||
</vn-icon>
|
||||
</div>
|
||||
<div
|
||||
ng-transclude="append"
|
||||
class="append">
|
||||
</div>
|
||||
<div class="icons post">
|
||||
</div>
|
||||
<div class="underline blur"></div>
|
||||
<div class="underline focus"></div>
|
||||
</div>
|
||||
<div class="hint"></div>
|
||||
|
|
|
@ -1,15 +1,13 @@
|
|||
import ngModule from '../../module';
|
||||
import Input from '../../lib/input';
|
||||
import FormInput from '../form-input';
|
||||
import './style.scss';
|
||||
|
||||
export default class InputFile extends Input {
|
||||
export default class InputFile extends FormInput {
|
||||
constructor($element, $scope) {
|
||||
super($element, $scope);
|
||||
this.element = $element[0];
|
||||
this.hasFocus = false;
|
||||
this._multiple = false;
|
||||
this._value = 'Select a file';
|
||||
|
||||
this.input = this.element.querySelector('input');
|
||||
this.registerEvents();
|
||||
}
|
||||
|
||||
|
@ -106,26 +104,12 @@ export default class InputFile extends Input {
|
|||
}
|
||||
}
|
||||
|
||||
InputFile.$inject = ['$element', '$scope'];
|
||||
|
||||
ngModule.component('vnInputFile', {
|
||||
ngModule.vnComponent('vnInputFile', {
|
||||
template: require('./index.html'),
|
||||
controller: InputFile,
|
||||
transclude: {
|
||||
leftIcons: '?tLeftIcons',
|
||||
rightIcons: '?tRightIcons'
|
||||
},
|
||||
bindings: {
|
||||
label: '@?',
|
||||
name: '@?',
|
||||
disabled: '<?',
|
||||
multiple: '<?',
|
||||
required: '@?',
|
||||
accept: '@?',
|
||||
rule: '@?',
|
||||
files: '=model',
|
||||
validate: '&',
|
||||
onChange: '&',
|
||||
onClear: '&'
|
||||
files: '=model'
|
||||
}
|
||||
});
|
||||
|
|
|
@ -7,159 +7,7 @@ vn-input-file {
|
|||
padding: 4px 0;
|
||||
outline: 0
|
||||
}
|
||||
input {
|
||||
display: none !important
|
||||
}
|
||||
margin: 20px 0;
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
|
||||
& > .container {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
padding-bottom: 2px;
|
||||
display: flex;
|
||||
|
||||
& > .textField {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
padding-top: 4px;
|
||||
}
|
||||
}
|
||||
|
||||
.leftIcons, .rightIcons, .suffix {
|
||||
display: flex;
|
||||
color: $color-font-secondary;
|
||||
|
||||
.material-icons {
|
||||
font-size: 20px !important
|
||||
}
|
||||
}
|
||||
|
||||
.suffix vn-icon-button {
|
||||
padding: 0
|
||||
}
|
||||
|
||||
t-left-icons {
|
||||
padding-right: 0.5em
|
||||
}
|
||||
|
||||
t-right-icons {
|
||||
padding-left: 0.5em
|
||||
}
|
||||
|
||||
.infix {
|
||||
position: relative;
|
||||
display: block;
|
||||
flex: auto;
|
||||
width: 100%;
|
||||
min-width: 0;
|
||||
}
|
||||
i.clear {
|
||||
visibility: hidden;
|
||||
cursor: pointer;
|
||||
outline: 0;
|
||||
|
||||
&:hover {
|
||||
color: #222;
|
||||
}
|
||||
}
|
||||
&:hover i.clear {
|
||||
visibility: visible;
|
||||
}
|
||||
i.visible {
|
||||
visibility: visible;
|
||||
}
|
||||
label {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
padding: 4px 0!important;
|
||||
pointer-events: none;
|
||||
color: $color-font-secondary;
|
||||
transition-duration: .2s;
|
||||
transition-timing-function: cubic-bezier(.4,0,.2,1);
|
||||
}
|
||||
&.not-empty label{
|
||||
bottom: 24px;
|
||||
color: $color-main;
|
||||
padding: 0;
|
||||
font-size: 12px;
|
||||
}
|
||||
input {
|
||||
outline: none;
|
||||
border: none;
|
||||
font-family: "Helvetica", "Arial", sans-serif;
|
||||
display: block;
|
||||
font-size: 16px;
|
||||
width: 100%;
|
||||
background: 0 0;
|
||||
color: inherit;
|
||||
padding: 4px;
|
||||
box-sizing: border-box;
|
||||
border-bottom: 0!important;
|
||||
|
||||
&[type=number] {
|
||||
-moz-appearance: textfield;
|
||||
&::-webkit-outer-spin-button,
|
||||
&::-webkit-inner-spin-button {
|
||||
-webkit-appearance: none;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
&:invalid {
|
||||
box-shadow: none;
|
||||
}
|
||||
}
|
||||
.underline {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
height: 1px;
|
||||
content: ' ';
|
||||
pointer-events: none;
|
||||
width: 100%;
|
||||
background-color: $color-input-underline;
|
||||
}
|
||||
.selected.underline {
|
||||
background-color: $color-main;
|
||||
height: 2px;
|
||||
left: 50%;
|
||||
width: 0px !important;
|
||||
transition-duration: 0.2s;
|
||||
transition-timing-function: cubic-bezier(.4,0,.2,1);
|
||||
}
|
||||
|
||||
div.selected {
|
||||
&.container{
|
||||
border-bottom: 0px;
|
||||
}
|
||||
label {
|
||||
bottom: 24px;
|
||||
color: $color-main;
|
||||
font-size: 12px;
|
||||
}
|
||||
.selected.underline{
|
||||
left: 0;
|
||||
width: 100%!important;
|
||||
}
|
||||
}
|
||||
& > div.container > div.textField > div.infix.invalid {
|
||||
@extend div.selected;
|
||||
|
||||
& > span.mdl-textfield__error {
|
||||
visibility: visible;
|
||||
}
|
||||
& > label {
|
||||
color: #d50000;
|
||||
}
|
||||
}
|
||||
.infix.invalid + .underline {
|
||||
background-color: #d50000;
|
||||
}
|
||||
|
||||
label span:nth-child(2) {
|
||||
color: $color-alert
|
||||
input[type=file] {
|
||||
display: none;
|
||||
}
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
<div>
|
||||
<label translate>{{::$ctrl.label}}</label>
|
||||
<input
|
||||
name="{{$ctrl.name}}"
|
||||
class="mdl-slider mdl-js-slider"
|
||||
type="range"/>
|
||||
<label class="min-label" translate>Company</label>
|
||||
<label class="max-label" translate>Sales/Client</label>
|
||||
</div>
|
|
@ -1,79 +0,0 @@
|
|||
import ngModule from '../../module';
|
||||
import Input from '../../lib/input';
|
||||
import './style.scss';
|
||||
|
||||
export default class inputRange extends Input {
|
||||
constructor($element, $scope) {
|
||||
super($element, $scope);
|
||||
this.mdlElement = this.element.querySelector('.mdl-slider');
|
||||
componentHandler.upgradeElement(this.mdlElement);
|
||||
this.mdlElement.addEventListener('change', () => {
|
||||
this._value = this.input.value;
|
||||
this.$.$applyAsync();
|
||||
if (this._value && this.onChange)
|
||||
this.emit('change', {value: this._value});
|
||||
});
|
||||
}
|
||||
|
||||
get value() {
|
||||
return this._value;
|
||||
}
|
||||
|
||||
set value(value) {
|
||||
this._value = value;
|
||||
this.mdlElement.MaterialSlider.change(value);
|
||||
}
|
||||
|
||||
get max() {
|
||||
return this.input.max;
|
||||
}
|
||||
|
||||
set max(value) {
|
||||
this.input.max = value;
|
||||
}
|
||||
|
||||
get min() {
|
||||
return this.input.min;
|
||||
}
|
||||
|
||||
set min(value) {
|
||||
this.input.min = value;
|
||||
}
|
||||
|
||||
get step() {
|
||||
return this.input.step;
|
||||
}
|
||||
|
||||
set step(value) {
|
||||
this.input.step = value;
|
||||
}
|
||||
|
||||
get() {
|
||||
return this._model;
|
||||
}
|
||||
|
||||
set model(value) {
|
||||
this._model = value;
|
||||
}
|
||||
|
||||
set disabled(value) {
|
||||
this.input.disabled = value;
|
||||
}
|
||||
}
|
||||
|
||||
inputRange.$inject = ['$element', '$scope'];
|
||||
|
||||
ngModule.component('vnInputRange', {
|
||||
template: require('./index.html'),
|
||||
controller: inputRange,
|
||||
bindings: {
|
||||
label: '@?',
|
||||
disabled: '<?',
|
||||
min: '<?',
|
||||
max: '<?',
|
||||
step: '<?',
|
||||
value: '=',
|
||||
model: '=',
|
||||
onChange: '&'
|
||||
}
|
||||
});
|
|
@ -1,14 +0,0 @@
|
|||
@import "variables";
|
||||
vn-input-range {
|
||||
label {
|
||||
color: $color-main;
|
||||
font-size: 12px;
|
||||
padding: 0 25px;
|
||||
}
|
||||
label.min-label, label.max-label {
|
||||
color: $color-font;
|
||||
}
|
||||
label.max-label {
|
||||
float: right;
|
||||
}
|
||||
}
|
|
@ -15,7 +15,7 @@ export default class InputTime extends Field {
|
|||
}
|
||||
|
||||
set field(value) {
|
||||
this.input.value = this.$filter('dateTime')(value, 'HH:mm');
|
||||
this.input.value = this.$filter('date')(value, 'HH:mm');
|
||||
super.field = value;
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,10 @@ export default class InputTime extends Field {
|
|||
|
||||
if (value) {
|
||||
let split = value.split(':').map(i => parseInt(i) || null);
|
||||
date = new Date(this.field || null);
|
||||
|
||||
date = this.field instanceof Date
|
||||
? this.field
|
||||
: new Date(this.field || null);
|
||||
date.setHours(split[0], split[1], 0, 0);
|
||||
}
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ describe('Component vnInputTime', () => {
|
|||
it(`should display the formated the date`, () => {
|
||||
let date = new Date();
|
||||
$ctrl.field = date;
|
||||
let displayed = $filter('dateTime')(date, 'HH:mm');
|
||||
let displayed = $filter('date')(date, 'HH:mm');
|
||||
|
||||
expect($ctrl.value).toEqual(displayed);
|
||||
});
|
||||
|
|
|
@ -24,11 +24,10 @@
|
|||
|
||||
vn-icon-button {
|
||||
opacity: .4;
|
||||
color: $color-main;
|
||||
margin-left: .5em;
|
||||
transition: opacity 250ms ease-out;
|
||||
padding: 0;
|
||||
font-size: 2em;
|
||||
font-size: 1.2em;
|
||||
|
||||
&:hover {
|
||||
opacity: 1;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import ngModule from '../../module';
|
||||
import Input from '../../lib/input';
|
||||
import FormInput from '../form-input';
|
||||
import './style.scss';
|
||||
|
||||
/**
|
||||
|
@ -8,7 +8,7 @@ import './style.scss';
|
|||
* @param {Array} data List of options shown in drop-down
|
||||
* @param {Array} models Elements to check / unCheck
|
||||
*/
|
||||
export default class MultiCheck extends Input {
|
||||
export default class MultiCheck extends FormInput {
|
||||
constructor($element, $scope) {
|
||||
super($element, $scope);
|
||||
this._checked = false;
|
||||
|
|
|
@ -109,6 +109,7 @@ export default class Popover extends Component {
|
|||
this.showTimeout = null;
|
||||
this.element.style.display = 'none';
|
||||
this.document.body.removeChild(this.element);
|
||||
this.emit('close');
|
||||
}, 250);
|
||||
|
||||
this.document.removeEventListener('keydown', this.docKeyDownHandler);
|
||||
|
@ -118,7 +119,7 @@ export default class Popover extends Component {
|
|||
this.bgMouseDownHandler = null;
|
||||
|
||||
if (this.deregisterCallback) this.deregisterCallback();
|
||||
this.emit('close');
|
||||
this.emit('closeStart');
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
<label class="main" translate>{{::$ctrl.label}}</label>
|
||||
<input name="{{::$ctrl.name}}" type="range"></input>
|
||||
<label class="min-label" translate>{{::$ctrl.minLabel}}</label>
|
||||
<label class="max-label" translate>{{::$ctrl.maxLabel}}</label>
|
|
@ -0,0 +1,50 @@
|
|||
import ngModule from '../../module';
|
||||
import FormInput from '../form-input';
|
||||
import './style.scss';
|
||||
|
||||
export default class Range extends FormInput {
|
||||
constructor($element, $scope) {
|
||||
super($element, $scope);
|
||||
this.input = this.element.querySelector('input');
|
||||
}
|
||||
|
||||
get max() {
|
||||
return this.input.max;
|
||||
}
|
||||
|
||||
set max(value) {
|
||||
this.input.max = value;
|
||||
}
|
||||
|
||||
get min() {
|
||||
return this.input.min;
|
||||
}
|
||||
|
||||
set min(value) {
|
||||
this.input.min = value;
|
||||
}
|
||||
|
||||
get step() {
|
||||
return this.input.step;
|
||||
}
|
||||
|
||||
set step(value) {
|
||||
this.input.step = value;
|
||||
}
|
||||
|
||||
refreshTabIndex() {
|
||||
this.input.tabIndex = this.disabled ? -1 : this.tabIndex;
|
||||
}
|
||||
}
|
||||
|
||||
ngModule.vnComponent('vnRange', {
|
||||
template: require('./index.html'),
|
||||
controller: Range,
|
||||
bindings: {
|
||||
min: '<?',
|
||||
max: '<?',
|
||||
step: '<?',
|
||||
minLabel: '@?',
|
||||
maxLabel: '@?'
|
||||
}
|
||||
});
|
|
@ -0,0 +1,84 @@
|
|||
@import "variables";
|
||||
|
||||
@mixin range($thumb-selector, $track-selector) {
|
||||
&::#{$thumb-selector} {
|
||||
-webkit-appearance: none;
|
||||
margin-top: -5px;
|
||||
border-radius: 50%;
|
||||
background: $color-main;
|
||||
border: none;
|
||||
height: 12px;
|
||||
width: 12px;
|
||||
border-radius: 50%;
|
||||
transition-property: transform, box-shadow;
|
||||
transition-duration: 250ms;
|
||||
transition-timing-function: ease-out;
|
||||
}
|
||||
&:focus::#{$thumb-selector} {
|
||||
box-shadow: 0 0 0 10px rgba($color-main, .2);
|
||||
}
|
||||
&:active::#{$thumb-selector} {
|
||||
transform: scale(1.5);
|
||||
box-shadow: none;
|
||||
}
|
||||
&:disabled::#{$thumb-selector} {
|
||||
transform: none;
|
||||
cursor: initial;
|
||||
}
|
||||
&::#{$track-selector} {
|
||||
width: 100%;
|
||||
height: 3px;
|
||||
cursor: inherit;
|
||||
background: $color-secondary;
|
||||
border-radius: 2px;
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
|
||||
vn-range {
|
||||
& > label {
|
||||
font-size: 12px;
|
||||
|
||||
&.main {
|
||||
color: $color-main;
|
||||
}
|
||||
&.min-label {
|
||||
float: left;
|
||||
}
|
||||
&.max-label {
|
||||
float: right;
|
||||
}
|
||||
}
|
||||
& > input {
|
||||
cursor: pointer;
|
||||
height: 30px;
|
||||
display: block;
|
||||
width: 100%;
|
||||
background: transparent;
|
||||
border-color: transparent;
|
||||
-webkit-appearance: none;
|
||||
margin: .2em 0;
|
||||
|
||||
&:focus {
|
||||
outline: none;
|
||||
}
|
||||
&::-moz-focus-outer {
|
||||
border: 0;
|
||||
}
|
||||
@include range(
|
||||
"-moz-range-thumb",
|
||||
"-moz-range-track"
|
||||
);
|
||||
@include range(
|
||||
"-webkit-slider-thumb",
|
||||
"-webkit-slider-runnable-track"
|
||||
);
|
||||
@include range(
|
||||
"-ms-thumb",
|
||||
"-ms-track"
|
||||
);
|
||||
&:disabled {
|
||||
cursor: initial;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
<button class="mdl-button mdl-js-button mdl-button--fab mdl-button--mini-fab mdl-js-ripple-effect mdl-button--colored"
|
||||
<vn-button
|
||||
icon="keyboard_arrow_up"
|
||||
ng-click="$ctrl.goUp()"
|
||||
vn-tooltip="Go up">
|
||||
<vn-icon icon="keyboard_arrow_up"></vn-icon>
|
||||
</button>
|
||||
vn-tooltip="Go up"
|
||||
class="round">
|
||||
</vn-button>
|
|
@ -1,6 +1,6 @@
|
|||
vn-scroll-up {
|
||||
top: 5em;
|
||||
right: 2.5em;
|
||||
top: 5.5em;
|
||||
right: 2em;
|
||||
display: none;
|
||||
position: fixed;
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
<form ng-submit="$ctrl.onSubmit()">
|
||||
<vn-textfield
|
||||
class="dense vn-py-md"
|
||||
class="dense"
|
||||
placeholder="{{::'Search' | translate}}"
|
||||
ng-model="$ctrl.searchString">
|
||||
<prepend>
|
||||
|
|
|
@ -69,7 +69,7 @@ export default class Controller extends Component {
|
|||
|
||||
this.$panelScope = this.$.$new();
|
||||
this.$panel = this.$compile(`<${this.panel}/>`)(this.$panelScope);
|
||||
let panel = this.$panel.isolateScope().$ctrl;
|
||||
let panel = this.$panel[0].$ctrl;
|
||||
if (this.shownFilter)
|
||||
panel.filter = JSON.parse(JSON.stringify(this.shownFilter));
|
||||
panel.onSubmit = filter => this.onPanelSubmit(filter);
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
vn-searchbar {
|
||||
display: block;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.search-panel {
|
||||
|
|
|
@ -1,2 +1,12 @@
|
|||
<div class="mdl-spinner mdl-spinner--single-color mdl-js-spinner">
|
||||
<div class="loader">
|
||||
<svg class="circular" viewBox="25 25 50 50">
|
||||
<circle
|
||||
class="path"
|
||||
cx="50"
|
||||
cy="50"
|
||||
r="20"
|
||||
fill="none"
|
||||
stroke-miterlimit="10">
|
||||
</circle>
|
||||
</svg>
|
||||
</div>
|
|
@ -1,19 +1,18 @@
|
|||
import ngModule from '../../module';
|
||||
import Component from '../../lib/component';
|
||||
import './style.css';
|
||||
import './style.scss';
|
||||
|
||||
/**
|
||||
* A spinner to inform the user about loading process.
|
||||
*/
|
||||
export default class Spinner extends Component {
|
||||
constructor($element, $scope) {
|
||||
super($element);
|
||||
super($element, $scope);
|
||||
this._enable = false;
|
||||
this.spinner = $element[0].firstChild;
|
||||
componentHandler.upgradeElement(this.spinner);
|
||||
}
|
||||
/**
|
||||
* Enables/disables the spinner.
|
||||
* Activates/deactivates the spinner.
|
||||
*
|
||||
* @param {Boolean} value %true to enable, %false to disable
|
||||
*/
|
||||
|
@ -35,14 +34,14 @@ export default class Spinner extends Component {
|
|||
* Activates the spinner.
|
||||
*/
|
||||
start() {
|
||||
this.spinner.MaterialSpinner.start();
|
||||
this.spinner.style.display = 'block';
|
||||
this._enable = true;
|
||||
}
|
||||
/**
|
||||
* Deactivates the spinner.
|
||||
*/
|
||||
stop() {
|
||||
this.spinner.MaterialSpinner.stop();
|
||||
this.spinner.style.display = 'none';
|
||||
this._enable = false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import './spinner.js';
|
||||
|
||||
describe('Component vnSpinner', () => {
|
||||
let $scope;
|
||||
let $element;
|
||||
let controller;
|
||||
|
||||
|
@ -9,53 +8,44 @@ describe('Component vnSpinner', () => {
|
|||
$translateProvider.translations('en', {});
|
||||
}));
|
||||
|
||||
beforeEach(angular.mock.inject(($componentController, $rootScope) => {
|
||||
$scope = $rootScope.$new();
|
||||
$element = angular.element('<div><div></div></div>');
|
||||
controller = $componentController('vnSpinner', {$scope, $element});
|
||||
beforeEach(angular.mock.inject(($compile, $rootScope) => {
|
||||
$element = $compile(`<vn-spinner></vn-spinner>`)($rootScope);
|
||||
controller = $element.controller('vnSpinner');
|
||||
}));
|
||||
|
||||
afterEach(() => {
|
||||
$element.remove();
|
||||
});
|
||||
|
||||
describe('enable()', () => {
|
||||
it(`should call start() based on a boolean value passed as argument`, () => {
|
||||
it(`should call start() when enable is set to true`, () => {
|
||||
spyOn(controller, 'start');
|
||||
spyOn(controller, 'stop');
|
||||
controller.enable = true;
|
||||
|
||||
expect(controller.start).toHaveBeenCalledWith();
|
||||
expect(controller.stop).not.toHaveBeenCalledWith();
|
||||
});
|
||||
|
||||
it(`should call stop() based on a boolean value passed as argument`, () => {
|
||||
spyOn(controller, 'start');
|
||||
it(`should call stop() when enable is set to false`, () => {
|
||||
spyOn(controller, 'stop');
|
||||
controller.enable = false;
|
||||
|
||||
expect(controller.start).not.toHaveBeenCalledWith();
|
||||
expect(controller.stop).toHaveBeenCalledWith();
|
||||
});
|
||||
});
|
||||
|
||||
describe('start()', () => {
|
||||
it(`should call start() on the controller.materialSpinner then set controllers._enable to be truthy`, () => {
|
||||
controller.spinner = {MaterialSpinner: {start: () => {}}};
|
||||
spyOn(controller.spinner.MaterialSpinner, 'start');
|
||||
controller._enable = false;
|
||||
it(`should set enable to true`, () => {
|
||||
controller.start();
|
||||
|
||||
expect(controller.spinner.MaterialSpinner.start).toHaveBeenCalledWith();
|
||||
expect(controller._enable).toBeTruthy();
|
||||
expect(controller.enable).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('stop()', () => {
|
||||
it(`should call stop() on the controller.materialSpinner then set controllers._enable to be truthy`, () => {
|
||||
controller.spinner = {MaterialSpinner: {stop: () => {}}};
|
||||
spyOn(controller.spinner.MaterialSpinner, 'stop');
|
||||
controller._enable = true;
|
||||
it(`should set enable to false`, () => {
|
||||
controller.stop();
|
||||
|
||||
expect(controller.spinner.MaterialSpinner.stop).toHaveBeenCalledWith();
|
||||
expect(controller._enable).toBeFalsy();
|
||||
expect(controller.enable).toBeFalsy();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
vn-spinner {
|
||||
display: inline-block;
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
@import "variables";
|
||||
|
||||
vn-spinner {
|
||||
display: inline-block;
|
||||
min-height: 28px;
|
||||
min-width: 28px;
|
||||
|
||||
& > .loader {
|
||||
position: relative;
|
||||
margin: 0 auto;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
&:before {
|
||||
content: '';
|
||||
display: block;
|
||||
padding-top: 100%;
|
||||
}
|
||||
& > .circular {
|
||||
animation: rotate 2s linear infinite;
|
||||
transform-origin: center center;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
margin: auto;
|
||||
|
||||
& > .path {
|
||||
stroke: $color-main;
|
||||
stroke-dasharray: 1, 200;
|
||||
stroke-dashoffset: 0;
|
||||
stroke-linecap: square;
|
||||
stroke-width: 6px;
|
||||
animation: dash 1.5s ease-in-out infinite;
|
||||
}
|
||||
}
|
||||
}
|
||||
@keyframes rotate {
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
@keyframes dash {
|
||||
0% {
|
||||
stroke-dasharray: 1, 200;
|
||||
stroke-dashoffset: 0;
|
||||
}
|
||||
50% {
|
||||
stroke-dasharray: 89, 200;
|
||||
stroke-dashoffset: -35px;
|
||||
}
|
||||
100% {
|
||||
stroke-dasharray: 89, 200;
|
||||
stroke-dashoffset: -124px;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -41,11 +41,5 @@ vn-step-control {
|
|||
& > .buttons > .step {
|
||||
display: flex
|
||||
}
|
||||
& > .buttons > .step > .mdl-button {
|
||||
line-height: 32px;
|
||||
font-size: 12px;
|
||||
padding: 0 12px;
|
||||
height: 32px
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
import ngModule from '../../module';
|
||||
import Button from '../button';
|
||||
|
||||
export default class Controller extends Button {
|
||||
constructor($element, $scope) {
|
||||
super($element, $scope);
|
||||
this.type = 'submit';
|
||||
}
|
||||
}
|
||||
|
||||
ngModule.vnComponent('vnSubmit', {
|
||||
controller: Controller
|
||||
});
|
|
@ -1,6 +0,0 @@
|
|||
<input
|
||||
class="mdl-button mdl-js-button mdl-button--raised mdl-button--colored"
|
||||
type="submit"
|
||||
translate-attr="{value: $ctrl.label}"
|
||||
value="$ctrl.label">
|
||||
</input>
|
|
@ -1,25 +0,0 @@
|
|||
import ngModule from '../../module';
|
||||
import Input from '../../lib/input';
|
||||
|
||||
export default class Controller extends Input {
|
||||
constructor($element, $scope) {
|
||||
super($element, $scope);
|
||||
this.$element = $element;
|
||||
this.input = $element[0].querySelector('input');
|
||||
}
|
||||
|
||||
set disabled(value) {
|
||||
this.input.disabled = value;
|
||||
}
|
||||
}
|
||||
|
||||
Controller.$inject = ['$element', '$scope'];
|
||||
|
||||
ngModule.component('vnSubmit', {
|
||||
template: require('./submit.html'),
|
||||
controller: Controller,
|
||||
bindings: {
|
||||
label: '@?',
|
||||
disabled: '<?',
|
||||
}
|
||||
});
|
|
@ -1,6 +1,6 @@
|
|||
import ngModule from '../../module';
|
||||
import Component from '../../lib/component';
|
||||
import Input from '../../lib/input';
|
||||
import FormInput from '../form-input';
|
||||
import './style.scss';
|
||||
|
||||
export default class Controller extends Component {
|
||||
|
@ -37,7 +37,7 @@ export default class Controller extends Component {
|
|||
}
|
||||
|
||||
let inputCtrl = this.field[0].firstElementChild.$ctrl;
|
||||
if (inputCtrl instanceof Input) {
|
||||
if (inputCtrl instanceof FormInput) {
|
||||
let evt = new MouseEvent('click', {
|
||||
bubbles: true,
|
||||
cancelable: true,
|
||||
|
|
|
@ -19,15 +19,24 @@ export default class Toggle extends FormInput {
|
|||
}
|
||||
|
||||
set disabled(value) {
|
||||
this.element.tabIndex = !value ? 0 : -1;
|
||||
this.element.classList.toggle('disabled', Boolean(value));
|
||||
this._disabled = value;
|
||||
this.classList.toggle('disabled', Boolean(value));
|
||||
this.refreshTabIndex();
|
||||
}
|
||||
|
||||
get disabled() {
|
||||
return this._disabled;
|
||||
}
|
||||
|
||||
set readonly(value) {
|
||||
this._readonly = value;
|
||||
this.classList.toggle('readonly', Boolean(value));
|
||||
}
|
||||
|
||||
get readonly() {
|
||||
return this._readonly;
|
||||
}
|
||||
|
||||
onKeydown(event) {
|
||||
if (event.code == 'Space')
|
||||
this.onClick(event);
|
||||
|
|
|
@ -11,7 +11,10 @@
|
|||
cursor: inherit;
|
||||
}
|
||||
& > span {
|
||||
font-size: $input-font-size;
|
||||
font-size: $font-size;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
}
|
||||
& > .btn {
|
||||
position: relative;
|
||||
|
|
|
@ -13,7 +13,7 @@ export default class Tooltip extends Component {
|
|||
constructor($element, $scope, $timeout) {
|
||||
super($element, $scope);
|
||||
this.$timeout = $timeout;
|
||||
$element.addClass('vn-tooltip mdl-shadow--4dp');
|
||||
$element.addClass('vn-tooltip vn-shadow');
|
||||
this.position = 'down';
|
||||
this.margin = 10;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
<div class="node clickable">
|
||||
<vn-icon
|
||||
class="arrow"
|
||||
ng-class="{invisible: !$ctrl.item.sons}"
|
||||
icon="keyboard_arrow_down"
|
||||
translate-attr="::{title: 'Toggle'}">
|
||||
</vn-icon>
|
||||
<section class="content"></section>
|
||||
<section class="buttons" ng-if="::!$ctrl.treeview.readOnly">
|
||||
<vn-icon-button translate-attr="::{title: 'Remove'}"
|
||||
icon="delete"
|
||||
ng-click="$ctrl.treeview.onRemove($ctrl.item)"
|
||||
ng-if="$ctrl.item.parent">
|
||||
</vn-icon-button>
|
||||
<vn-icon-button translate-attr="::{title: 'Create'}"
|
||||
icon="add_circle"
|
||||
ng-click="$ctrl.treeview.onCreate($ctrl.item)">
|
||||
</vn-icon-button>
|
||||
</section>
|
||||
</div>
|
|
@ -2,22 +2,33 @@ import ngModule from '../../module';
|
|||
|
||||
class Controller {
|
||||
constructor($element, $scope, $compile) {
|
||||
this.$element = $element;
|
||||
this.$scope = $scope;
|
||||
this.$compile = $compile;
|
||||
this.element = $element[0];
|
||||
|
||||
this.element.$ctrl = this;
|
||||
this.element.droppable = true;
|
||||
this.dropCount = 0;
|
||||
this.element.classList.add('vn-droppable');
|
||||
}
|
||||
|
||||
$onInit() {
|
||||
const transcludeElement = this.element.querySelector('.content');
|
||||
const content = angular.element(transcludeElement);
|
||||
|
||||
if (this.item.parent) {
|
||||
this.treeview.$transclude(($clone, $scope) => {
|
||||
this.$contentScope = $scope;
|
||||
$scope.item = this.item;
|
||||
this.$element.append($clone);
|
||||
content.append($clone);
|
||||
});
|
||||
|
||||
this.element.draggable = true;
|
||||
this.element.classList.add('vn-draggable');
|
||||
} else {
|
||||
let template = `<span translate>{{$ctrl.treeview.rootLabel}}</span>`;
|
||||
let $clone = this.$compile(template)(this.$scope);
|
||||
this.$element.append($clone);
|
||||
content.append($clone);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -25,10 +36,21 @@ class Controller {
|
|||
if (this.$contentScope)
|
||||
this.$contentScope.$destroy();
|
||||
}
|
||||
|
||||
dragEnter() {
|
||||
this.dropCount++;
|
||||
|
||||
if (element != this.dropping) {
|
||||
this.undrop();
|
||||
if (element) element.classList.add('dropping');
|
||||
this.dropping = element;
|
||||
}
|
||||
}
|
||||
}
|
||||
Controller.$inject = ['$element', '$scope', '$compile'];
|
||||
|
||||
ngModule.component('vnTreeviewContent', {
|
||||
ngModule.component('vnTreeviewChild', {
|
||||
template: require('./child.html'),
|
||||
controller: Controller,
|
||||
bindings: {
|
||||
item: '<'
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue