Skip to content

Commit

Permalink
Merge pull request #114 from GabrielInTheWorld/motion-poll
Browse files Browse the repository at this point in the history
Updates motion and assignment polls
  • Loading branch information
GabrielInTheWorld committed Mar 16, 2021
2 parents 9d52425 + 7cf36f0 commit 88e620e
Show file tree
Hide file tree
Showing 144 changed files with 2,563 additions and 2,642 deletions.
74 changes: 0 additions & 74 deletions client/src/app/core/actions/assignment-poll-action.ts

This file was deleted.

57 changes: 0 additions & 57 deletions client/src/app/core/actions/motion-poll-action.ts

This file was deleted.

159 changes: 159 additions & 0 deletions client/src/app/core/actions/poll-action.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
import { HasMeetingId } from 'app/shared/models/base/has-meeting-id';
import { Identifiable } from 'app/shared/models/base/identifiable';
import { Decimal, Fqid, Id } from '../definitions/key-types';

export namespace PollAction {
export const CREATE = 'poll.create';
export const UPDATE = 'poll.update';
export const DELETE = 'poll.delete';

export const PUBLISH = 'poll.publish';
export const RESET = 'poll.reset';
export const START = 'poll.start';
export const STOP = 'poll.stop';
export const ANONYMIZE = 'poll.anonymize';
export const VOTE = 'poll.vote';
export const UPDATE_OPTION = 'option.update';

interface UserIdentifiable {
user_id: Id;
}

type YNA = 'Y' | 'N' | 'A';

interface Option {
// Exactly one of text and content_object_id must be given
text?: string;
content_object_id?: Fqid;
}

export interface AnalogOption extends Option {
// Only for type==analog, optional votes can be given
Y?: Decimal; // Y, YN, YNA mode
N?: Decimal; // N, YN mode
A?: Decimal; // YNA mode
}

export interface ElectronicOption extends Option {}

interface AnalogVotesPayload {
votesvalid?: Decimal;
votesinvalid?: Decimal;
votescast?: Decimal;
}

interface AnalogGlobalAmountPayload {
// Only for type==analog, optional votes can be given
amount_global_yes?: Decimal;
amount_global_no?: Decimal;
amount_global_abstain?: Decimal;
}

interface PartialCreatePayload extends HasMeetingId {
// Required
title: string;
type: string;
pollmethod: string;

options: Option[]; // must have at least one entry.

// Optional
content_object_id?: Fqid;
description?: string;
min_votes_amount?: number;
max_votes_amount?: number;
global_yes?: boolean;
global_no?: boolean;
global_abstain?: boolean;
onehundred_percent_base?: string;
majority_method?: string;
}

interface PartialUpdatePayload {
// Optional, every state
title?: string;
description?: string;
onehundred_percent_base?: string;
majority_method?: string;
}

interface PartialUpdateCreatedPollPayload {
// Optional, only if state == created
pollmethod?: string;
min_votes_amount?: number;
max_votes_amount?: number;
allow_multiple_votes_per_candidate?: boolean;
}

interface PartialUpdateAnalogPayload extends AnalogVotesPayload, AnalogGlobalAmountPayload {
// type==analog, every state
}
export interface CreateAnalogPollPayload
extends PartialCreatePayload,
AnalogVotesPayload,
AnalogGlobalAmountPayload {
options: AnalogOption[];

// Only for type==analog
publish_immediately?: boolean;
}

export interface CreateElectronicPollPayload extends PartialCreatePayload {
options: ElectronicOption[];
// Only for non analog types
entitled_group_ids?: Id[];
}

export interface UpdateAnalogPollPayload
extends Identifiable,
PartialUpdatePayload,
PartialUpdateCreatedPollPayload,
PartialUpdateAnalogPayload {
// Only for type==analog
publish_immediately?: boolean;
}

export interface UpdateElectronicPollPayload
extends Identifiable,
PartialUpdatePayload,
PartialUpdateCreatedPollPayload {
// Optional, only if state == created, only for non analog types
entitled_group_ids: Id[];
}

export interface UpdateOtherStateAnalogPollPayload
extends Identifiable,
PartialUpdatePayload,
PartialUpdateAnalogPayload {
publish_immediately?: boolean;
}

export interface DeletePollPayload extends Identifiable {}

export interface ResetPollPayload extends Identifiable {}
export interface StartPollPayload extends Identifiable {}
export interface StopPollPayload extends Identifiable {}
export interface PublishPollPayload extends Identifiable {}
export interface AnonymizePollPayload extends Identifiable {}

/**
* Only for non-analog polls
*/
export interface YNVotePayload extends Identifiable, UserIdentifiable {
value: { [option_id: number]: number } | YNA;
}

/**
* Only for non-analog polls
*/
export interface YNAVotePayload extends Identifiable, UserIdentifiable {
value: { [option_id: number]: YNA } | YNA;
}

export interface OptionUpdatePayload extends Identifiable {
Y?: number;
N?: number;
A?: number;
publish_immediately?: boolean;
}
}
6 changes: 6 additions & 0 deletions client/src/app/core/core-services/active-meeting.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,12 @@ export class ActiveMeetingService {
{ idField: 'preview_projection_ids', follow: [{ idField: 'content_object_id' }] }
// {idField: 'used_as_default_$_in_meeting_id'} // TODO
]
},
{
// needed for the voting-banner
idField: 'poll_ids',
fieldset: 'list',
follow: [{ idField: 'content_object_id' }]
}
],
fieldset: 'settings',
Expand Down
2 changes: 2 additions & 0 deletions client/src/app/core/core-services/app-load.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { HistoryAppConfig } from 'app/site/history/history.config';
import { MediafileAppConfig } from 'app/site/mediafiles/mediafile.config';
import { SettingsAppConfig } from 'app/site/meeting-settings/meeting-settings.config';
import { MotionsAppConfig } from 'app/site/motions/motions.config';
import { PollsAppConfig } from 'app/site/polls/polls.config';
import { ProjectorAppConfig } from 'app/site/projector/projector.config';
import { TagAppConfig } from 'app/site/tags/tag.config';
import { TopicsAppConfig } from 'app/site/topics/topics.config';
Expand All @@ -32,6 +33,7 @@ const appConfigs: AppConfig[] = [
AgendaAppConfig,
AssignmentsAppConfig,
MotionsAppConfig,
PollsAppConfig,
MediafileAppConfig,
TagAppConfig,
UsersAppConfig,
Expand Down
9 changes: 7 additions & 2 deletions client/src/app/core/core-services/auth.service.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Injectable } from '@angular/core';
import { EventEmitter, Injectable } from '@angular/core';
import { Router } from '@angular/router';

