fixes #4866 más detalle en faltas #1201
|
@ -8,9 +8,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
## [2302.01] - 2023-01-12
|
## [2302.01] - 2023-01-12
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
- [General](Inicio) Permite recuperar la contraseña
|
||||||
-
|
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
|
||||||
- Se ha eliminado la sección "Control clientes" dentro de Ticket
|
|
||||||
|
### Removed
|
||||||
|
- [Tickets](Control clientes) Eliminada sección
|
||||||
|
|
|
@ -29,8 +29,12 @@ module.exports = Self => {
|
||||||
filter = mergeFilters(filter, {where});
|
filter = mergeFilters(filter, {where});
|
||||||
|
|
||||||
const stmt = new ParameterizedSQL(
|
const stmt = new ParameterizedSQL(
|
||||||
`SELECT * FROM campaign`);
|
`SELECT * FROM (`);
|
||||||
|
stmt.merge('SELECT * FROM campaign');
|
||||||
stmt.merge(conn.makeWhere(filter.where));
|
stmt.merge(conn.makeWhere(filter.where));
|
||||||
|
stmt.merge('ORDER BY dated ASC');
|
||||||
|
stmt.merge('LIMIT 10000000000000000000');
|
||||||
|
stmt.merge(') sub');
|
||||||
stmt.merge('GROUP BY code');
|
stmt.merge('GROUP BY code');
|
||||||
stmt.merge(conn.makePagination(filter));
|
stmt.merge(conn.makePagination(filter));
|
||||||
|
|
||||||
|
|
|
@ -2652,7 +2652,7 @@ INSERT INTO `vn`.`mdbVersion` (`app`, `branchFk`, `version`)
|
||||||
|
|
||||||
INSERT INTO `vn`.`accountingConfig` (`id`, `minDate`, `maxDate`)
|
INSERT INTO `vn`.`accountingConfig` (`id`, `minDate`, `maxDate`)
|
||||||
VALUES
|
VALUES
|
||||||
(1, '2022-01-01', '2023-01-01');
|
(1, CONCAT(YEAR(DATE_ADD(util.VN_CURDATE(), INTERVAL -1 YEAR)), '-01-01'), CONCAT(YEAR(DATE_ADD(util.VN_CURDATE(), INTERVAL +1 YEAR)), '-01-01'));
|
||||||
|
|
||||||
|
|
||||||
INSERT INTO `vn`.`saleGroup` (`userFk`, `parkingFk`, `sectorFk`)
|
INSERT INTO `vn`.`saleGroup` (`userFk`, `parkingFk`, `sectorFk`)
|
||||||
|
|
|
@ -30,7 +30,7 @@ export default {
|
||||||
firstModuleRemovePinIcon: 'vn-home a:nth-child(1) vn-icon[icon="remove_circle"]'
|
firstModuleRemovePinIcon: 'vn-home a:nth-child(1) vn-icon[icon="remove_circle"]'
|
||||||
},
|
},
|
||||||
recoverPassword: {
|
recoverPassword: {
|
||||||
recoverPasswordButton: 'vn-login a[ui-sref="recoverPassword"]',
|
recoverPasswordButton: 'vn-login a[ui-sref="recover-password"]',
|
||||||
email: 'vn-recover-password vn-textfield[ng-model="$ctrl.email"]',
|
email: 'vn-recover-password vn-textfield[ng-model="$ctrl.email"]',
|
||||||
sendEmailButton: 'vn-recover-password vn-submit',
|
sendEmailButton: 'vn-recover-password vn-submit',
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
import selectors from '../../helpers/selectors';
|
import selectors from '../../helpers/selectors';
|
||||||
import getBrowser from '../../helpers/puppeteer';
|
import getBrowser from '../../helpers/puppeteer';
|
||||||
|
|
||||||
// https://redmine.verdnatura.es/issues/4995 fix login
|
describe('RecoverPassword path', async() => {
|
||||||
xdescribe('RecoverPassword path', async() => {
|
|
||||||
let browser;
|
let browser;
|
||||||
let page;
|
let page;
|
||||||
|
|
||||||
|
@ -11,7 +10,7 @@ xdescribe('RecoverPassword path', async() => {
|
||||||
page = browser.page;
|
page = browser.page;
|
||||||
|
|
||||||
await page.waitToClick(selectors.recoverPassword.recoverPasswordButton);
|
await page.waitToClick(selectors.recoverPassword.recoverPasswordButton);
|
||||||
await page.waitForState('recoverPassword');
|
await page.waitForState('recover-password');
|
||||||
});
|
});
|
||||||
|
|
||||||
afterAll(async() => {
|
afterAll(async() => {
|
||||||
|
|
|
@ -58,6 +58,7 @@ describe('Worker time control path', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it(`should return error when insert 'out' of first entry`, async() => {
|
it(`should return error when insert 'out' of first entry`, async() => {
|
||||||
|
pending('https://redmine.verdnatura.es/issues/4707');
|
||||||
await page.waitToClick(selectors.workerTimeControl.mondayAddTimeButton);
|
await page.waitToClick(selectors.workerTimeControl.mondayAddTimeButton);
|
||||||
await page.pickTime(selectors.workerTimeControl.dialogTimeInput, eightAm);
|
await page.pickTime(selectors.workerTimeControl.dialogTimeInput, eightAm);
|
||||||
await page.autocompleteSearch(selectors.workerTimeControl.dialogTimeDirection, 'out');
|
await page.autocompleteSearch(selectors.workerTimeControl.dialogTimeDirection, 'out');
|
||||||
|
@ -68,6 +69,7 @@ describe('Worker time control path', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it(`should insert 'in' monday`, async() => {
|
it(`should insert 'in' monday`, async() => {
|
||||||
|
pending('https://redmine.verdnatura.es/issues/4707');
|
||||||
await page.waitToClick(selectors.workerTimeControl.mondayAddTimeButton);
|
await page.waitToClick(selectors.workerTimeControl.mondayAddTimeButton);
|
||||||
await page.pickTime(selectors.workerTimeControl.dialogTimeInput, eightAm);
|
await page.pickTime(selectors.workerTimeControl.dialogTimeInput, eightAm);
|
||||||
await page.autocompleteSearch(selectors.workerTimeControl.dialogTimeDirection, 'in');
|
await page.autocompleteSearch(selectors.workerTimeControl.dialogTimeDirection, 'in');
|
||||||
|
@ -78,6 +80,7 @@ describe('Worker time control path', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it(`should insert 'out' monday`, async() => {
|
it(`should insert 'out' monday`, async() => {
|
||||||
|
pending('https://redmine.verdnatura.es/issues/4707');
|
||||||
await page.waitToClick(selectors.workerTimeControl.mondayAddTimeButton);
|
await page.waitToClick(selectors.workerTimeControl.mondayAddTimeButton);
|
||||||
await page.pickTime(selectors.workerTimeControl.dialogTimeInput, fourPm);
|
await page.pickTime(selectors.workerTimeControl.dialogTimeInput, fourPm);
|
||||||
await page.autocompleteSearch(selectors.workerTimeControl.dialogTimeDirection, 'out');
|
await page.autocompleteSearch(selectors.workerTimeControl.dialogTimeDirection, 'out');
|
||||||
|
@ -88,11 +91,13 @@ describe('Worker time control path', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it(`should check Hank Pym worked 8:20 hours`, async() => {
|
it(`should check Hank Pym worked 8:20 hours`, async() => {
|
||||||
|
pending('https://redmine.verdnatura.es/issues/4707');
|
||||||
await page.waitForTextInElement(selectors.workerTimeControl.mondayWorkedHours, '08:20 h.');
|
await page.waitForTextInElement(selectors.workerTimeControl.mondayWorkedHours, '08:20 h.');
|
||||||
await page.waitForTextInElement(selectors.workerTimeControl.weekWorkedHours, '08:20 h.');
|
await page.waitForTextInElement(selectors.workerTimeControl.weekWorkedHours, '08:20 h.');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should remove first entry of monday', async() => {
|
it('should remove first entry of monday', async() => {
|
||||||
|
pending('https://redmine.verdnatura.es/issues/4707');
|
||||||
await page.waitForTextInElement(selectors.workerTimeControl.firstEntryOfMonday, eightAm);
|
await page.waitForTextInElement(selectors.workerTimeControl.firstEntryOfMonday, eightAm);
|
||||||
await page.waitForTextInElement(selectors.workerTimeControl.secondEntryOfMonday, fourPm);
|
await page.waitForTextInElement(selectors.workerTimeControl.secondEntryOfMonday, fourPm);
|
||||||
await page.waitToClick(selectors.workerTimeControl.firstEntryOfMondayDelete);
|
await page.waitToClick(selectors.workerTimeControl.firstEntryOfMondayDelete);
|
||||||
|
@ -103,6 +108,7 @@ describe('Worker time control path', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it(`should be the 'out' the first entry of monday`, async() => {
|
it(`should be the 'out' the first entry of monday`, async() => {
|
||||||
|
pending('https://redmine.verdnatura.es/issues/4707');
|
||||||
const result = await page.waitToGetProperty(selectors.workerTimeControl.firstEntryOfMonday, 'innerText');
|
const result = await page.waitToGetProperty(selectors.workerTimeControl.firstEntryOfMonday, 'innerText');
|
||||||
|
|
||||||
expect(result).toEqual(fourPm);
|
expect(result).toEqual(fourPm);
|
||||||
|
|
|
@ -24,7 +24,7 @@ export default class Auth {
|
||||||
initialize() {
|
initialize() {
|
||||||
let criteria = {
|
let criteria = {
|
||||||
to: state => {
|
to: state => {
|
||||||
const outLayout = ['login', 'recoverPassword', 'resetPassword'];
|
const outLayout = ['login', 'recover-password', 'reset-password'];
|
||||||
return !outLayout.some(ol => ol == state.name);
|
return !outLayout.some(ol => ol == state.name);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,9 +1,3 @@
|
||||||
<vn-layout
|
<ui-view></ui-view>
|
||||||
ng-if="$ctrl.showLayout">
|
|
||||||
</vn-layout>
|
|
||||||
<ui-view
|
|
||||||
name="login"
|
|
||||||
ng-if="!$ctrl.showLayout">
|
|
||||||
</ui-view>
|
|
||||||
<vn-snackbar vn-id="snackbar"></vn-snackbar>
|
<vn-snackbar vn-id="snackbar"></vn-snackbar>
|
||||||
<vn-debug-info></vn-debug-info>
|
<vn-debug-info></vn-debug-info>
|
||||||
|
|
|
@ -19,12 +19,6 @@ export default class App extends Component {
|
||||||
this.vnApp.logger = this;
|
this.vnApp.logger = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
get showLayout() {
|
|
||||||
const state = this.$state.current.name || this.$location.$$path.substring(1).replace('/', '.');
|
|
||||||
const outLayout = ['login', 'recoverPassword', 'resetPassword', 'reset-password'];
|
|
||||||
return state && !outLayout.some(ol => ol == state);
|
|
||||||
}
|
|
||||||
|
|
||||||
$onDestroy() {
|
$onDestroy() {
|
||||||
this.deregisterCallback();
|
this.deregisterCallback();
|
||||||
this.vnApp.logger = null;
|
this.vnApp.logger = null;
|
||||||
|
|
|
@ -5,10 +5,10 @@ import './descriptor-popover';
|
||||||
import './home/home';
|
import './home/home';
|
||||||
import './layout';
|
import './layout';
|
||||||
import './left-menu/left-menu';
|
import './left-menu/left-menu';
|
||||||
import './login/index';
|
import './login';
|
||||||
import './login/login';
|
import './outLayout';
|
||||||
import './login/recover-password';
|
import './recover-password';
|
||||||
import './login/reset-password';
|
import './reset-password';
|
||||||
import './module-card';
|
import './module-card';
|
||||||
import './module-main';
|
import './module-main';
|
||||||
import './side-menu/side-menu';
|
import './side-menu/side-menu';
|
||||||
|
|
|
@ -1,6 +1,27 @@
|
||||||
<div class="box">
|
<vn-textfield
|
||||||
<img src="./logo.svg"/>
|
label="User"
|
||||||
<form name="form">
|
ng-model="$ctrl.user"
|
||||||
<ui-view></ui-view>
|
vn-id="userField"
|
||||||
</form>
|
vn-focus>
|
||||||
|
</vn-textfield>
|
||||||
|
<vn-textfield
|
||||||
|
label="Password"
|
||||||
|
ng-model="$ctrl.password"
|
||||||
|
type="password">
|
||||||
|
</vn-textfield>
|
||||||
|
<vn-check
|
||||||
|
label="Do not close session"
|
||||||
|
ng-model="$ctrl.remember"
|
||||||
|
name="remember">
|
||||||
|
</vn-check>
|
||||||
|
<div class="footer">
|
||||||
|
<vn-submit label="Enter" ng-click="$ctrl.submit()"></vn-submit>
|
||||||
|
<div class="spinner-wrapper">
|
||||||
|
<vn-spinner enable="$ctrl.loading"></vn-spinner>
|
||||||
|
</div>
|
||||||
|
<div class="vn-pt-lg">
|
||||||
|
<a ui-sref="recover-password" translate>
|
||||||
|
I do not remember my password
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,16 +1,43 @@
|
||||||
import ngModule from '../../module';
|
import ngModule from '../../module';
|
||||||
import Component from 'core/lib/component';
|
|
||||||
import './style.scss';
|
import './style.scss';
|
||||||
|
|
||||||
export default class OutLayout extends Component {
|
/**
|
||||||
constructor($element, $scope) {
|
* A simple login form.
|
||||||
super($element, $scope);
|
*/
|
||||||
|
export default class Controller {
|
||||||
|
constructor($, $element, vnAuth) {
|
||||||
|
Object.assign(this, {
|
||||||
|
$,
|
||||||
|
$element,
|
||||||
|
vnAuth,
|
||||||
|
user: localStorage.getItem('lastUser'),
|
||||||
|
remember: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
submit() {
|
||||||
|
this.loading = true;
|
||||||
|
this.vnAuth.login(this.user, this.password, this.remember)
|
||||||
|
.then(() => {
|
||||||
|
localStorage.setItem('lastUser', this.user);
|
||||||
|
this.loading = false;
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
this.loading = false;
|
||||||
|
this.password = '';
|
||||||
|
this.focusUser();
|
||||||
|
throw err;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
focusUser() {
|
||||||
|
this.$.userField.select();
|
||||||
|
this.$.userField.focus();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Controller.$inject = ['$scope', '$element', 'vnAuth'];
|
||||||
|
|
||||||
OutLayout.$inject = ['$element', '$scope'];
|
ngModule.vnComponent('vnLogin', {
|
||||||
|
|
||||||
ngModule.vnComponent('vnOutLayout', {
|
|
||||||
template: require('./index.html'),
|
template: require('./index.html'),
|
||||||
controller: OutLayout
|
controller: Controller
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,16 +1,5 @@
|
||||||
User: Usuario
|
User: Usuario
|
||||||
Password: Contraseña
|
Password: Contraseña
|
||||||
Email: Correo electrónico
|
|
||||||
Do not close session: No cerrar sesión
|
Do not close session: No cerrar sesión
|
||||||
Enter: Entrar
|
Enter: Entrar
|
||||||
I do not remember my password: No recuerdo mi contraseña
|
I do not remember my password: No recuerdo mi contraseña
|
||||||
Recover password: Recuperar contraseña
|
|
||||||
We will sent you an email to recover your password: Te enviaremos un correo para restablecer tu contraseña
|
|
||||||
Notification sent!: ¡Notificación enviada!
|
|
||||||
Reset password: Restrablecer contraseña
|
|
||||||
New password: Nueva contraseña
|
|
||||||
Repeat password: Repetir contraseña
|
|
||||||
Password requirements: >
|
|
||||||
La contraseña debe tener al menos {{ length }} caracteres de longitud,
|
|
||||||
{{nAlpha}} caracteres alfabéticos, {{nUpper}} letras mayúsculas, {{nDigits}}
|
|
||||||
dígitos y {{nPunct}} símbolos (Ej: $%&.)
|
|
||||||
|
|
|
@ -1,32 +0,0 @@
|
||||||
<div class="box">
|
|
||||||
<img src="./logo.svg"/>
|
|
||||||
<form name="form" ng-submit="$ctrl.submit()">
|
|
||||||
<vn-textfield
|
|
||||||
label="User"
|
|
||||||
ng-model="$ctrl.user"
|
|
||||||
vn-id="userField"
|
|
||||||
vn-focus>
|
|
||||||
</vn-textfield>
|
|
||||||
<vn-textfield
|
|
||||||
label="Password"
|
|
||||||
ng-model="$ctrl.password"
|
|
||||||
type="password">
|
|
||||||
</vn-textfield>
|
|
||||||
<vn-check
|
|
||||||
label="Do not close session"
|
|
||||||
ng-model="$ctrl.remember"
|
|
||||||
name="remember">
|
|
||||||
</vn-check>
|
|
||||||
<div class="footer">
|
|
||||||
<vn-submit label="Enter" ng-click="$ctrl.submit()"></vn-submit>
|
|
||||||
<div class="spinner-wrapper">
|
|
||||||
<vn-spinner enable="$ctrl.loading"></vn-spinner>
|
|
||||||
</div>
|
|
||||||
<!--<div class="vn-pt-lg">
|
|
||||||
<a ui-sref="recoverPassword" translate>
|
|
||||||
I do not remember my password
|
|
||||||
</a>
|
|
||||||
</div>-->
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
|
@ -1,43 +0,0 @@
|
||||||
import ngModule from '../../module';
|
|
||||||
import './style.scss';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A simple login form.
|
|
||||||
*/
|
|
||||||
export default class Controller {
|
|
||||||
constructor($, $element, vnAuth) {
|
|
||||||
Object.assign(this, {
|
|
||||||
$,
|
|
||||||
$element,
|
|
||||||
vnAuth,
|
|
||||||
user: localStorage.getItem('lastUser'),
|
|
||||||
remember: true
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
submit() {
|
|
||||||
this.loading = true;
|
|
||||||
this.vnAuth.login(this.user, this.password, this.remember)
|
|
||||||
.then(() => {
|
|
||||||
localStorage.setItem('lastUser', this.user);
|
|
||||||
this.loading = false;
|
|
||||||
})
|
|
||||||
.catch(err => {
|
|
||||||
this.loading = false;
|
|
||||||
this.password = '';
|
|
||||||
this.focusUser();
|
|
||||||
throw err;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
focusUser() {
|
|
||||||
this.$.userField.select();
|
|
||||||
this.$.userField.focus();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Controller.$inject = ['$scope', '$element', 'vnAuth'];
|
|
||||||
|
|
||||||
ngModule.vnComponent('vnLogin', {
|
|
||||||
template: require('./login.html'),
|
|
||||||
controller: Controller
|
|
||||||
});
|
|
|
@ -1,8 +1,6 @@
|
||||||
@import "variables";
|
@import "variables";
|
||||||
|
|
||||||
vn-login,
|
vn-login{
|
||||||
vn-reset-password,
|
|
||||||
vn-recover-password{
|
|
||||||
.footer {
|
.footer {
|
||||||
margin-top: 32px;
|
margin-top: 32px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
@ -24,69 +22,3 @@ vn-recover-password{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vn-login{
|
|
||||||
position: absolute;
|
|
||||||
height: 100%;
|
|
||||||
width: 100%;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
color: $color-font;
|
|
||||||
font-size: 1.1rem;
|
|
||||||
font-weight: normal;
|
|
||||||
background-color: $color-bg-dark;
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
overflow: auto;
|
|
||||||
|
|
||||||
& > .box {
|
|
||||||
box-sizing: border-box;
|
|
||||||
position: absolute;
|
|
||||||
max-width: 304px;
|
|
||||||
min-width: 240px;
|
|
||||||
padding: 48px;
|
|
||||||
background-color: $color-bg-panel;
|
|
||||||
box-shadow: 0 0 16px 0 rgba(0, 0, 0, .6);
|
|
||||||
border-radius: 8px;
|
|
||||||
|
|
||||||
& > img {
|
|
||||||
width: 100%;
|
|
||||||
padding-bottom: 16px;
|
|
||||||
}
|
|
||||||
& > form {
|
|
||||||
& > .vn-textfield {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
& > .vn-check {
|
|
||||||
display: block;
|
|
||||||
.md-label {
|
|
||||||
white-space: inherit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
h5{
|
|
||||||
color: $color-primary;
|
|
||||||
}
|
|
||||||
|
|
||||||
.text-secondary{
|
|
||||||
text-align: center;
|
|
||||||
padding-bottom: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@media screen and (max-width: 600px) {
|
|
||||||
background-color: $color-bg-panel;
|
|
||||||
|
|
||||||
& > .box {
|
|
||||||
padding: 16px;
|
|
||||||
box-shadow: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
a{
|
|
||||||
color: $color-primary;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
<div class="box">
|
||||||
|
<img src="./logo.svg"/>
|
||||||
|
<form name="form">
|
||||||
|
<ui-view></ui-view>
|
||||||
|
</form>
|
||||||
|
</div>
|
|
@ -0,0 +1,16 @@
|
||||||
|
import ngModule from '../../module';
|
||||||
|
import Component from 'core/lib/component';
|
||||||
|
import './style.scss';
|
||||||
|
|
||||||
|
export default class OutLayout extends Component {
|
||||||
|
constructor($element, $scope) {
|
||||||
|
super($element, $scope);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
OutLayout.$inject = ['$element', '$scope'];
|
||||||
|
|
||||||
|
ngModule.vnComponent('vnOutLayout', {
|
||||||
|
template: require('./index.html'),
|
||||||
|
controller: OutLayout
|
||||||
|
});
|
After Width: | Height: | Size: 6.2 KiB |
|
@ -0,0 +1,67 @@
|
||||||
|
@import "variables";
|
||||||
|
|
||||||
|
vn-out-layout{
|
||||||
|
position: absolute;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
color: $color-font;
|
||||||
|
font-size: 1.1rem;
|
||||||
|
font-weight: normal;
|
||||||
|
background-color: $color-bg-dark;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
overflow: auto;
|
||||||
|
|
||||||
|
& > .box {
|
||||||
|
box-sizing: border-box;
|
||||||
|
position: absolute;
|
||||||
|
max-width: 304px;
|
||||||
|
min-width: 240px;
|
||||||
|
padding: 48px;
|
||||||
|
background-color: $color-bg-panel;
|
||||||
|
box-shadow: 0 0 16px 0 rgba(0, 0, 0, .6);
|
||||||
|
border-radius: 8px;
|
||||||
|
|
||||||
|
& > img {
|
||||||
|
width: 100%;
|
||||||
|
padding-bottom: 16px;
|
||||||
|
}
|
||||||
|
& > form {
|
||||||
|
& > .vn-textfield {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
& > .vn-check {
|
||||||
|
display: block;
|
||||||
|
.md-label {
|
||||||
|
white-space: inherit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
h5{
|
||||||
|
color: $color-primary;
|
||||||
|
}
|
||||||
|
|
||||||
|
.text-secondary{
|
||||||
|
text-align: center;
|
||||||
|
padding-bottom: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 600px) {
|
||||||
|
background-color: $color-bg-panel;
|
||||||
|
|
||||||
|
& > .box {
|
||||||
|
padding: 16px;
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
a{
|
||||||
|
color: $color-primary;
|
||||||
|
}
|
||||||
|
}
|
|
@ -32,6 +32,6 @@ export default class Controller {
|
||||||
Controller.$inject = ['$scope', '$element', '$http', 'vnApp', '$translate', '$state'];
|
Controller.$inject = ['$scope', '$element', '$http', 'vnApp', '$translate', '$state'];
|
||||||
|
|
||||||
ngModule.vnComponent('vnRecoverPassword', {
|
ngModule.vnComponent('vnRecoverPassword', {
|
||||||
template: require('./recover-password.html'),
|
template: require('./index.html'),
|
||||||
controller: Controller
|
controller: Controller
|
||||||
});
|
});
|
|
@ -0,0 +1,3 @@
|
||||||
|
Recover password: Recuperar contraseña
|
||||||
|
We will sent you an email to recover your password: Te enviaremos un correo para restablecer tu contraseña
|
||||||
|
Notification sent!: ¡Notificación enviada!
|
|
@ -0,0 +1,24 @@
|
||||||
|
@import "variables";
|
||||||
|
|
||||||
|
vn-recover-password{
|
||||||
|
.footer {
|
||||||
|
margin-top: 32px;
|
||||||
|
text-align: center;
|
||||||
|
position: relative;
|
||||||
|
& > .vn-submit {
|
||||||
|
display: block;
|
||||||
|
|
||||||
|
& > input {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
& > .spinner-wrapper {
|
||||||
|
position: absolute;
|
||||||
|
width: 0;
|
||||||
|
top: 3px;
|
||||||
|
right: -8px;
|
||||||
|
overflow: visible;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -43,6 +43,6 @@ export default class Controller {
|
||||||
Controller.$inject = ['$scope', '$element', '$http', 'vnApp', '$translate', '$state', '$location'];
|
Controller.$inject = ['$scope', '$element', '$http', 'vnApp', '$translate', '$state', '$location'];
|
||||||
|
|
||||||
ngModule.vnComponent('vnResetPassword', {
|
ngModule.vnComponent('vnResetPassword', {
|
||||||
template: require('./reset-password.html'),
|
template: require('./index.html'),
|
||||||
controller: Controller
|
controller: Controller
|
||||||
});
|
});
|
|
@ -1,7 +1,3 @@
|
||||||
User: User
|
|
||||||
Password: Password
|
|
||||||
Do not close session: Do not close session
|
|
||||||
Enter: Enter
|
|
||||||
Password requirements: >
|
Password requirements: >
|
||||||
The password must have at least {{ length }} length characters,
|
The password must have at least {{ length }} length characters,
|
||||||
{{nAlpha}} alphabetic characters, {{nUpper}} capital letters, {{nDigits}}
|
{{nAlpha}} alphabetic characters, {{nUpper}} capital letters, {{nDigits}}
|
|
@ -0,0 +1,8 @@
|
||||||
|
Reset password: Restrablecer contraseña
|
||||||
|
New password: Nueva contraseña
|
||||||
|
Repeat password: Repetir contraseñaç
|
||||||
|
Password changed!: ¡Contraseña cambiada!
|
||||||
|
Password requirements: >
|
||||||
|
La contraseña debe tener al menos {{ length }} caracteres de longitud,
|
||||||
|
{{nAlpha}} caracteres alfabéticos, {{nUpper}} letras mayúsculas, {{nDigits}}
|
||||||
|
dígitos y {{nPunct}} símbolos (Ej: $%&.)
|
|
@ -0,0 +1,24 @@
|
||||||
|
@import "variables";
|
||||||
|
|
||||||
|
vn-reset-password{
|
||||||
|
.footer {
|
||||||
|
margin-top: 32px;
|
||||||
|
text-align: center;
|
||||||
|
position: relative;
|
||||||
|
& > .vn-submit {
|
||||||
|
display: block;
|
||||||
|
|
||||||
|
& > input {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
& > .spinner-wrapper {
|
||||||
|
position: absolute;
|
||||||
|
width: 0;
|
||||||
|
top: 3px;
|
||||||
|
right: -8px;
|
||||||
|
overflow: visible;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,27 +3,38 @@ import getMainRoute from 'core/lib/get-main-route';
|
||||||
|
|
||||||
config.$inject = ['$stateProvider', '$urlRouterProvider'];
|
config.$inject = ['$stateProvider', '$urlRouterProvider'];
|
||||||
function config($stateProvider, $urlRouterProvider) {
|
function config($stateProvider, $urlRouterProvider) {
|
||||||
$urlRouterProvider.otherwise('/');
|
$urlRouterProvider
|
||||||
|
.otherwise('/');
|
||||||
|
|
||||||
$stateProvider
|
$stateProvider
|
||||||
|
.state('layout', {
|
||||||
|
abstract: true,
|
||||||
|
template: '<vn-layout></vn-layout>',
|
||||||
|
})
|
||||||
|
.state('outLayout', {
|
||||||
|
abstract: true,
|
||||||
|
template: '<vn-out-layout></vn-out-layout>',
|
||||||
|
})
|
||||||
.state('login', {
|
.state('login', {
|
||||||
|
parent: 'outLayout',
|
||||||
url: '/login?continue',
|
url: '/login?continue',
|
||||||
description: 'Login',
|
description: 'Login',
|
||||||
views: {
|
template: '<vn-login></vn-login>'
|
||||||
'login': {template: '<vn-login></vn-login>'},
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
.state('recoverPassword', {
|
.state('recover-password', {
|
||||||
|
parent: 'outLayout',
|
||||||
url: '/recover-password',
|
url: '/recover-password',
|
||||||
description: 'Recover-password',
|
description: 'Recover password',
|
||||||
template: '<vn-recover-password>asd</vn-recover-password>'
|
template: '<vn-recover-password></vn-recover-password>'
|
||||||
})
|
})
|
||||||
.state('resetPassword', {
|
.state('reset-password', {
|
||||||
|
parent: 'outLayout',
|
||||||
url: '/reset-password',
|
url: '/reset-password',
|
||||||
description: 'Reset-password',
|
description: 'Reset password',
|
||||||
template: '<vn-reset-password></vn-reset-password>'
|
template: '<vn-reset-password></vn-reset-password>'
|
||||||
})
|
})
|
||||||
.state('home', {
|
.state('home', {
|
||||||
|
parent: 'layout',
|
||||||
url: '/',
|
url: '/',
|
||||||
description: 'Home',
|
description: 'Home',
|
||||||
template: '<vn-home></vn-home>'
|
template: '<vn-home></vn-home>'
|
||||||
|
@ -54,6 +65,10 @@ function config($stateProvider, $urlRouterProvider) {
|
||||||
};
|
};
|
||||||
if (route.abstract)
|
if (route.abstract)
|
||||||
configRoute.abstract = true;
|
configRoute.abstract = true;
|
||||||
|
|
||||||
|
if (!route.state.includes('.'))
|
||||||
|
configRoute.parent = 'layout';
|
||||||
|
|
||||||
if (route.routeParams)
|
if (route.routeParams)
|
||||||
configRoute.params = route.routeParams;
|
configRoute.params = route.routeParams;
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@ describe('workerTimeControl sendMail()', () => {
|
||||||
const ctx = {req: activeCtx, args: {}};
|
const ctx = {req: activeCtx, args: {}};
|
||||||
|
|
||||||
it('should fill time control of a worker without records in Journey and with rest', async() => {
|
it('should fill time control of a worker without records in Journey and with rest', async() => {
|
||||||
|
pending('https://redmine.verdnatura.es/issues/4903');
|
||||||
const tx = await models.WorkerTimeControl.beginTransaction({});
|
const tx = await models.WorkerTimeControl.beginTransaction({});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -34,6 +35,7 @@ describe('workerTimeControl sendMail()', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should fill time control of a worker without records in Journey and without rest', async() => {
|
it('should fill time control of a worker without records in Journey and without rest', async() => {
|
||||||
|
pending('https://redmine.verdnatura.es/issues/4903');
|
||||||
const workdayOf20Hours = 3;
|
const workdayOf20Hours = 3;
|
||||||
const tx = await models.WorkerTimeControl.beginTransaction({});
|
const tx = await models.WorkerTimeControl.beginTransaction({});
|
||||||
|
|
||||||
|
@ -61,6 +63,7 @@ describe('workerTimeControl sendMail()', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should fill time control of a worker with records in Journey and with rest', async() => {
|
it('should fill time control of a worker with records in Journey and with rest', async() => {
|
||||||
|
pending('https://redmine.verdnatura.es/issues/4903');
|
||||||
const tx = await models.WorkerTimeControl.beginTransaction({});
|
const tx = await models.WorkerTimeControl.beginTransaction({});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -92,6 +95,7 @@ describe('workerTimeControl sendMail()', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should fill time control of a worker with records in Journey and without rest', async() => {
|
it('should fill time control of a worker with records in Journey and without rest', async() => {
|
||||||
|
pending('https://redmine.verdnatura.es/issues/4903');
|
||||||
const tx = await models.WorkerTimeControl.beginTransaction({});
|
const tx = await models.WorkerTimeControl.beginTransaction({});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -201,6 +201,7 @@ describe('workerTimeControl add/delete timeEntry()', () => {
|
||||||
|
|
||||||
describe('WorkerTimeControl_clockIn calls', () => {
|
describe('WorkerTimeControl_clockIn calls', () => {
|
||||||
it('should fail to add a time entry if the target user has an absence that day', async() => {
|
it('should fail to add a time entry if the target user has an absence that day', async() => {
|
||||||
|
pending('https://redmine.verdnatura.es/issues/4707');
|
||||||
activeCtx.accessToken.userId = salesBossId;
|
activeCtx.accessToken.userId = salesBossId;
|
||||||
const workerId = hankPymId;
|
const workerId = hankPymId;
|
||||||
const date = new Date();
|
const date = new Date();
|
||||||
|
@ -247,6 +248,7 @@ describe('workerTimeControl add/delete timeEntry()', () => {
|
||||||
|
|
||||||
describe('direction errors', () => {
|
describe('direction errors', () => {
|
||||||
it('should throw an error when trying "in" direction twice', async() => {
|
it('should throw an error when trying "in" direction twice', async() => {
|
||||||
|
pending('https://redmine.verdnatura.es/issues/4707');
|
||||||
activeCtx.accessToken.userId = salesBossId;
|
activeCtx.accessToken.userId = salesBossId;
|
||||||
const workerId = hankPymId;
|
const workerId = hankPymId;
|
||||||
|
|
||||||
|
@ -276,6 +278,7 @@ describe('workerTimeControl add/delete timeEntry()', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should throw an error when trying "in" direction after insert "in" and "middle"', async() => {
|
it('should throw an error when trying "in" direction after insert "in" and "middle"', async() => {
|
||||||
|
pending('https://redmine.verdnatura.es/issues/4707');
|
||||||
activeCtx.accessToken.userId = salesBossId;
|
activeCtx.accessToken.userId = salesBossId;
|
||||||
const workerId = hankPymId;
|
const workerId = hankPymId;
|
||||||
|
|
||||||
|
@ -309,6 +312,7 @@ describe('workerTimeControl add/delete timeEntry()', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Should throw an error when trying "out" before closing a "middle" couple', async() => {
|
it('Should throw an error when trying "out" before closing a "middle" couple', async() => {
|
||||||
|
pending('https://redmine.verdnatura.es/issues/4707');
|
||||||
activeCtx.accessToken.userId = salesBossId;
|
activeCtx.accessToken.userId = salesBossId;
|
||||||
const workerId = hankPymId;
|
const workerId = hankPymId;
|
||||||
|
|
||||||
|
@ -342,6 +346,7 @@ describe('workerTimeControl add/delete timeEntry()', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should throw an error when trying "middle" after "out"', async() => {
|
it('should throw an error when trying "middle" after "out"', async() => {
|
||||||
|
pending('https://redmine.verdnatura.es/issues/4707');
|
||||||
activeCtx.accessToken.userId = salesBossId;
|
activeCtx.accessToken.userId = salesBossId;
|
||||||
const workerId = hankPymId;
|
const workerId = hankPymId;
|
||||||
|
|
||||||
|
@ -375,6 +380,7 @@ describe('workerTimeControl add/delete timeEntry()', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should throw an error when trying "out" direction twice', async() => {
|
it('should throw an error when trying "out" direction twice', async() => {
|
||||||
|
pending('https://redmine.verdnatura.es/issues/4707');
|
||||||
activeCtx.accessToken.userId = salesBossId;
|
activeCtx.accessToken.userId = salesBossId;
|
||||||
const workerId = hankPymId;
|
const workerId = hankPymId;
|
||||||
|
|
||||||
|
@ -446,6 +452,7 @@ describe('workerTimeControl add/delete timeEntry()', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not fail as the 12h rest is fulfilled', async() => {
|
it('should not fail as the 12h rest is fulfilled', async() => {
|
||||||
|
pending('https://redmine.verdnatura.es/issues/4707');
|
||||||
activeCtx.accessToken.userId = salesBossId;
|
activeCtx.accessToken.userId = salesBossId;
|
||||||
const workerId = hankPymId;
|
const workerId = hankPymId;
|
||||||
|
|
||||||
|
@ -482,6 +489,7 @@ describe('workerTimeControl add/delete timeEntry()', () => {
|
||||||
|
|
||||||
describe('for 3500kg drivers with enforced 9h rest', () => {
|
describe('for 3500kg drivers with enforced 9h rest', () => {
|
||||||
it('should throw an error when the 9h enforced rest is not fulfilled', async() => {
|
it('should throw an error when the 9h enforced rest is not fulfilled', async() => {
|
||||||
|
pending('https://redmine.verdnatura.es/issues/4707');
|
||||||
activeCtx.accessToken.userId = salesBossId;
|
activeCtx.accessToken.userId = salesBossId;
|
||||||
const workerId = jessicaJonesId;
|
const workerId = jessicaJonesId;
|
||||||
|
|
||||||
|
@ -516,6 +524,7 @@ describe('workerTimeControl add/delete timeEntry()', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not fail when the 9h enforced rest is fulfilled', async() => {
|
it('should not fail when the 9h enforced rest is fulfilled', async() => {
|
||||||
|
pending('https://redmine.verdnatura.es/issues/4707');
|
||||||
activeCtx.accessToken.userId = salesBossId;
|
activeCtx.accessToken.userId = salesBossId;
|
||||||
const workerId = jessicaJonesId;
|
const workerId = jessicaJonesId;
|
||||||
|
|
||||||
|
@ -552,6 +561,7 @@ describe('workerTimeControl add/delete timeEntry()', () => {
|
||||||
|
|
||||||
describe('for 36h weekly rest', () => {
|
describe('for 36h weekly rest', () => {
|
||||||
it('should throw an error when the 36h weekly rest is not fulfilled', async() => {
|
it('should throw an error when the 36h weekly rest is not fulfilled', async() => {
|
||||||
|
pending('https://redmine.verdnatura.es/issues/4707');
|
||||||
activeCtx.accessToken.userId = salesBossId;
|
activeCtx.accessToken.userId = salesBossId;
|
||||||
const workerId = hankPymId;
|
const workerId = hankPymId;
|
||||||
|
|
||||||
|
@ -586,6 +596,7 @@ describe('workerTimeControl add/delete timeEntry()', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should throw an error when the 36h weekly rest is not fulfilled again', async() => {
|
it('should throw an error when the 36h weekly rest is not fulfilled again', async() => {
|
||||||
|
pending('https://redmine.verdnatura.es/issues/4707');
|
||||||
activeCtx.accessToken.userId = salesBossId;
|
activeCtx.accessToken.userId = salesBossId;
|
||||||
const workerId = hankPymId;
|
const workerId = hankPymId;
|
||||||
|
|
||||||
|
@ -619,6 +630,7 @@ describe('workerTimeControl add/delete timeEntry()', () => {
|
||||||
|
|
||||||
describe('for 72h weekly rest', () => {
|
describe('for 72h weekly rest', () => {
|
||||||
it('should throw when the 72h weekly rest is not fulfilled yet', async() => {
|
it('should throw when the 72h weekly rest is not fulfilled yet', async() => {
|
||||||
|
pending('https://redmine.verdnatura.es/issues/4707');
|
||||||
activeCtx.accessToken.userId = salesBossId;
|
activeCtx.accessToken.userId = salesBossId;
|
||||||
const workerId = hankPymId;
|
const workerId = hankPymId;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue