Merge branch 'dev' into feature/landing-page

This commit is contained in:
Mariela Bonilla 2021-07-23 02:13:39 -06:00
commit 3bd65155e7
57 changed files with 907 additions and 297 deletions

View File

@ -1,7 +1,8 @@
package org.datasurvey.repository;
import org.datasurvey.domain.Categoria;
import org.springframework.data.jpa.repository.*;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.stereotype.Repository;
/**

View File

@ -168,7 +168,11 @@ public class AccountResource {
public void requestPasswordReset(@RequestBody String mail) {
Optional<User> user = userService.requestPasswordReset(mail);
if (user.isPresent()) {
mailService.sendPasswordResetMail(user.get());
if (user.get().getFirstName() == null || (!user.get().getFirstName().equals("IsGoogle"))) {
mailService.sendPasswordResetMail(user.get());
} else {
throw new UserIsGoogleException();
}
} else {
// Pretend the request has been successful to prevent checking which emails really exist
// but log that an invalid attempt has been made

View File

@ -13,6 +13,7 @@ public final class ErrorConstants {
public static final URI EMAIL_ALREADY_USED_TYPE = URI.create(PROBLEM_BASE_URL + "/email-already-used");
public static final URI LOGIN_ALREADY_USED_TYPE = URI.create(PROBLEM_BASE_URL + "/login-already-used");
public static final URI EMAIL_NOT_EXISTS_TYPE = URI.create(PROBLEM_BASE_URL + "/email-not-exists");
public static final URI USER_IS_GOOGLE_TYOE = URI.create(PROBLEM_BASE_URL + "/user-is-google");
private ErrorConstants() {}
}

View File

@ -0,0 +1,10 @@
package org.datasurvey.web.rest.errors;
public class UserIsGoogleException extends BadRequestAlertException {
private static final long serialVersionUID = 1L;
public UserIsGoogleException() {
super(ErrorConstants.USER_IS_GOOGLE_TYOE, "User Is Google", "userManagement", "userisgoogle");
}
}

View File

@ -5,25 +5,25 @@ error.status=Estado:
error.message=Mensaje:
# Activation email
email.activation.title=Activación de DataSurvey
email.activation.title=Confirmación de correo con DataSurvey
email.activation.greeting=¡Hola, {0}!
email.activation.text1=Su cuenta en DataSurvey ha sido creada. Por favor, haga clic en el siguiente enlace para activarla:
email.activation.text1=¡Nos alegra que sea parte de DataSurvey! Como último paso debe confirmar su dirección de correo haciendo clic en el siguiente enlace:
email.activation.text2=Saludos,
email.signature=Equipo de DataSurvey.
email.signature=Equipo de DataSurvey
# Creation email
email.creation.text1=Su cuenta en DataSurvey ha sido creada. Por favor, haga clic en el siguiente enlace para utilizarla:
# Reset email
email.reset.title=Reinicio de contraseña de DataSurvey
email.reset.title=Restablecer contraseña de DataSurvey
email.reset.greeting=¡Hola, {0}!
email.reset.text1=Se ha solicitado el reinicio de la contraseña para su cuenta en DataSurvey. Por favor, haga clic en el siguiente enlace para reiniciarla:
email.reset.text1=Se ha solicitado una modificación de contraseña para su cuenta en DataSurvey. Por favor haga clic en el siguiente enlace para restablecerla:
email.reset.text2=Saludos,
# Password Restored Mail
email.restored.title=Se restaleció su contraseña en DataSurvey
email.restored.title=Modificación de contraseña exitosa
email.restored.greeting=¡Hola, {0}!
email.restored.text1=Se ha restablecido correctamente su contraseña en DataSurvey.
email.restored.text1=¡Se ha restablecido correctamente su contraseña en DataSurvey!
email.restored.text2=Saludos,
email.restored.text3=Si usted no realizó este cambio, favor notifique inmediatamente al siguiente correo:
email.restored.email=datasurvey@gmail.com

View File

@ -264,7 +264,7 @@
th:with="url=(@{|${baseUrl}/account/activate?key=${user.activationKey}|})"
th:href="${url}"
class="btn btn-primary"
>Activar cuenta</a
>Confirmar correo electrónico</a
>
</p>
</div>
@ -293,7 +293,7 @@
<tr>
<td style="text-align: left; padding-right: 10px">
<h3 class="heading">Acerca de</h3>
<p>DataSurvey es su compañero más cercano para poder recolectar información valiosa para usted.</p>
<p>DataSurvey es su compañero más cercano para poder recolectar información valiosa para usted</p>
</td>
</tr>
</table>
@ -304,7 +304,7 @@
<td style="text-align: left; padding-left: 5px; padding-right: 5px">
<h3 class="heading">Información de contacto</h3>
<ul>
<li><span class="text">datasurvey@gmail.com</span></li>
<li><span href="mailto:datasurveyapp@gmail.com" class="text">datasurveyapp@gmail.com</span></li>
</ul>
</td>
</tr>

View File

@ -304,7 +304,7 @@
<td style="text-align: left; padding-left: 5px; padding-right: 5px">
<h3 class="heading">Información de contacto</h3>
<ul>
<li><span class="text">datasurvey@gmail.com</span></li>
<li><span href="mailto:datasurveyapp@gmail.com" class="text">datasurveyapp@gmail.com</span></li>
</ul>
</td>
</tr>

View File

@ -304,7 +304,7 @@
<td style="text-align: left; padding-left: 5px; padding-right: 5px">
<h3 class="heading">Información de contacto</h3>
<ul>
<li><span class="text">datasurvey@gmail.com</span></li>
<li><span href="mailto:datasurveyapp@gmail.com" class="text">datasurveyapp@gmail.com</span></li>
</ul>
</td>
</tr>

View File

@ -267,7 +267,7 @@
>If you did not make this change, please notify the following email immediately</span
>
<a th:href="#{'mailto:'+email.restored.email}" th:text="#{email.restored.email}">datasurvey@gmail.com</a>
<a href="mailto:datasurveyapp@gmail.com" th:text="#{email.restored.email}">datasurveyapp@gmail.com</a>
</p>
</div>
<div class="text" style="padding: 0.2em 2.5em 0.5em; text-align: center">
@ -306,7 +306,7 @@
<td style="text-align: left; padding-left: 5px; padding-right: 5px">
<h3 class="heading">Información de contacto</h3>
<ul>
<li><span class="text">datasurvey@gmail.com</span></li>
<li><span href="mailto:datasurveyapp@gmail.com" class="text">datasurveyapp@gmail.com</span></li>
</ul>
</td>
</tr>

View File

@ -15,13 +15,12 @@
style="color: #727070; font-weight: 700; font-size: 1.3rem"
jhiTranslate="activate.title"
>
Activación de Cuenta
Registro Completado
</h4>
</div>
<div *ngIf="success">
<div class="alert alert-success text-center my-2">
<span jhiTranslate="activate.messages.success"><strong>Your user account has been activated.</strong></span>
<span jhiTranslate="global.messages.info.authenticated.link">sign in</span>
<span jhiTranslate="activate.messages.success"></span>
</div>
<div class="d-flex justify-content-center">
<button class="ds-btn ds-btn--primary" routerLink="/login" jhiTranslate="global.messages.info.authenticated.link">
@ -30,9 +29,7 @@
</div>
</div>
<div *ngIf="error">
<div class="alert alert-danger text-center my-2" jhiTranslate="activate.messages.error">
<strong>Your user could not be activated.</strong> Please use the registration form to sign up.
</div>
<div class="alert alert-danger text-center my-2" jhiTranslate="activate.messages.error"></div>
<div class="d-flex justify-content-center">
<button class="ds-btn ds-btn--primary" routerLink="/account/register" jhiTranslate="global.registerLink">
create account</button

View File

@ -35,7 +35,6 @@
<div *ngIf="success">
<div class="alert alert-success text-center my-2">
<span jhiTranslate="reset.finish.messages.success"><strong>Your password has been reset.</strong></span>
<strong><span jhiTranslate="global.messages.info.authenticated.link">sign in</span></strong>
</div>
<div class="d-flex justify-content-center">
<button class="ds-btn ds-btn--primary" routerLink="/login" jhiTranslate="global.messages.info.authenticated.botonInicio">

View File

@ -15,7 +15,7 @@
style="color: #727070; font-weight: 700; font-size: 1.3rem"
jhiTranslate="reset.request.title"
>
RESET YOUR PASSWORDD
RESET YOUR PASSWORD
</h4>
<p class="mb-4" style="color: rgba(146, 146, 146, 0.664)" jhiTranslate="reset.request.messages.info">
Enter the email address you used to register.
@ -27,12 +27,15 @@
</div>
<div class="alert alert-danger" *ngIf="errorEmailNotExists" jhiTranslate="reset.request.messages.error.emailnotexists">
<strong>Email no exists!</strong> Please choose another one.
<strong>Email no exists!</strong>
</div>
<div class="alert alert-danger" *ngIf="errorUserIsGoogle" jhiTranslate="reset.request.messages.error.userisgoogle">
<strong>No cuenta con el permiso de restablecer su contraseña al haber activado su cuenta por medio de Google</strong>
</div>
</div>
<form *ngIf="!success" name="form" class="ds-form" role="form" (ngSubmit)="requestReset()" [formGroup]="resetRequestForm">
<div class="form-group">
<label class="form-label" for="email" jhiTranslate="global.form.email.label">Email</label>
<label class="form-control-label" for="email" jhiTranslate="global.form.email.label">Email</label>
<input
type="email"
class="form-control"
@ -65,25 +68,6 @@
>
Your email is invalid.
</small>
<small
class="form-text text-danger"
*ngIf="resetRequestForm.get('email')?.errors?.minlength"
jhiTranslate="global.messages.validate.email.minlength"
>
Your email is required to be at least 5 characters.
</small>
<small
class="form-text text-danger"
*ngIf="resetRequestForm.get('email')?.errors?.maxlength"
jhiTranslate="global.messages.validate.email.maxlength"
>
Your email cannot be longer than 100 characters.
</small>
<small class="form-text text-danger" *ngIf="resetRequestForm.get('email')?.errors?.email">
Se requiere un correo electrónico válido.
</small>
</div>
</div>
@ -115,7 +99,7 @@
<div class="row mt-3">
<div class="col-12 text-center">
<p class="text-muted">
¿Aún no se encuentra registrado/a?
¿Aún no es parte de DataSurvey?
<a routerLink="/account/register" class="text-muted ms-1"><b>Crea una cuenta</b></a>
</p>
</div>

View File

@ -3,7 +3,7 @@ import { FormBuilder, Validators } from '@angular/forms';
import { PasswordResetInitService } from './password-reset-init.service';
import { HttpErrorResponse } from '@angular/common/http';
import { EMAIL_NOT_EXISTS_TYPE } from '../../../config/error.constants';
import { EMAIL_NOT_EXISTS_TYPE, USER_IS_GOOGLE_TYPE } from '../../../config/error.constants';
@Component({
selector: 'jhi-password-reset-init',
@ -13,6 +13,7 @@ export class PasswordResetInitComponent implements AfterViewInit {
@ViewChild('email', { static: false })
email?: ElementRef;
errorEmailNotExists = false;
errorUserIsGoogle = false;
error = false;
success = false;
resetRequestForm = this.fb.group({
@ -29,6 +30,7 @@ export class PasswordResetInitComponent implements AfterViewInit {
requestReset(): void {
this.errorEmailNotExists = false;
this.errorUserIsGoogle = false;
this.passwordResetInitService.save(this.resetRequestForm.get(['email'])!.value).subscribe(
() => (this.success = true),
response => this.processError(response)
@ -42,6 +44,8 @@ export class PasswordResetInitComponent implements AfterViewInit {
processError(response: HttpErrorResponse): void {
if (response.status === 400 && response.error.type === EMAIL_NOT_EXISTS_TYPE) {
this.errorEmailNotExists = true;
} else if (response.status === 400 && response.error.type === USER_IS_GOOGLE_TYPE) {
this.errorUserIsGoogle = true;
} else {
this.error = true;
}

View File

@ -8,13 +8,21 @@
</div>
<div class="card-body p-4">
<div class="text-center w-75 m-auto">
<div class="text-center w-75 m-auto" *ngIf="!success">
<h4 class="text-dark-50 text-center pb-0 fw-bold p-0 m-0" style="color: #727070; font-weight: 700; font-size: 1.3rem">
REGISTRARSE
</h4>
<p class="mb-4" style="color: rgba(146, 146, 146, 0.664)">Ingrese sus datos para registrarse.</p>
<p class="mb-4" style="color: rgba(146, 146, 146, 0.664)">Ingrese sus datos para registrarse</p>
</div>
<div class="text-center w-75 m-auto" *ngIf="success">
<h4 class="text-dark-50 text-center pb-0 fw-bold p-0 m-0" style="color: #727070; font-weight: 700; font-size: 1.3rem">
¡Gracias por registrarse en DataSurvey!
</h4>
</div>
<hr />
<div class="alert alert-success" *ngIf="success" jhiTranslate="register.messages.success">
<strong>Registration saved!</strong> Please check your email for confirmation.
</div>

View File

@ -63,6 +63,7 @@ describe('Component Tests', () => {
login: '',
langKey: 'es',
name: '',
firstName: 'normalUser',
profileIcon: 1,
isAdmin: 0,
isGoogle: 0,

View File

@ -84,6 +84,7 @@ export class RegisterComponent implements AfterViewInit {
const login = this.registerForm.get(['email'])!.value;
const email = this.registerForm.get(['email'])!.value;
const name = this.registerForm.get(['name'])!.value;
const firstName = 'normalUser';
this.registerService
.save({
@ -92,6 +93,7 @@ export class RegisterComponent implements AfterViewInit {
password,
langKey: this.translateService.currentLang,
name,
firstName,
profileIcon: this.profileIcon,
isAdmin: 0,
isGoogle: 0,

View File

@ -7,6 +7,7 @@ export class Registration {
public name: string,
public profileIcon: number,
public isAdmin: number,
public isGoogle: number
public isGoogle: number,
public firstName: string
) {}
}

View File

@ -175,7 +175,7 @@
<p class="ds-title">Perfil</p>
</div>
<div>
<p class="ds-subtitle">Información general de su usuario, el correo electrónico es su identificador en DataSurvey.</p>
<p class="ds-subtitle">Información general de su usuario, el correo electrónico es su identificador en DataSurvey</p>
</div>
</div>
</div>
@ -246,7 +246,7 @@
</div>
<div class="row mb-4">
<div class="form-group w-100">
<label for="iconoPerfil">Ícono de perfil</label>
<label>Ícono de perfil</label>
<div class="d-flex">
<jhi-swiper style="width: 22.5rem !important" [data]="profileIcons" (onSelectEvent)="selectIcon($event)"></jhi-swiper>
</div>
@ -284,7 +284,7 @@
</div>
<div>
<p class="ds-subtitle">
Utilice una contraseña segura al realizar el cambio, este dato debe ser secreto ya que provee acceso a su cuenta.
Utilice una contraseña segura al realizar el cambio, este dato debe ser secreto ya que provee acceso a su cuenta
</p>
</div>
@ -305,19 +305,35 @@
<div class="row mb-3 pb-3" style="border-bottom: 1px solid #e7ebf3">
<div
class="alert alert-danger"
*ngIf="errorPassword && !doNotMatch && !successPassword"
*ngIf="errorPassword && !doNotMatch && !successPassword && !samePassword"
jhiTranslate="global.messages.info.authenticated.passwordForm"
data-cy="loginError"
></div>
<div *ngIf="successPassword" class="alert alert-success alert-dismissible fade show" role="alert">
<div
*ngIf="successPassword && !errorPassword && !samePassword && !doNotMatch"
class="alert alert-success alert-dismissible fade show"
role="alert"
>
Sus contraseña fue actualizada de manera exitosa
<!-- <button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>-->
</div>
<div class="alert alert-danger" *ngIf="doNotMatch && !successPassword" jhiTranslate="global.messages.error.dontmatch">
<div
class="alert alert-danger"
*ngIf="doNotMatch && !successPassword && !errorPassword"
jhiTranslate="global.messages.error.dontmatch"
>
The password and its confirmation do not match!
</div>
<div
class="alert alert-danger"
*ngIf="samePassword && !successPassword && !errorPassword && !doNotMatch"
jhiTranslate="global.messages.error.samePassword"
>
The password and its confirmation do not match!
</div>
@ -477,7 +493,7 @@
type="submit"
id="save-entity"
data-cy="entityCreateSaveButton"
[disabled]="isSaving"
[disabled]="passwordForm.invalid || isSaving"
class="ds-btn ds-btn--primary"
>
<span jhiTranslate="entity.action.save">Save</span>

View File

@ -26,6 +26,7 @@ export class SettingsComponent implements OnInit {
isSaving = false;
success = false;
successPassword = false;
samePassword = false;
error = false;
errorPassword = false;
doNotMatch = false;
@ -49,8 +50,8 @@ export class SettingsComponent implements OnInit {
//form de la contraseña
passwordForm = this.fb.group({
password: [null, [Validators.required], Validators.minLength(8), Validators.maxLength(50)],
passwordNew: [null, [Validators.required], Validators.minLength(8), Validators.maxLength(50)],
password: [null, [Validators.required, Validators.minLength(8), Validators.maxLength(50)]],
passwordNew: [null, [Validators.required, Validators.minLength(8), Validators.maxLength(50)]],
passwordNewConfirm: [null, [Validators.required, Validators.minLength(8), Validators.maxLength(50)]],
});
@ -120,7 +121,7 @@ export class SettingsComponent implements OnInit {
}
});
console.log(this.isGoogle);
//console.log(this.isGoogle);
// this.activatedRoute.data.subscribe(({ usuarioExtra }) => {
@ -143,14 +144,25 @@ export class SettingsComponent implements OnInit {
}
savePassword(): void {
this.successPassword = false;
this.doNotMatch = false;
this.samePassword = false;
this.errorPassword = false;
const passwordNew = this.passwordForm.get(['passwordNew'])!.value;
if (passwordNew !== this.passwordForm.get(['passwordNewConfirm'])!.value) {
this.doNotMatch = true;
const passwordOld = this.passwordForm.get(['password'])!.value;
if (passwordOld == passwordNew) {
this.samePassword = true;
} else {
this.passwordService.save(this.passwordForm.get(['passwordNew'])!.value, this.passwordForm.get(['password'])!.value).subscribe(
() => (this.successPassword = true),
() => (this.errorPassword = true)
);
if (passwordNew !== this.passwordForm.get(['passwordNewConfirm'])!.value) {
(this.doNotMatch = true), (this.samePassword = false);
} else {
this.passwordService.save(passwordNew, passwordOld).subscribe(
() => (this.successPassword = true),
() => (this.errorPassword = true)
);
}
}
}
@ -175,15 +187,16 @@ export class SettingsComponent implements OnInit {
protected subscribeToSaveResponse(result: Observable<HttpResponse<IUsuarioExtra>>): void {
result.pipe(finalize(() => this.onSaveFinalize())).subscribe(
() => (
(this.success = true),
this.router.navigate(['account/settings']).then(() => {
window.location.reload();
})
),
() => ((this.success = true), this.windowReload()),
response => this.processError(response)
);
}
windowReload() {
this.router.navigate(['account/settings']).then(() => {
window.location.reload();
});
}
processError(response: HttpErrorResponse): void {
if (response.status === 400) {
this.error = true;
@ -217,8 +230,10 @@ export class SettingsComponent implements OnInit {
// Update swiper
this.profileIcon = usuarioExtra.iconoPerfil!;
console.log(this.profileIcon);
this.profileIcons.forEach(icon => {
if (parseInt(icon.name.split('C')[1]) === this.profileIcon) {
if (icon.name.split('C')[1] === this.profileIcon) {
icon.class = 'active';
}
});
@ -269,7 +284,7 @@ export class SettingsComponent implements OnInit {
event.target.classList.add('active');
this.profileIcon = +event.target.getAttribute('id')! + 1;
console.log(this.profileIcon);
//console.log(this.profileIcon);
}
}
}

View File

@ -2,3 +2,4 @@ export const PROBLEM_BASE_URL = 'https://www.jhipster.tech/problem';
export const EMAIL_ALREADY_USED_TYPE = PROBLEM_BASE_URL + '/email-already-used';
export const LOGIN_ALREADY_USED_TYPE = PROBLEM_BASE_URL + '/login-already-used';
export const EMAIL_NOT_EXISTS_TYPE = PROBLEM_BASE_URL + '/email-not-exists';
export const USER_IS_GOOGLE_TYPE = PROBLEM_BASE_URL + '/user-is-google';

View File

@ -22,7 +22,7 @@ export interface Alert {
providedIn: 'root',
})
export class AlertService {
timeout = 5000;
timeout = 3000;
toast = false;
position = 'top right';
@ -65,7 +65,7 @@ export class AlertService {
alert.timeout = alert.timeout ?? this.timeout;
alert.toast = alert.toast ?? this.toast;
alert.position = alert.position ?? this.position;
alert.close = (alertsArray: Alert[]) => this.closeAlert(alert.id!, alertsArray);
//alert.close = (alertsArray: Alert[]) => this.closeAlert(alert.id!, alertsArray);
(extAlerts ?? this.alerts).push(alert);

View File

@ -1,25 +1,26 @@
<form class="ds-form" *ngIf="categoria" name="deleteForm" (ngSubmit)="confirmDelete(categoria.id!)">
<div class="modal-header">
<h4 class="modal-title" data-cy="categoriaDeleteDialogHeading" jhiTranslate="entity.delete.title">Confirm delete operation</h4>
<button type="button" class="ds-btn close" data-dismiss="modal" aria-hidden="true" (click)="cancel()">&times;</button>
</div>
<form class="ds-form" *ngIf="categoria" name="deleteForm" (ngSubmit)="confirmDelete(categoria!)">
<div class="modal-header"></div>
<div class="modal-body">
<jhi-alert-error></jhi-alert-error>
<p id="jhi-delete-categoria-heading" jhiTranslate="dataSurveyApp.categoria.delete.question" [translateValues]="{ id: categoria.id }">
Are you sure you want to delete this Categoria?
<p
id="jhi-delete-categoria-heading"
jhiTranslate="dataSurveyApp.categoria.delete.question"
[translateValues]="{ nombre: categoria.nombre }"
style="text-align: center"
>
Are you sure you want to toggle this category's status?
</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary ds-btn ds-btn-secondary" data-dismiss="modal" (click)="cancel()">
<fa-icon icon="ban"></fa-icon>&nbsp;<span jhiTranslate="entity.action.cancel">Cancel</span>
&nbsp;<span jhiTranslate="entity.action.cancel">Cancel</span>
</button>
<button id="jhi-confirm-delete-categoria" data-cy="entityConfirmDeleteButton" type="submit" class="btn btn-danger ds-btn ds-btn-danger">
<fa-icon icon="times"></fa-icon>&nbsp;<span jhiTranslate="entity.action.delete">Delete</span>
<span jhiTranslate="entity.action.toggleStatus">Toggle Status</span>
</button>
</div>
</form>

View File

@ -1,65 +0,0 @@
jest.mock('@ng-bootstrap/ng-bootstrap');
import { ComponentFixture, TestBed, inject, fakeAsync, tick } from '@angular/core/testing';
import { HttpResponse } from '@angular/common/http';
import { HttpClientTestingModule } from '@angular/common/http/testing';
import { of } from 'rxjs';
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
import { CategoriaService } from '../service/categoria.service';
import { CategoriaDeleteDialogComponent } from './categoria-delete-dialog.component';
describe('Component Tests', () => {
describe('Categoria Management Delete Component', () => {
let comp: CategoriaDeleteDialogComponent;
let fixture: ComponentFixture<CategoriaDeleteDialogComponent>;
let service: CategoriaService;
let mockActiveModal: NgbActiveModal;
beforeEach(() => {
TestBed.configureTestingModule({
imports: [HttpClientTestingModule],
declarations: [CategoriaDeleteDialogComponent],
providers: [NgbActiveModal],
})
.overrideTemplate(CategoriaDeleteDialogComponent, '')
.compileComponents();
fixture = TestBed.createComponent(CategoriaDeleteDialogComponent);
comp = fixture.componentInstance;
service = TestBed.inject(CategoriaService);
mockActiveModal = TestBed.inject(NgbActiveModal);
});
describe('confirmDelete', () => {
it('Should call delete service on confirmDelete', inject(
[],
fakeAsync(() => {
// GIVEN
jest.spyOn(service, 'delete').mockReturnValue(of(new HttpResponse({})));
// WHEN
comp.confirmDelete(123);
tick();
// THEN
expect(service.delete).toHaveBeenCalledWith(123);
expect(mockActiveModal.close).toHaveBeenCalledWith('deleted');
})
));
it('Should not call delete service on clear', () => {
// GIVEN
jest.spyOn(service, 'delete');
// WHEN
comp.cancel();
// THEN
expect(service.delete).not.toHaveBeenCalled();
expect(mockActiveModal.close).not.toHaveBeenCalled();
expect(mockActiveModal.dismiss).toHaveBeenCalled();
});
});
});
});

View File

@ -1,7 +1,13 @@
import { HttpResponse } from '@angular/common/http';
import { Component } from '@angular/core';
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
import { IEncuesta } from 'app/entities/encuesta/encuesta.model';
import { EncuestaService } from 'app/entities/encuesta/service/encuesta.service';
import { EstadoCategoria } from 'app/entities/enumerations/estado-categoria.model';
import { Observable } from 'rxjs';
import { finalize, map } from 'rxjs/operators';
import { ICategoria } from '../categoria.model';
import { Categoria, ICategoria } from '../categoria.model';
import { CategoriaService } from '../service/categoria.service';
@Component({
@ -9,16 +15,62 @@ import { CategoriaService } from '../service/categoria.service';
})
export class CategoriaDeleteDialogComponent {
categoria?: ICategoria;
encuestas?: IEncuesta[];
encuestasFiltradas?: IEncuesta[];
constructor(protected categoriaService: CategoriaService, protected activeModal: NgbActiveModal) {}
constructor(
protected categoriaService: CategoriaService,
protected activeModal: NgbActiveModal,
protected encuestaService: EncuestaService
) {
this.getEncuestas();
}
cancel(): void {
this.activeModal.dismiss();
}
confirmDelete(id: number): void {
this.categoriaService.delete(id).subscribe(() => {
confirmDelete(categoria: ICategoria): void {
const categoriaNula = new Categoria(0, 'Otra', EstadoCategoria.ACTIVE);
this.getEncuestas();
if (categoria.estado == EstadoCategoria.INACTIVE) {
categoria.estado = EstadoCategoria.ACTIVE;
} else {
this.encuestas!.forEach(encuesta => {
if (encuesta.categoria != null && encuesta.categoria!.id === categoria.id) {
encuesta.categoria = categoriaNula;
this.subscribeToSaveResponse(this.encuestaService.update(encuesta));
}
});
categoria.estado = EstadoCategoria.INACTIVE;
}
this.categoriaService.update(categoria).subscribe(() => {
this.activeModal.close('deleted');
});
}
getEncuestas(): void {
this.encuestaService.query().subscribe(res => {
this.encuestas = res.body ?? [];
});
}
protected subscribeToSaveResponse(result: Observable<HttpResponse<IEncuesta>>): void {
result.pipe(finalize(() => this.onSaveFinalize())).subscribe(
() => this.onSaveSuccess(),
() => this.onSaveError()
);
}
protected onSaveFinalize(): void {
// this.isSaving = false;
}
protected onSaveSuccess(): void {
// this.previousState();
}
protected onSaveError(): void {
// Api for inheritance.
}
}

View File

@ -25,11 +25,16 @@
</dl>
<button type="submit" (click)="previousState()" class="btn btn-ds btn-info" data-cy="entityDetailsBackButton">
<fa-icon icon="arrow-left"></fa-icon>&nbsp;<span jhiTranslate="entity.action.back">Back</span>
&nbsp;<span jhiTranslate="entity.action.back">Back</span>
</button>
<button type="button" [routerLink]="['/categoria', categoria.id, 'edit']" class="btn btn-ds btn-ds-primary btn-primary">
<fa-icon icon="pencil-alt"></fa-icon>&nbsp;<span jhiTranslate="entity.action.edit">Edit</span>
<button
*ngIf="categoria.id != 0"
type="button"
[routerLink]="['/categoria', categoria.id, 'edit']"
class="btn btn-ds btn-ds-primary btn-primary"
>
&nbsp;<span jhiTranslate="entity.action.edit">Edit</span>
</button>
</div>
</div>

View File

@ -15,9 +15,15 @@
</div>
</h2>
<jhi-alert-error></jhi-alert-error>
<!-- <div class="alert alert-success" *ngIf="success" jhiTranslate="dataSurveyApp.categoria.delete.error">
<jhi-alert></jhi-alert>
</div>-->
<div>
<jhi-alert class="alert-success"></jhi-alert>
</div>
<div class="alert alert-success" *ngIf="success" jhiTranslate="dataSurveyApp.categoria.delete.success"></div>
<div class="alert alert-warning" id="no-result" *ngIf="categorias?.length === 0">
<span jhiTranslate="dataSurveyApp.categoria.home.notFound">No categorias found</span>
@ -40,9 +46,9 @@
</thead>
<tbody>
<tr *ngFor="let categoria of categorias | filter: 'nombre':searchString; trackBy: trackId" data-cy="entityTable">
<td>{{ categoria.nombre }}</td>
<td jhiTranslate="{{ 'dataSurveyApp.EstadoCategoria.' + categoria.estado }}">{{ categoria.estado }}</td>
<td class="text-right">
<td *ngIf="categoria.id != 0">{{ categoria.nombre }}</td>
<td *ngIf="categoria.id != 0" jhiTranslate="{{ 'dataSurveyApp.EstadoCategoria.' + categoria.estado }}">{{ categoria.estado }}</td>
<td *ngIf="categoria.id != 0" class="text-right">
<div class="btn-group">
<button
type="submit"
@ -50,13 +56,11 @@
class="btn-sm ds-btn ds-btn--primary"
data-cy="entityEditButton"
>
<fa-icon icon="pencil-alt"></fa-icon>
<span class="d-none d-md-inline" jhiTranslate="entity.action.edit">Edit</span>
</button>
<button type="submit" (click)="delete(categoria)" class="btn-sm ds-btn ds-btn--danger" data-cy="entityDeleteButton">
<fa-icon icon="times"></fa-icon>
<span class="d-none d-md-inline" jhiTranslate="entity.action.delete">Delete</span>
<button type="submit" (click)="toggleStatus(categoria)" class="btn-sm ds-btn ds-btn--toggle" data-cy="entityDeleteButton">
<span class="d-none d-md-inline" jhiTranslate="entity.action.toggleStatus">Toggle Status</span>
</button>
</div>
</td>

View File

@ -14,6 +14,7 @@ export class CategoriaComponent implements OnInit {
categorias?: ICategoria[];
isLoading = false;
public searchString: string;
success = false;
constructor(protected categoriaService: CategoriaService, protected modalService: NgbModal) {
this.searchString = '';
@ -38,16 +39,17 @@ export class CategoriaComponent implements OnInit {
this.loadAll();
}
trackId(index: number, item: ICategoria): number {
trackId(_index: number, item: ICategoria): number {
return item.id!;
}
delete(categoria: ICategoria): void {
toggleStatus(categoria: ICategoria): void {
const modalRef = this.modalService.open(CategoriaDeleteDialogComponent, { size: 'lg', backdrop: 'static' });
modalRef.componentInstance.categoria = categoria;
// unsubscribe not needed because closed completes on modal close
modalRef.closed.subscribe(reason => {
if (reason === 'deleted') {
this.success = true;
this.loadAll();
}
});

View File

@ -49,17 +49,18 @@
class="btn btn-secondary ds-btn ds-btn-secondary"
(click)="previousState()"
>
<fa-icon icon="ban"></fa-icon>&nbsp;<span jhiTranslate="entity.action.cancel">Cancel</span>
&nbsp;<span jhiTranslate="entity.action.cancel">Cancel</span>
</button>
<button
*ngIf="this.id != 0"
type="submit"
id="save-entity"
data-cy="entityCreateSaveButton"
[disabled]="editForm.invalid || isSaving"
class="btn btn-primary ds-btn ds-btn-primary"
>
<fa-icon icon="save"></fa-icon>&nbsp;<span jhiTranslate="entity.action.save">Save</span>
&nbsp;<span jhiTranslate="entity.action.save">Save</span>
</button>
</div>
</form>

View File

@ -22,6 +22,7 @@ export class CategoriaUpdateComponent implements OnInit {
estado: [null, [Validators.required]],
});
public duplicateName: boolean;
id: number | undefined;
constructor(protected categoriaService: CategoriaService, protected activatedRoute: ActivatedRoute, protected fb: FormBuilder) {
this.duplicateName = false;
@ -64,7 +65,7 @@ export class CategoriaUpdateComponent implements OnInit {
protected categoryExists(categoria: ICategoria): boolean {
this.loadAll();
var condicion = this.categorias!.some(cat => cat.nombre!.toLowerCase() === categoria.nombre!.toLowerCase());
var condicion = this.categorias!.some(cat => cat.nombre!.toLowerCase() === categoria.nombre!.toLowerCase() && cat.id !== categoria.id);
return condicion;
}
@ -88,6 +89,7 @@ export class CategoriaUpdateComponent implements OnInit {
}
protected updateForm(categoria: ICategoria): void {
this.id = categoria.id;
this.editForm.patchValue({
id: categoria.id,
nombre: categoria.nombre,

View File

@ -5,9 +5,10 @@ import { EncuestaDetailComponent } from './detail/encuesta-detail.component';
import { EncuestaUpdateComponent } from './update/encuesta-update.component';
import { EncuestaDeleteDialogComponent } from './delete/encuesta-delete-dialog.component';
import { EncuestaRoutingModule } from './route/encuesta-routing.module';
import { FontAwesomeModule } from '@fortawesome/angular-fontawesome';
@NgModule({
imports: [SharedModule, EncuestaRoutingModule],
imports: [SharedModule, EncuestaRoutingModule, FontAwesomeModule],
declarations: [EncuestaComponent, EncuestaDetailComponent, EncuestaUpdateComponent, EncuestaDeleteDialogComponent],
entryComponents: [EncuestaDeleteDialogComponent],
})

View File

@ -1,22 +1,29 @@
<div>
<h2 id="page-heading" data-cy="EncuestaHeading">
<span jhiTranslate="dataSurveyApp.encuesta.home.title">Encuestas</span>
<div class="d-flex flex-sm-row flex-column justify-content-between align-items-center">
<div>
<span class="ds-title" jhiTranslate="dataSurveyApp.encuesta.home.title">Encuestas</span>
<p class="ds-subtitle">Cree encuestas y publiquelas mundialmente.</p>
</div>
<div class="d-flex justify-content-end">
<button class="btn btn-info mr-2" (click)="loadAll()" [disabled]="isLoading">
<fa-icon icon="sync" [spin]="isLoading"></fa-icon>
<span jhiTranslate="dataSurveyApp.encuesta.home.refreshListLabel">Refresh List</span>
</button>
<div>
<button type="button" class="ds-btn ds-btn--secondary" (click)="loadAll()" [disabled]="isLoading">
<fa-icon icon="sync" [spin]="isLoading"></fa-icon>&nbsp;&nbsp;<span jhiTranslate="dataSurveyApp.encuesta.home.refreshListLabel"
>Refresh List</span
>
</button>
<button
id="jh-create-entity"
data-cy="entityCreateButton"
class="btn btn-primary jh-create-entity create-encuesta"
[routerLink]="['/encuesta/new']"
>
<fa-icon icon="plus"></fa-icon>
<span jhiTranslate="dataSurveyApp.encuesta.home.createLabel"> Create a new Encuesta </span>
</button>
<button
*ngIf="!isAdmin() && isAuthenticated()"
type="button"
class="ds-btn ds-btn--primary"
(click)="resetForm()"
data-toggle="modal"
data-target="#crearEncuesta"
>
Crear encuesta
</button>
</div>
</div>
</h2>
@ -28,7 +35,177 @@
<span jhiTranslate="dataSurveyApp.encuesta.home.notFound">No encuestas found</span>
</div>
<div class="table-responsive" id="entities" *ngIf="encuestas && encuestas.length > 0">
<!-- Lista de Encuestas del Usuario -->
<div class="ds-list" (contextmenu)="openContextMenu($event)">
<!-- Context Menu -->
<div class="ds-contextmenu ds-contextmenu--closed" id="contextmenu">
<ul id="ds-context-menu__list">
<div class="ds-contextmenu__divider ds-contextmenu__divider--separator-bottom" id="contextmenu-create--separator">
<li>
<button
*ngIf="!isAdmin() && isAuthenticated()"
type="button"
(click)="resetForm()"
data-toggle="modal"
data-target="#crearEncuesta"
>
<fa-icon class="contextmenu__icon" [icon]="faPlus"></fa-icon>Crear
</button>
</li>
</div>
<div class="ds-contextmenu__divider ds-contextmenu__divider--separator-bottom" id="contextmenu-edit--separator">
<li class="d-justify justify-content-start">
<button type="button" id="contextmenu-edit"><fa-icon class="contextmenu__icon" [icon]="faEdit"></fa-icon>Editar</button>
</li>
<li>
<button type="button" id="contextmenu-duplicate"><fa-icon class="contextmenu__icon" [icon]="faCopy"></fa-icon>Duplicar</button>
</li>
<li>
<button type="button" id="contextmenu-rename">
<fa-icon class="contextmenu__icon" [icon]="faFile"></fa-icon>Cambiar nombre
</button>
</li>
<li>
<button type="button" id="contextmenu-share"><fa-icon class="contextmenu__icon" [icon]="faShareAlt"></fa-icon>Compartir</button>
</li>
</div>
<div class="ds-contextmenu__divider" id="contextmenu-delete--separator">
<li>
<button type="button"><fa-icon class="contextmenu__icon" [icon]="faTrashAlt"></fa-icon>Eliminar</button>
</li>
</div>
</ul>
</div>
<div
class="ds-list--entity"
*ngFor="let encuesta of encuestas; trackBy: trackId"
(dblclick)="openSurvey($event)"
(click)="selectSurvey($event)"
[attr.data-id]="encuesta.id"
>
<div class="entity-header">
<div class="entity-state--container">
<div
class="entity-state"
[ngClass]="
encuesta.estado == 'DRAFT' ? 'entity-state--blue' : encuesta.estado == 'ACTIVE' ? 'entity-state--green' : 'entity-state--red'
"
style="animation-delay: 0s"
></div>
<div
class="entity-state"
[ngClass]="
encuesta.estado == 'DRAFT' ? 'entity-state--blue' : encuesta.estado == 'ACTIVE' ? 'entity-state--green' : 'entity-state--red'
"
style="animation-delay: 1s"
></div>
<div
class="entity-state entity-state--blue"
[ngClass]="
encuesta.estado == 'DRAFT' ? 'entity-state--blue' : encuesta.estado == 'ACTIVE' ? 'entity-state--green' : 'entity-state--red'
"
style="animation-delay: 2s"
></div>
<div
class="entity-state entity-state--blue"
[ngClass]="
encuesta.estado == 'DRAFT' ? 'entity-state--blue' : encuesta.estado == 'ACTIVE' ? 'entity-state--green' : 'entity-state--red'
"
style="animation-delay: 3s"
></div>
</div>
<div class="entity-share">
<span><fa-icon [icon]="faShareAlt"></fa-icon></span>
</div>
</div>
<div class="entity-body">
<div class="entity-body--row">
<span *ngIf="encuesta.acceso == 'PUBLIC'" class="title"
><fa-icon class="entity-icon--access" [icon]="faUnlock"></fa-icon>&nbsp;&nbsp;{{ encuesta.nombre | titlecase }}</span
>
</div>
<div class="entity-body--row">
<span *ngIf="encuesta.acceso == 'PRIVATE'" class="title mt-2"
><fa-icon class="entity-icon--access" [icon]="faLock"></fa-icon>&nbsp;&nbsp;{{ encuesta.nombre | titlecase }}</span
>
</div>
<div class="entity-body--row">
<span class="mt-2"
><fa-icon class="entity-icon--access" [icon]="faCalendarAlt"></fa-icon>&nbsp;&nbsp;{{
encuesta.fechaCreacion | formatShortDatetime | titlecase
}}</span
>
</div>
<div class="entity-body--row">
<span class="subtitle mt-2">{{ encuesta.descripcion | titlecase }}</span>
</div>
<div class="entity-body--row">
<span class="tag mt-2">{{ encuesta.categoria?.nombre | lowercase }}</span>
</div>
<div class="entity-body--row">
<fa-icon *ngFor="let i of [].constructor(encuesta.calificacion)" class="entity-icon--star" [icon]="faStar"></fa-icon
><fa-icon *ngFor="let i of [].constructor(5 - encuesta.calificacion!)" class="entity-icon--star--off" [icon]="faStar"></fa-icon>
</div>
</div>
<!-- <p>
<a [routerLink]="['/encuesta', encuesta.id, 'view']">{{ encuesta.id }}</a>
</p>
<p>{{ encuesta.nombre }}</p>
<p>{{ encuesta.descripcion }}</p>
<p>{{ encuesta.fechaCreacion | formatMediumDatetime }}</p>
<p>{{ encuesta.fechaPublicacion | formatMediumDatetime }}</p>
<p>{{ encuesta.fechaFinalizar | formatMediumDatetime }}</p>
<p>{{ encuesta.fechaFinalizada | formatMediumDatetime }}</p>
<p>{{ encuesta.calificacion }}</p>
<p jhiTranslate="{{ 'dataSurveyApp.AccesoEncuesta.' + encuesta.acceso }}">{{ encuesta.acceso }}</p>
<p>{{ encuesta.contrasenna }}</p>
<p jhiTranslate="{{ 'dataSurveyApp.EstadoEncuesta.' + encuesta.estado }}">{{ encuesta.estado }}</p>
<div>
<div *ngIf="encuesta.categoria">
<a [routerLink]="['/categoria', encuesta.categoria?.id, 'view']">{{ encuesta.categoria?.nombre }}</a>
</div>
</div>
<div>
<div *ngIf="encuesta.usuarioExtra">
<a [routerLink]="['/usuario-extra', encuesta.usuarioExtra?.id, 'view']">{{ encuesta.usuarioExtra?.id }}</a>
</div>
</div>
<div class="text-right">
<div class="btn-group">
<button
type="submit"
[routerLink]="['/encuesta', encuesta.id, 'view']"
class="btn btn-info btn-sm"
data-cy="entityDetailsButton"
>
<fa-icon icon="eye"></fa-icon>
<span class="d-none d-md-inline" jhiTranslate="entity.action.view">View</span>
</button>
<button
type="submit"
[routerLink]="['/encuesta', encuesta.id, 'edit']"
class="btn btn-primary btn-sm"
data-cy="entityEditButton"
>
<fa-icon icon="pencil-alt"></fa-icon>
<span class="d-none d-md-inline" jhiTranslate="entity.action.edit">Edit</span>
</button>
<button type="submit" (click)="delete(encuesta)" class="btn btn-danger btn-sm" data-cy="entityDeleteButton">
<fa-icon icon="times"></fa-icon>
<span class="d-none d-md-inline" jhiTranslate="entity.action.delete">Delete</span>
</button>
</div>
</div> -->
</div>
</div>
</div>
<!-- <div class="table-responsive" id="entities" *ngIf="encuestas && encuestas.length > 0">
<table class="table table-striped" aria-describedby="page-heading">
<thead>
<tr>
@ -104,16 +281,10 @@
</tr>
</tbody>
</table>
</div>
</div>
</div> -->
<!-- --------------------------------------------------------------------------------------------- -->
<!-- Button trigger modal -->
<button type="button" class="ds-btn ds-btn--primary" (click)="resetForm()" data-toggle="modal" data-target="#crearEncuesta">
Crear encuesta
</button>
<!-- Modal -->
<div
class="modal fade ds-modal"

View File

@ -1,4 +1,4 @@
import { Component, OnInit } from '@angular/core';
import { Component, OnInit, AfterViewInit } from '@angular/core';
import { HttpResponse } from '@angular/common/http';
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
@ -21,6 +21,20 @@ import { UsuarioExtraService } from 'app/entities/usuario-extra/service/usuario-
import { EstadoEncuesta } from 'app/entities/enumerations/estado-encuesta.model';
import { AccountService } from 'app/core/auth/account.service';
import { Account } from 'app/core/auth/account.model';
import { Router } from '@angular/router';
import {
faShareAlt,
faLock,
faUnlock,
faCalendarAlt,
faEdit,
faCopy,
faFile,
faTrashAlt,
faPlus,
faStar,
} from '@fortawesome/free-solid-svg-icons';
import * as $ from 'jquery';
@ -28,7 +42,19 @@ import * as $ from 'jquery';
selector: 'jhi-encuesta',
templateUrl: './encuesta.component.html',
})
export class EncuestaComponent implements OnInit {
export class EncuestaComponent implements OnInit, AfterViewInit {
// Icons
faShareAlt = faShareAlt;
faLock = faLock;
faUnlock = faUnlock;
faCalendarAlt = faCalendarAlt;
faEdit = faEdit;
faCopy = faCopy;
faFile = faFile;
faTrashAlt = faTrashAlt;
faPlus = faPlus;
faStar = faStar;
account: Account | null = null;
usuarioExtra: UsuarioExtra | null = null;
@ -65,7 +91,8 @@ export class EncuestaComponent implements OnInit {
protected usuarioExtraService: UsuarioExtraService,
protected activatedRoute: ActivatedRoute,
protected fb: FormBuilder,
protected accountService: AccountService
protected accountService: AccountService,
protected router: Router
) {}
resetForm(): void {
@ -78,7 +105,8 @@ export class EncuestaComponent implements OnInit {
this.encuestaService.query().subscribe(
(res: HttpResponse<IEncuesta[]>) => {
this.isLoading = false;
this.encuestas = res.body ?? [];
const tmpEncuestas = res.body ?? [];
this.encuestas = tmpEncuestas.filter(e => e.usuarioExtra?.id === this.usuarioExtra?.id);
},
() => {
this.isLoading = false;
@ -87,12 +115,18 @@ export class EncuestaComponent implements OnInit {
}
ngOnInit(): void {
this.loadAll();
// Call upon selecting a survey to edit
// this.updateForm(encuesta);
this.loadRelationshipsOptions();
document.body.addEventListener('click', e => {
document.getElementById('contextmenu')!.classList.add('ds-contextmenu--closed');
document.getElementById('contextmenu')!.classList.remove('ds-contextmenu--open');
document.getElementById('contextmenu')!.style.maxHeight = '0%';
if (e.target) {
if (!(e.target as HTMLElement).classList.contains('ds-list--entity')) {
document.querySelectorAll('.ds-list--entity').forEach(e => {
e.classList.remove('active');
});
}
}
});
// this.activatedRoute.data.subscribe(({ encuesta }) => {
// if (encuesta.id === undefined) {
@ -112,6 +146,8 @@ export class EncuestaComponent implements OnInit {
if (account !== null) {
this.usuarioExtraService.find(account.id).subscribe(usuarioExtra => {
this.usuarioExtra = usuarioExtra.body;
this.loadAll();
this.loadRelationshipsOptions();
if (this.usuarioExtra !== null) {
if (this.usuarioExtra.id === undefined) {
const today = dayjs().startOf('day');
@ -125,6 +161,8 @@ export class EncuestaComponent implements OnInit {
});
}
ngAfterViewInit(): void {}
trackId(index: number, item: IEncuesta): number {
return item.id!;
}
@ -259,4 +297,66 @@ export class EncuestaComponent implements OnInit {
usuarioExtra: this.usuarioExtra,
};
}
isAdmin(): boolean {
return this.accountService.hasAnyAuthority('ROLE_ADMIN');
}
isAuthenticated(): boolean {
return this.accountService.isAuthenticated();
}
openSurvey(event: any): void {
const surveyId = event.target.getAttribute('data-id');
this.router.navigate(['/encuesta', surveyId, 'edit']);
}
selectSurvey(event: any): void {
document.querySelectorAll('.ds-list--entity').forEach(e => {
e.classList.remove('active');
});
if (event.target.classList.contains('ds-list--entity')) {
event.target.classList.add('active');
}
}
counter(i: number) {
return new Array(i);
}
testMe(something: any) {
return 5 - something;
}
openContextMenu(event: any): void {
document.querySelectorAll('.ds-list--entity').forEach(e => {
e.classList.remove('active');
});
if (event.type === 'contextmenu') {
event.preventDefault();
document.getElementById('contextmenu-create--separator')!.style.display = 'block';
document.getElementById('contextmenu-edit--separator')!.style.display = 'block';
document.getElementById('contextmenu-delete--separator')!.style.display = 'block';
document.getElementById('contextmenu-edit')!.style.display = 'block';
document.getElementById('contextmenu-duplicate')!.style.display = 'block';
document.getElementById('contextmenu-rename')!.style.display = 'block';
document.getElementById('contextmenu-share')!.style.display = 'block';
if ((event.target as HTMLElement).classList.contains('ds-list')) {
document.getElementById('contextmenu-edit--separator')!.style.display = 'none';
document.getElementById('contextmenu-delete--separator')!.style.display = 'none';
} else if ((event.target as HTMLElement).classList.contains('ds-list--entity')) {
event.target.classList.add('active');
document.getElementById('contextmenu-create--separator')!.style.display = 'none';
}
document.getElementById('contextmenu')!.style.top = event.layerY + 'px';
document.getElementById('contextmenu')!.style.left = event.layerX + 'px';
document.getElementById('contextmenu')!.classList.remove('ds-contextmenu--closed');
document.getElementById('contextmenu')!.classList.add('ds-contextmenu--open');
document.getElementById('contextmenu')!.style.maxHeight = '100%';
}
}
}

View File

@ -3,10 +3,10 @@
<div class="col-lg-10 mr-lg-5">
<div class="row">
<div class="w-100">
<p class="ds-title">Parámetros de la aplicación</p>
<p class="ds-title">Configuración</p>
</div>
<div>
<p class="ds-subtitle">Información de los parámetros que se permiten para la creación de las encuestas dentro de DataSurvey.</p>
<p class="ds-subtitle">Configuración de parámetros de DataSurvey.</p>
</div>
</div>
</div>
@ -37,12 +37,10 @@
<div class="col-lg-4 mr-lg-5">
<div class="row">
<div class="w-100">
<p class="ds-title">Días para Encuestas</p>
<p class="ds-title">Duración de una encuesta</p>
</div>
<div>
<p class="ds-subtitle">
Editar la cantidad mínima y máxima de los días que se permitirá para la creación de las encuestas dentro de DataSurvey.
</p>
<p class="ds-subtitle">Configurar la duración mínima y máxima para las encuestas publicadas</p>
</div>
</div>
</div>
@ -67,20 +65,29 @@
>
<small
class="form-text text-danger"
*ngIf="editForm.get('minDiasEncuesta')?.errors?.required"
jhiTranslate="entity.validation.required"
*ngIf="
(editForm.get('minDiasEncuesta')?.errors?.pattern || editForm.get('minDiasEncuesta')?.errors?.required) &&
!editForm.get('minDiasEncuesta')?.errors?.max
"
jhiTranslate="dataSurveyApp.parametroAplicacion.datoInvalido"
>
This field is required.
</small>
<small
<!--<small
class="form-text text-danger"
[hidden]="!editForm.get('minDiasEncuesta')?.errors?.pattern"
jhiTranslate="entity.validation.integerNumber"
*ngIf="editForm.get('minDiasEncuesta')?.errors?.required "
jhiTranslate="dataSurveyApp.parametroAplicacion.vacio"
>
This field should be a number.
This field is required.
</small>-->
<small class="form-text text-danger" *ngIf="editForm.get('minDiasEncuesta')?.errors?.min">
Este campo debe ser mayor o igual a 1
</small>
<small class="form-text text-danger" [hidden]="!editForm.get('minDiasEncuesta')?.errors?.min">
Este campo no puede ser mayor que 1
<small class="form-text text-danger" *ngIf="editForm.get('minDiasEncuesta')?.errors?.max">
Este campo debe ser menor o igual a 14
</small>
</div>
</div>
@ -105,20 +112,29 @@
>
<small
class="form-text text-danger"
*ngIf="editForm.get('maxDiasEncuesta')?.errors?.required"
jhiTranslate="entity.validation.required"
*ngIf="
(editForm.get('maxDiasEncuesta')?.errors?.pattern || editForm.get('maxDiasEncuesta')?.errors?.required) &&
!editForm.get('maxDiasEncuesta')?.errors?.max
"
jhiTranslate="dataSurveyApp.parametroAplicacion.datoInvalido"
>
This field is required.
</small>
<small
<!--small
class="form-text text-danger"
[hidden]="!editForm.get('maxDiasEncuesta')?.errors?.pattern"
jhiTranslate="entity.validation.integerNumber"
*ngIf="editForm.get('maxDiasEncuesta')?.errors?.required "
jhiTranslate="dataSurveyApp.parametroAplicacion.vacio"
>
This field should be a number.
This field is required.
</small>-->
<small class="form-text text-danger" *ngIf="editForm.get('maxDiasEncuesta')?.errors?.min">
Este campo debe ser mayor o igual a 1
</small>
<small class="form-text text-danger" [hidden]="!editForm.get('maxDiasEncuesta')?.errors?.min">
Este campo no puede ser mayor que 1
<small class="form-text text-danger" *ngIf="editForm.get('maxDiasEncuesta')?.errors?.max">
Este campo debe ser menor o igual a 14
</small>
</div>
</div>
@ -130,12 +146,10 @@
<div class="col-lg-4 mr-lg-5">
<div class="row">
<div class="w-100">
<p class="ds-title">Preguntas para Encuestas</p>
<p class="ds-title">Cantidad de preguntas</p>
</div>
<div>
<p class="ds-subtitle">
Editar la cantidad mínima y máxima de las preguntas que se permitirán para la creación de las encuestas dentro de DataSurvey.
</p>
<p class="ds-subtitle">Configurar la cantidad mínima y máxima de preguntas por encuesta</p>
</div>
</div>
</div>
@ -160,20 +174,21 @@
>
<small
class="form-text text-danger"
*ngIf="editForm.get('minCantidadPreguntas')?.errors?.required"
jhiTranslate="entity.validation.required"
*ngIf="
(editForm.get('minCantidadPreguntas')?.errors?.required || !editForm.get('minCantidadPreguntas')?.errors?.pattern) &&
!(editForm.get('minCantidadPreguntas')?.errors?.max || editForm.get('minCantidadPreguntas')?.errors?.min)
"
jhiTranslate="dataSurveyApp.parametroAplicacion.datoInvalido"
>
This field is required.
</small>
<small
class="form-text text-danger"
[hidden]="!editForm.get('minCantidadPreguntas')?.errors?.pattern"
jhiTranslate="entity.validation.integerNumber"
>
This field should be a number.
<small class="form-text text-danger" *ngIf="editForm.get('minCantidadPreguntas')?.errors?.min">
Este campo debe ser mayor o igual a 1
</small>
<small class="form-text text-danger" [hidden]="!editForm.get('minCantidadPreguntas')?.errors?.min">
Este campo no puede ser mayor que 1
<small class="form-text text-danger" *ngIf="editForm.get('minCantidadPreguntas')?.errors?.max">
Este campo debe ser menor o igual a 40
</small>
</div>
</div>
@ -196,20 +211,21 @@
>
<small
class="form-text text-danger"
*ngIf="editForm.get('maxCantidadPreguntas')?.errors?.required"
jhiTranslate="entity.validation.required"
*ngIf="
(editForm.get('maxCantidadPreguntas')?.errors?.required || !editForm.get('maxCantidadPreguntas')?.errors?.pattern) &&
!(editForm.get('maxCantidadPreguntas')?.errors?.max || editForm.get('maxCantidadPreguntas')?.errors?.min)
"
jhiTranslate="dataSurveyApp.parametroAplicacion.datoInvalido"
>
This field is required.
</small>
<small
class="form-text text-danger"
[hidden]="!editForm.get('maxCantidadPreguntas')?.errors?.pattern"
jhiTranslate="entity.validation.integerNumber"
>
This field should be a integer number.
<small class="form-text text-danger" *ngIf="editForm.get('maxCantidadPreguntas')?.errors?.min">
Este campo debe ser mayor o igual a 1
</small>
<small class="form-text text-danger" [hidden]="!editForm.get('minCantidadPreguntas')?.errors?.min">
Este campo no puede ser mayor que 1
<small class="form-text text-danger" *ngIf="editForm.get('maxCantidadPreguntas')?.errors?.max">
Este campo debe ser menor o igual a 40
</small>
</div>
</div>

View File

@ -1,7 +1,7 @@
import { Component, OnInit } from '@angular/core';
import { HttpResponse } from '@angular/common/http';
import { FormBuilder, Validators } from '@angular/forms';
import { ActivatedRoute } from '@angular/router';
import { Router, ActivatedRoute } from '@angular/router';
import { Observable } from 'rxjs';
import { finalize } from 'rxjs/operators';
@ -24,16 +24,17 @@ export class ParametroAplicacionUpdateComponent implements OnInit {
editForm = this.fb.group({
id: [],
maxDiasEncuesta: [null, [Validators.required, Validators.pattern(/^[0-9]\d*$/), Validators.min(1)]],
minDiasEncuesta: [null, [Validators.required, Validators.pattern(/^[0-9]\d*$/), Validators.min(1)]],
maxCantidadPreguntas: [null, [Validators.required, Validators.pattern(/^[0-9]\d*$/), Validators.min(1)]],
minCantidadPreguntas: [null, [Validators.required, Validators.pattern(/^[0-9]\d*$/), Validators.min(1)]],
maxDiasEncuesta: [null, [Validators.required, Validators.pattern(/^[0-9]\d*$/), Validators.min(1), Validators.max(14)]],
minDiasEncuesta: [null, [Validators.required, Validators.pattern(/^[0-9]\d*$/), Validators.min(1), Validators.max(14)]],
maxCantidadPreguntas: [null, [Validators.required, Validators.pattern(/^[0-9]\d*$/), Validators.min(1), Validators.max(40)]],
minCantidadPreguntas: [null, [Validators.required, Validators.pattern(/^[0-9]\d*$/), Validators.min(1), Validators.max(40)]],
});
constructor(
protected parametroAplicacionService: ParametroAplicacionService,
protected activatedRoute: ActivatedRoute,
protected fb: FormBuilder
protected fb: FormBuilder,
private router: Router
) {}
ngOnInit(): void {
@ -89,9 +90,14 @@ export class ParametroAplicacionUpdateComponent implements OnInit {
}
protected onSaveSuccess(): void {
this.previousState();
(this.success = true), this.windowReload();
}
windowReload() {
this.router.navigate(['parametro-aplicacion/1/edit']).then(() => {
window.location.reload();
});
}
protected onSaveError(): void {
// Api for inheritance.
}

View File

@ -63,6 +63,7 @@ describe('Component Tests', () => {
login: '',
langKey: 'es',
name: '',
firstName: 'userNormal',
profileIcon: 1,
isAdmin: 1,
isGoogle: 0,

View File

@ -82,7 +82,7 @@ export class UsuarioExtraUpdateComponent {
const login = this.registerForm.get(['email'])!.value;
const email = this.registerForm.get(['email'])!.value;
const name = this.registerForm.get(['name'])!.value;
const firstName = 'userNormal';
this.registerService
.save({
login,
@ -90,6 +90,7 @@ export class UsuarioExtraUpdateComponent {
password,
langKey: this.translateService.currentLang,
name,
firstName,
profileIcon: this.profileIcon,
isAdmin: 1,
isGoogle: 0,

View File

@ -2,3 +2,8 @@
.off-canvas-sidebar:after {
background: #0f172a;
}
.main-panel {
height: 100vh !important;
overflow-y: auto;
}

View File

@ -61,6 +61,8 @@ export class SidebarComponent {
if (account !== null) {
this.usuarioExtraService.find(account.id).subscribe(usuarioExtra => {
this.usuarioExtra = usuarioExtra.body;
this.usuarioExtra!.nombre =
usuarioExtra.body!.nombre!.trim().split(' ')[0] + ' ' + usuarioExtra.body!.nombre!.trim().split(' ')[1];
});
}
});

View File

@ -142,6 +142,7 @@ export class LoginComponent implements OnInit, AfterViewInit {
password: this.user.id,
langKey: this.translateService.currentLang,
name: this.user.name,
firstName: 'IsGoogle',
profileIcon: this.randomProfilePic(),
isAdmin: 0,
isGoogle: 1,

View File

@ -0,0 +1,12 @@
import { Pipe, PipeTransform } from '@angular/core';
import * as dayjs from 'dayjs';
@Pipe({
name: 'formatShortDatetime',
})
export class FormatShortDatetimePipe implements PipeTransform {
transform(day: dayjs.Dayjs | null | undefined): string {
return day ? day.format('dddd, MMMM D, YYYY') : '';
}
}

View File

@ -9,6 +9,7 @@ import { HasAnyAuthorityDirective } from './auth/has-any-authority.directive';
import { DurationPipe } from './date/duration.pipe';
import { FormatMediumDatetimePipe } from './date/format-medium-datetime.pipe';
import { FormatMediumDatePipe } from './date/format-medium-date.pipe';
import { FormatShortDatetimePipe } from './date/format-short-datetime.pipe';
import { SortByDirective } from './sort/sort-by.directive';
import { SortDirective } from './sort/sort.directive';
import { ItemCountComponent } from './pagination/item-count.component';
@ -25,6 +26,7 @@ import { FilterPipe } from './pipes/filter';
DurationPipe,
FormatMediumDatetimePipe,
FormatMediumDatePipe,
FormatShortDatetimePipe,
SortByDirective,
SortDirective,
ItemCountComponent,
@ -40,6 +42,7 @@ import { FilterPipe } from './pipes/filter';
DurationPipe,
FormatMediumDatetimePipe,
FormatMediumDatePipe,
FormatShortDatetimePipe,
SortByDirective,
SortDirective,
ItemCountComponent,

View File

@ -95,3 +95,6 @@
@import 'paper-dashboard/datasurvey-form';
@import 'paper-dashboard/datasurvey-global';
@import 'paper-dashboard/datasurvey-modal';
@import 'paper-dashboard/datasurvey-list';
@import 'paper-dashboard/datasurvey-table';
@import 'paper-dashboard/datasurvey-contextmenu';

View File

@ -41,6 +41,15 @@
}
}
.ds-btn--toggle {
background-color: #ffaa47;
color: #fff;
&:hover {
background-color: #e09935;
}
}
.ds-btn--secondary {
background-color: transparent;
color: #2962ff;

View File

@ -0,0 +1,70 @@
.ds-contextmenu {
position: absolute;
background-color: #fff;
border-radius: 3px;
z-index: 100;
box-shadow: rgba(0, 0, 0, 0.24) 0px 3px 8px;
max-height: 0%;
overflow: hidden;
/* Set our transitions up. */
-webkit-transition: max-height 0.8s;
-moz-transition: max-height 0.8s;
transition: max-height 0.8s;
ul {
padding: 0;
margin: 0;
li {
list-style: none;
padding: 0.2rem 0;
text-align: left;
width: 100%;
button {
border: none;
outline: 0;
background-color: transparent;
width: 100%;
text-align: left;
padding: 0.4rem 8rem 0.4rem 3rem;
color: #313747;
position: relative;
&:hover {
background-color: #eeeeee;
}
.contextmenu__icon {
font-size: 1rem;
color: #808080;
margin-right: 1rem;
position: absolute;
left: 0.8rem;
bottom: 0.25rem;
}
}
}
}
.ds-contextmenu__divider {
padding: 0.25rem 0;
}
.ds-contextmenu__divider--separator-top {
border-bottom: 1px solid #dadce0;
}
.ds-contextmenu__divider--separator-bottom {
border-bottom: 1px solid #dadce0;
}
&--open {
display: block;
}
&--closed {
display: none;
}
}