import { environment } from 'environments/environment';
Expand Down Expand Up @@ -48,6 +48,11 @@ export class AuthService {
return this.authTokenSubject.getValue();
}

/**
* "Pings" every time when a user logs out.
*/
public readonly onLogout = new EventEmitter<void>();

public constructor(
private http: HttpService,
private lifecycleService: LifecycleService,
Expand Down Expand Up @@ -101,7 +106,7 @@ export class AuthService {
if (response.success) {
this.authTokenService.setRawAccessToken(null);
}
this.router.navigate(['/']);
this.onLogout.emit();
this.lifecycleService.bootup();
}

Expand Down
5 changes: 5 additions & 0 deletions client/src/app/core/core-services/key-transforms.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,8 @@ export function collectionIdFieldFromFqfield(fqfield: Fqfield): [Collection, Id,
export function collectionFromFqid(fqid: Fqid): Collection {
return collectionIdFromFqid(fqid)[0];
}

// E.g. (group_$_ids, 4) -> group_$4_ids
export function fillTemplateValueInTemplateField(field: Field, value: string): Field {
return field.replace('$', '$' + value);
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
} from './autoupdate.service';
import { CollectionMapperService } from './collection-mapper.service';
import { Deferred } from '../promises/deferred';
import { fillTemplateValueInTemplateField } from './key-transforms';
import { Collection, Field, Id } from '../definitions/key-types';
import { OnAfterAppsLoaded } from '../definitions/on-after-apps-loaded';
import { RelationManagerService } from './relation-manager.service';
Expand Down Expand Up @@ -166,16 +167,11 @@ export class ModelRequestBuilderService implements OnAfterAppsLoaded {
};
} else {
// Specific structured field
fields[this.fillTemplateValueInTempalteField(f.templateIdField, f.templateValue)] = null;
fields[fillTemplateValueInTemplateField(f.templateIdField, f.templateValue)] = null;
}
}
}

// E.g. (group_$_ids, 4) -> group_$4_ids
private fillTemplateValueInTempalteField(field: Field, value: string): Field {
return field.replace('$', '$' + value);
}

private addFollowedRelations(collection: Collection, followList: FollowList, fields: Fields): void {
for (const entry of followList) {
let follow: Follow;
Expand All @@ -199,7 +195,7 @@ export class ModelRequestBuilderService implements OnAfterAppsLoaded {
effectiveIdField = queryIdField = follow.idField;
} else {
queryIdField = follow.idField.templateIdField;
effectiveIdField = this.fillTemplateValueInTempalteField(queryIdField, follow.idField.templateValue);
effectiveIdField = fillTemplateValueInTemplateField(queryIdField, follow.idField.templateValue);
}
const isSpecificStructuredField = queryIdField !== effectiveIdField;

Expand Down
Loading

0 comments on commit 88e620e

Please sign in to comment.