#328087 Add ability to change event date vote and unregister from event altogether.

This commit is contained in:
Georgi Prodanov 2017-02-02 19:51:03 +02:00
Родитель 541069d497
Коммит 8055688450
7 изменённых файлов: 114 добавлений и 33 удалений

Просмотреть файл

@ -61,10 +61,7 @@ export class EventDetailsComponent implements OnInit {
this.event = event;
this._page.actionBar.title = event.Name;
this.isPastEvent = this._eventsService.isPastEvent(this.event);
return this._eventsService.getDateChoicesVotes(event.Id);
})
.then((result) => {
this._countByDate = result.countByDate;
return this._updateCountsByDate();
})
.catch(this._onError.bind(this));
@ -86,6 +83,11 @@ export class EventDetailsComponent implements OnInit {
});
}
private _updateCountsByDate() {
return this._eventsService.getDateChoicesVotes(this.event.Id)
.then(result => this._countByDate = result.countByDate);
}
onEdit() {
this._routerExtensions.navigate([`/events/${this.event.Id}/edit`]);
}
@ -95,22 +97,20 @@ export class EventDetailsComponent implements OnInit {
}
register() {
if (this.alreadyRegistered) {
return;
}
let registrationPromise: Promise<any>;
let dateSelectionPromise: Promise<string[]> = null;
if (this.event.EventDate) {
registrationPromise = this._eventsService.registerForEvent(this.event.Id, [this.event.EventDate]);
dateSelectionPromise = Promise.resolve([this.event.EventDate]);
} else {
registrationPromise = this._openPopupAndRegister();
dateSelectionPromise = this._openDateSelectionModal();
}
registrationPromise.then((didRegister) => {
if (didRegister) {
dateSelectionPromise.then(dateChoices => {
if (dateChoices) {
return this._eventsService.registerForEvent(this.event.Id, dateChoices);
} else {
return Promise.resolve(false);
}
return didRegister;
})
.then(didRegister => {
if (didRegister) { // would be false if user closed modal
@ -120,13 +120,43 @@ export class EventDetailsComponent implements OnInit {
closeTimeout: constants.modalsTimeout
};
this._alertsService.showModal(ctx, this._vcRef, AppModalComponent);
this._updateInfoOnRegister();
this._alertsService.showModal(ctx, this._vcRef, AppModalComponent);
}
})
.catch(this._onError.bind(this));
}
changeVote() {
let updatedChoices: string[];
this._openDateSelectionModal(true)
.then(dateChoices => {
if (!dateChoices) {
return Promise.reject(false); // dont show an error, user closed the modal
}
if (dateChoices.length) {
updatedChoices = dateChoices;
return this._regsService.updateChoices(this.event.Id, this._currentUser.Id, dateChoices);
}
})
.then(() => {
// let oldChoices: string[] = this._userRegForThisEvent.Choices;
// oldChoices.forEach(oc => {
// this._countByDate[oc]--;
// });
// updatedChoices.forEach(uc => {
// if (this._countByDate[uc]) {
// this._countByDate[uc] = (this._countByDate[uc] || 0) + 1;
// }
// });
this._updateCountsByDate();
this._userRegForThisEvent.Choices = updatedChoices;
this._alertsService.showSuccess('Date vote updated');
})
.catch(err => err && this._alertsService.showError(err.message));
}
showLocation() {
nsUtils.openUrl(this.event.LocationURL);
}
@ -135,14 +165,6 @@ export class EventDetailsComponent implements OnInit {
this.registeredUsersExpanded = !this.registeredUsersExpanded;
}
collapseExpandedUsers() {
this.registeredUsersExpanded = false;
}
getAllRegisteredUserNames() {
return this.registeredUsers.map(u => u.DisplayName || u.Username).join(', ');
}
onBack() {
this._routerExtensions.navigateByUrl('/events');
}
@ -163,7 +185,27 @@ export class EventDetailsComponent implements OnInit {
this._routerExtensions.navigateByUrl(`/events/${this.event.Id}/participants`);
}
private _openPopupAndRegister() {
canRegister() {
return !this.alreadyRegistered && !this.isPastEvent && this.event.OpenForRegistration && !this.event.RegistrationCompleted;
}
unregister() {
this._alertsService.askConfirmation(`Unregister from ${this.event.Name}?`)
.then(() => this._regsService.getUserRegistrationForEvent(this.event.Id, this._currentUser.Id))
.then(userReg => {
if (!userReg) {
return Promise.reject({ message: 'You are not registered for this event' })
}
this._userRegForThisEvent = userReg;
return this._eventsService.unregisterFromEvent(this.event.Id, this._currentUser.Id);
})
.then(() => this._updateInfoOnUnregister())
.then(() => this._alertsService.showSuccess(`Successfully unregistered from ${this.event.Name}`))
.catch(err => err && this._alertsService.showError(err.message));
}
private _openDateSelectionModal(isChangeVote = false) {
let opts: ModalDialogOptions = {
context: {
availableDates: this.event.EventDateChoices
@ -172,14 +214,21 @@ export class EventDetailsComponent implements OnInit {
viewContainerRef: this._vcRef
};
if (isChangeVote) {
opts.context.title = 'Change date vote';
}
return this._modalService.showModal(EventRegistrationModalComponent, opts)
.then((dateChoices: number[]) => {
let result: string[] = null;
if (dateChoices && dateChoices.length) {
this._dateChoicesMade = [];
dateChoices.forEach(c => this._dateChoicesMade.push(this.event.EventDateChoices[c]));
return this._eventsService.registerForEvent(this.event.Id, this._dateChoicesMade);
} else {
return Promise.resolve(false);
result = this._dateChoicesMade;
}
return Promise.resolve(result);
});
}
@ -194,9 +243,20 @@ export class EventDetailsComponent implements OnInit {
this.registeredUsers.unshift(this._currentUser);
this._userRegForThisEvent = this._userRegForThisEvent || ({ Choices: [] } as EventRegistration);
this._dateChoicesMade.forEach(dc => {
this._countByDate[dc] = this._countByDate[dc] || 0;
this._countByDate[dc]++;
// this._countByDate[dc] = this._countByDate[dc] || 0;
// this._countByDate[dc]++;
this._userRegForThisEvent.Choices.push(dc);
});
this._updateCountsByDate();
}
private _updateInfoOnUnregister() {
this.alreadyRegistered = false;
this.registeredUsers = this.registeredUsers.filter(u => u.Id !== this._currentUser.Id);
// this._userRegForThisEvent.Choices.forEach(userChoice => {
// this._countByDate[userChoice] = Math.max(0, this._countByDate[userChoice] - 1);
// });
this._updateCountsByDate();
this._userRegForThisEvent = null;
}
}

Просмотреть файл

@ -10,13 +10,19 @@
<Label class="button if" text="&#x65;"></Label>
</StackLayout>
</ActionItem>
<ActionItem *ngIf="alreadyRegistered" (tap)="unregister()" ios.position="right">
<StackLayout>
<Label text="X"></Label>
</StackLayout>
</ActionItem>
</ActionBarExtension>
<StackLayout *ngIf="event">
<photo-picker [url]="event.ImageUrl" [type]="'event'" [noImageIcon]="'&#x77;'" [noImageText]="'No image available'"></photo-picker>
<StackLayout class="info-container">
<Label *ngIf="!alreadyRegistered && !isPastEvent && event.OpenForRegistration && !event.RegistrationCompleted" text="Register" (tap)="register()" class="btn btn-primary"></Label>
<Label *ngIf="canRegister()" text="Register" (tap)="register()" class="btn btn-primary"></Label>
<Label *ngIf="alreadyRegistered && !event.EventDate" text="Change Date Vote" (tap)="changeVote()" class="btn btn-primary"></Label>
<StackLayout class="info-wrapper">
<GridLayout columns="auto, auto, *" rows="auto, auto">
@ -63,7 +69,6 @@
<Label class="info-value" [text]="(registeredUsers.length === 1 ? 'is' : 'are') + ' going'"></Label>
</StackLayout>
<Label class="info-value" *ngIf="registeredUsersExpanded" (tap)="collapseExpandedUsers()" [text]="getAllRegisteredUserNames()" [textWrap]="true"></Label>
<Label class="info-value" *ngIf="registeredUsers.length === 0" [text]="'No one has registered for this event.'"></Label>
</StackLayout>
</StackLayout>

Просмотреть файл

@ -12,8 +12,10 @@ import { utilities } from '../../shared';
export class EventRegistrationModalComponent {
availableDates: Array<{ value: Date, isSelected: boolean }>;
dateFormat = utilities.dateFormat;
title: string;
constructor(private _params: ModalDialogParams, private _alertsService: AlertService) {
this.title = this._params.context.title || 'Registration';
this.availableDates = this._params.context.availableDates.map((dateAsString: string) => {
return {
value: new Date(dateAsString),
@ -24,7 +26,7 @@ export class EventRegistrationModalComponent {
onOk() {
if (this._noDateIsSelected()) {
return this._alertsService.showInfo('Selecting at least one date');
return this._alertsService.showError('You need to select at least one date');
}
let selectedDates = this.availableDates.map((d, i) => d.isSelected ? i : null).filter(n => n !== null);

Просмотреть файл

@ -1,4 +1,4 @@
<app-modal (ok)="onOk($event)" (cancel)="onCancel($event)" [title]="'Registration'" [buttons]="{ ok: 'Submit', cancel: 'Maybe later' }">
<app-modal (ok)="onOk($event)" (cancel)="onCancel($event)" [title]="title" [buttons]="{ ok: 'Submit', cancel: 'Maybe later' }">
<StackLayout class="reg-modal">
<ListView [items]="availableDates" separatorColor="transparent">
<template let-option="item" class="form">

Просмотреть файл

@ -43,6 +43,11 @@ export class EventRegistrationsService {
});
}
updateChoices(eventId: string, userId: string, newChoices: string[]) {
let filter = { EventId: eventId, UserId: userId };
return this._data.update({ Choices: newChoices }, filter);
}
create(eventId: string, userId: string, dateChoices: string[]) {
let queryStringParams = {
eventId,
@ -61,4 +66,8 @@ export class EventRegistrationsService {
getForEvent(eventId: string) {
return this._data.get({ EventId: eventId }).then(resp => resp.result);
}
delete(eventId: string, userId: string) {
return this._data.destroy({ EventId: eventId, UserId: userId });
}
}

Просмотреть файл

@ -126,6 +126,10 @@ export class EventsService {
});
}
unregisterFromEvent(eventId: string, userId: string) {
return this._registrationsService.delete(eventId, userId);
}
isPastEvent(event: Event): boolean {
return event.EventDate && new Date(event.EventDate) < new Date();
}

Просмотреть файл

@ -10,6 +10,7 @@ export class Event extends ItemModel {
Image?: string;
ImageUrl?: string;
OpenForRegistration: boolean;
RegistrationCompleted: boolean;
OrganizerId: string;
GroupId: string;
}