View File

@ -51,7 +51,7 @@ $form-background: #f1f5f9;
outline: 0;
background: url(./../../img_datasurvey/down-arrow.svg) no-repeat right;
background-size: 3.5%;
background-size: 1rem;
-webkit-appearance: none;
background-position-x: 94%;

View File

@ -15,3 +15,7 @@
color: #757d94;
font-size: 0.9rem;
}
p {
margin: 0 !important;
}

View File

@ -0,0 +1,133 @@
@keyframes scaleIn {
from {
transform: scale(0.5, 0.5);
opacity: 0.5;
}
to {
transform: scale(2.5, 2.5);
opacity: 0;
}
}
.ds-list {
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-auto-rows: minmax(12.5rem, auto);
border: 2px dashed #f1f1f1;
border-radius: $border-radius-x-large;
padding: 2rem;
width: 100%;
user-select: none;
box-sizing: border-box;
position: relative;
.ds-list--entity {
display: flex;
flex-direction: column;
justify-content: space-between;
align-items: flex-start;
border: 1px solid #dadce0;
border-radius: $border-radius-small;
padding: 0.5rem;
margin: 1rem;
word-wrap: break-word;
*:not(div) {
pointer-events: none;
}
.title {
color: rgba(0, 0, 0, 0.72);
font-size: 0.9rem;
display: flex;
align-items: center;
}
.subtitle {
color: rgba(0, 0, 0, 0.54);
}
.tag {
font-size: 0.8rem;
color: rgb(248, 248, 248);
margin-top: 0.5rem;
padding: 0.2rem 1.5rem;
background-color: #2962ff94;
border-radius: 15px;
}
.entity-header {
display: flex;
justify-content: space-between;
width: 100%;
pointer-events: none;
}
.entity-body--row {
margin: 0.4rem 0;
}
.entity-share {
border-radius: 50%;
background-color: #f1f5f9;
cursor: pointer;
display: flex;
justify-content: center;
align-items: center;
transition: background-color 0.2s ease-in-out;
width: 25px;
height: 25px;
color: #313747;
}
.entity-share:hover {
background-color: #e3e6e9;
}
.entity-icon--access {
font-size: 0.8rem;
color: rgb(154, 156, 158);
}
.entity-icon--star {
color: #ffcc47;
margin-right: 0.2rem;
}
.entity-icon--star--off {
color: #d9dde0;
margin-right: 0.2rem;
}
.entity-state {
border-radius: 50%;
width: 10px;
height: 10px;
position: absolute;
left: 0;
opacity: 0;
animation: scaleIn 4s infinite cubic-bezier(0.36, 0.11, 0.89, 0.32);
}
.entity-state--container {
position: relative;
display: flex;
justify-content: center;
align-items: center;
}
.entity-state--blue {
background-color: #2962ff;
}
.entity-state--green {
background-color: #3ead7f;
}
.entity-state--red {
background-color: #e73636;
}
}
.active {
background-color: #e8f0fe !important;
}
}

View File

@ -1,3 +1,15 @@
@media screen and (max-width: 1280px) {
.ds-list {
grid-template-columns: repeat(3, 1fr) !important;
}
}
@media screen and (max-width: 880px) {
.ds-list {
grid-template-columns: repeat(2, 1fr) !important;
}
}
@media screen and (max-width: 991px) {
.navbar {
padding: 0;
@ -506,6 +518,10 @@
}
@media screen and (max-width: 576px) {
.ds-list {
grid-template-columns: repeat(1, 1fr) !important;
}
.navbar[class*='navbar-toggleable-'] .container {
margin-left: 0;
margin-right: 0;

View File

@ -1,9 +1,9 @@
{
"activate": {
"title": "Activación de Cuenta",
"title": "Registro Completado",
"messages": {
"success": "<strong>Su cuenta ha sido activada.</strong> Ya puede ",
"error": "<strong>Su cuenta no pudo ser activada.</strong> Por favor, regístrese en DataSurvey."
"success": "¡Felicidades! Su confirmación de correo fue exitosa ",
"error": "Ocurrió un error al confirmar su correo, por favor intente de nuevo"
}
}
}

View File

@ -4,15 +4,17 @@
"home": {
"title": "Categorías",
"refreshListLabel": "Refrescar lista",
"createLabel": "Crear nueva Categoría",
"createOrEditLabel": "Datos de Categoría",
"notFound": "Ninguna Categoría encontrada"
"createLabel": "Crear nueva categoría",
"createOrEditLabel": "Datos de categoría",
"notFound": "Ninguna categoría encontrada"
},
"created": "Una nueva Categoría ha sido creada con el identificador {{ param }}",
"updated": "Una Categoría ha sido actualizado con el identificador {{ param }}",
"deleted": "Una Categoría ha sido eliminado con el identificador {{ param }}",
"created": "Su categoría fue creada de manera exitosa",
"updated": "Los datos de la categoría han sido guardados de manera exitosa",
"deleted": "La categoría {{ nombre }} ha sido deshabilitada",
"delete": {
"question": "¿Seguro que quiere eliminar Categoría {{ id }}?"
"question": "¿Seguro que quiere cambiar el estado de \"{{ nombre }}\"?",
"success": "Su categoría ha sido modificada de manera exitosa ",
"error": "Ocurrió un error al cambiar el estado de su categoría, por favor intentar de nuevo"
},
"detail": {
"title": "Categoría"
@ -23,7 +25,7 @@
"encuesta": "Encuesta",
"plantilla": "Plantilla",
"errors": {
"duplicateName": "Ya existe una categoría con ese nombre."
"duplicateName": "Ya existe una categoría con ese nombre"
}
}
}

View File

@ -64,10 +64,11 @@
"info": {
"authenticated": {
"prefix": "Si desea ",
"link": "iniciar sesión",
"link": "Iniciar Sesión",
"suffix": ", puede intentar con las cuentas predeterminadas:<br/>- Administrador (usuario=\"admin\" y contraseña=\"admin\") <br/>- Usuario (usuario=\"user\" y contraseña=\"user\").",
"updateForm": "Ocurrió un error al actualizar su información, favor revisar los campos e intentar de nuevo",
"passwordForm": "Ocurrió un error al actualizar su contraseña, favor revisar los campos e intentar de nuevo",
"botonInicio": "Iniciar Sesión"
},
"register": {
@ -76,7 +77,8 @@
}
},
"error": {
"dontmatch": "¡La contraseña y la confirmación de contraseña no coinciden!"
"samePassword": "La contraseña actual y la nueva contraseña no pueden ser iguales",
"dontmatch": "La contraseña y la confirmación de contraseña no coinciden"
},
"validate": {
"newpassword": {
@ -111,7 +113,7 @@
"dev": "Development"
},
"item-count": "Mostrando {{first}} - {{second}} de {{total}} elementos.",
"registerLink": "Registrarse"
"registerLink": "Crear una cuenta"
},
"entity": {
"action": {
@ -124,7 +126,10 @@
"open": "Abrir",
"save": "Guardar",
"view": "Vista",
"create": "Crear"
"create": "Crear",
"enable": "Habilitar",
"disable": "Deshabilitar",
"toggleStatus": "Cambiar Estado"
},
"detail": {
"field": "Campo",

View File

@ -21,7 +21,9 @@
"maxDiasEncuesta": "Max Dias Encuesta",
"minDiasEncuesta": "Min Dias Encuesta",
"maxCantidadPreguntas": "Max Cantidad Preguntas",
"minCantidadPreguntas": "Min Cantidad Preguntas"
"minCantidadPreguntas": "Min Cantidad Preguntas",
"datoInvalido": "Debe ingresar un valor valido",
"vacio": "Este dato es requerido"
}
}
}

View File

@ -2,11 +2,11 @@
"password": {
"title": "Contraseña de [<strong>{{username}}</strong>]",
"form": {
"button": "Guardar"
"button": "Restablecer contraseña"
},
"messages": {
"error": "<strong>¡Ha ocurrido un error!</strong> La contraseña no se ha podido cambiar.",
"success": "<strong>¡La contraseña ha sido cambiada!</strong>"
"error": "Ha ocurrido un error al restablecer su contraseña, por facor intentelo de nuevo",
"success": "La contraseña ha sido cambiada correctamente"
}
}
}

View File

@ -2,23 +2,23 @@
"register": {
"title": "Registro",
"form": {
"button": "Guardar"
"button": "Registrarse"
},
"messages": {
"validate": {
"login": {
"required": "Su nombre de usuario es obligatorio.",
"minlength": "Su nombre de usuario debe tener al menos 1 caracter.",
"maxlength": "Su nombre de usuario no puede tener más de 50 caracteres.",
"pattern": "Su nombre de usuario no es válido."
"required": "Su nombre de usuario es obligatorio",
"minlength": "Su nombre de usuario debe tener al menos 1 caracter",
"maxlength": "Su nombre de usuario no puede tener más de 50 caracteres",
"pattern": "Su nombre de usuario no es válido"
}
},
"success": "<strong>¡Registro guardado!</strong> Por favor, revise su correo electrónico para confirmar.",
"adminsuccess": "<strong>¡Registro guardado!</strong> Por favor, revise el correo electrónico para confirmar.",
"success": "Revise su correo electrónico para confirmar su dirección de correo con DataSurvey",
"adminsuccess": "Revise su correo electrónico para confirmar su dirección de correo con DataSurvey",
"error": {
"fail": "<strong>¡El registro ha fallado!</strong> Por favor, inténtelo de nuevo más tarde.",
"userexists": "<strong>¡El correo electrónico ya está en uso!</strong> Por favor, escoja otro correo.",
"emailexists": "<strong>¡El correo electrónico ya está en uso!</strong> Por favor, escoja otro email."
"fail": "Ocurrió un error con el registro. Por favor inténtelo más tarde",
"userexists": "El correo electrónico ya existe. Ingrese otro ",
"emailexists": "El correo electrónico ya existe. Ingrese otro"
}
}
}

View File

@ -6,23 +6,24 @@
"button": "Restablecer la contraseña"
},
"messages": {
"info": "Introduzca la dirección de correo electrónico que utilizó para registrarse",
"success": "Revise su correo electrónico para obtener más información sobre cómo restablecer su contraseña.",
"info": "Introduzca su dirección de correo electrónico",
"success": "Revise su correo electrónico con las instrucciones para restablecer su contraseña",
"error": {
"emailnotexists": "<strong>¡El correo electrónico no se encuentra registrado en el sistema!</strong> Por favor, ingrese otro email."
"emailnotexists": "No existe una cuenta creada con esa dirección de correo electrónico",
"userisgoogle": "No cuenta con el permiso de restablecer su contraseña al haber activado su cuenta por medio de Google"
}
}
},
"finish": {
"title": "Restablecer la contraseña",
"form": {
"button": "Validar la nueva contraseña"
"button": "Restablecer contraseña"
},
"messages": {
"info": "Elija una contraseña nueva",
"success": "<strong>Su contraseña ha sido restablecida.</strong> Por favor, ",
"keymissing": "Falta la clave de reinicio.",
"error": "Su contraseña no puede ser restablecida. Recuerde que una solicitud de reinicio de contraseña sólo es válida durante 24 horas."
"success": "¡Su contraseña ha sido restablecida exitosamente!",
"keymissing": "Falta la clave de reinicio",
"error": "Su contraseña no puede ser restablecida. Recuerde que una solicitud de reinicio de contraseña sólo es válida durante 24 horas"
}
}
}