diff --git a/client/src/app/gateways/repositories/motions/motion-repository.service/motion-repository.service.ts b/client/src/app/gateways/repositories/motions/motion-repository.service/motion-repository.service.ts index e932e63fd3..bad793de02 100644 --- a/client/src/app/gateways/repositories/motions/motion-repository.service/motion-repository.service.ts +++ b/client/src/app/gateways/repositories/motions/motion-repository.service/motion-repository.service.ts @@ -187,7 +187,12 @@ export class MotionRepositoryService extends BaseAgendaItemAndListOfSpeakersCont public createTextBased( partialMotion: Partial< - Motion & { workflow_id: Id; attachment_mediafile_ids?: Id[]; supporter_meeting_user_ids?: Id[] } + Motion & { + workflow_id: Id; + attachment_mediafile_ids?: Id[]; + supporter_meeting_user_ids?: Id[]; + submitter_meeting_user_ids: Id[]; + } > ): Action { const payload = { @@ -196,7 +201,7 @@ export class MotionRepositoryService extends BaseAgendaItemAndListOfSpeakersCont title: partialMotion.title, text: partialMotion.text, origin_id: partialMotion.origin_id, - submitter_ids: partialMotion.submitter_ids, + submitter_meeting_user_ids: partialMotion.submitter_meeting_user_ids, workflow_id: partialMotion.workflow_id, category_id: partialMotion.category_id, attachment_mediafile_ids: partialMotion.attachment_mediafile_ids, @@ -212,7 +217,12 @@ export class MotionRepositoryService extends BaseAgendaItemAndListOfSpeakersCont public createParagraphBased( partialMotion: Partial< - Motion & { workflow_id: Id; attachment_mediafile_ids?: Id[]; supporter_meeting_user_ids?: Id[] } + Motion & { + workflow_id: Id; + attachment_mediafile_ids?: Id[]; + supporter_meeting_user_ids?: Id[]; + submitter_meeting_user_ids: Id[]; + } > ): Action { const payload = { @@ -220,7 +230,7 @@ export class MotionRepositoryService extends BaseAgendaItemAndListOfSpeakersCont lead_motion_id: partialMotion.lead_motion_id, title: partialMotion.title, origin_id: partialMotion.origin_id, - submitter_ids: partialMotion.submitter_ids === null ? [] : partialMotion.submitter_ids, + submitter_meeting_user_ids: partialMotion.submitter_meeting_user_ids, workflow_id: partialMotion.workflow_id, category_id: partialMotion.category_id, attachment_mediafile_ids: @@ -320,7 +330,7 @@ export class MotionRepositoryService extends BaseAgendaItemAndListOfSpeakersCont title: partialMotion.title, text: partialMotion.text, origin_id: partialMotion.origin_id, - submitter_ids: partialMotion.submitter_ids, + submitter_meeting_user_ids: partialMotion.submitter_meeting_user_ids, additional_submitter: partialMotion.additional_submitter, workflow_id: partialMotion.workflow_id, category_id: partialMotion.category_id, diff --git a/client/src/app/site/modules/global-headbar/components/account-button/account-button.component.html b/client/src/app/site/modules/global-headbar/components/account-button/account-button.component.html index e2a0c9e77a..378314685a 100644 --- a/client/src/app/site/modules/global-headbar/components/account-button/account-button.component.html +++ b/client/src/app/site/modules/global-headbar/components/account-button/account-button.component.html @@ -81,6 +81,11 @@ done {{ 'Present' | translate }} + } @else if (!isinMeeting) { +
+ clear + {{ 'Not part of meeting' | translate }} +
} @else {
clear diff --git a/client/src/app/site/modules/global-headbar/components/account-button/account-button.component.ts b/client/src/app/site/modules/global-headbar/components/account-button/account-button.component.ts index 7e254ed001..47e1c97ae9 100644 --- a/client/src/app/site/modules/global-headbar/components/account-button/account-button.component.ts +++ b/client/src/app/site/modules/global-headbar/components/account-button/account-button.component.ts @@ -44,14 +44,16 @@ export class AccountButtonComponent extends BaseUiComponent implements OnInit { private _langTriggerSubscription: Subscription; + public get isinMeeting(): boolean { + return this.hasActiveMeeting && this.operator.isInMeeting(this.activeMeetingId) && !this.operator.isAnonymous; + } + public get isPresent(): boolean { - return this.hasActiveMeeting && this.operator.isInMeeting(this.activeMeetingId) && !this.operator.isAnonymous - ? this.user.isPresentInMeeting() - : false; + return this.isinMeeting && this.user.isPresentInMeeting(); } public get isAllowedSelfSetPresent(): boolean { - return this._isAllowedSelfSetPresent && this.operator.isInMeeting(this.activeMeetingId); + return this.isinMeeting && this._isAllowedSelfSetPresent; } public get hasActiveMeeting(): boolean { diff --git a/client/src/app/site/pages/meetings/modules/poll/components/base-poll-vote/base-poll-vote.component.html b/client/src/app/site/pages/meetings/modules/poll/components/base-poll-vote/base-poll-vote.component.html index 41c7f4c09a..7631b5c9ff 100644 --- a/client/src/app/site/pages/meetings/modules/poll/components/base-poll-vote/base-poll-vote.component.html +++ b/client/src/app/site/pages/meetings/modules/poll/components/base-poll-vote/base-poll-vote.component.html @@ -1,6 +1,10 @@ @if (poll && isReady) { - @if (isUserPresent) { + @if (!isUserInMeeting) { +
+ {{ 'You are not part of the meeting' | translate }} +
+ } @else if (isUserPresent) { } @else {
diff --git a/client/src/app/site/pages/meetings/modules/poll/components/base-poll-vote/base-poll-vote.component.ts b/client/src/app/site/pages/meetings/modules/poll/components/base-poll-vote/base-poll-vote.component.ts index 8cae3ca506..a4241c3f3e 100644 --- a/client/src/app/site/pages/meetings/modules/poll/components/base-poll-vote/base-poll-vote.component.ts +++ b/client/src/app/site/pages/meetings/modules/poll/components/base-poll-vote/base-poll-vote.component.ts @@ -75,6 +75,10 @@ export abstract class BasePollVoteComponent e return this.user?.isPresentInMeeting(); } + public get isUserInMeeting(): boolean { + return this.user?.isInActiveMeeting; + } + public get isMobile(): boolean { return this.viewport.isMobile; } diff --git a/client/src/app/site/pages/meetings/pages/assignments/pages/assignment-detail/components/assignment-detail/assignment-detail.component.ts b/client/src/app/site/pages/meetings/pages/assignments/pages/assignment-detail/components/assignment-detail/assignment-detail.component.ts index 031105702b..47c9551725 100644 --- a/client/src/app/site/pages/meetings/pages/assignments/pages/assignment-detail/components/assignment-detail/assignment-detail.component.ts +++ b/client/src/app/site/pages/meetings/pages/assignments/pages/assignment-detail/components/assignment-detail/assignment-detail.component.ts @@ -1,5 +1,6 @@ import { Component, OnDestroy } from '@angular/core'; import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms'; +import { MatSnackBar } from '@angular/material/snack-bar'; import { TranslateService } from '@ngx-translate/core'; import { BehaviorSubject, Subscription } from 'rxjs'; import { Id } from 'src/app/domain/definitions/key-types'; @@ -162,7 +163,8 @@ export class AssignmentDetailComponent extends BaseMeetingComponent implements O private pollDialog: AssignmentPollDialogService, private assignmentPollService: AssignmentPollService, private pollController: PollControllerService, - private userRepo: UserControllerService + private userRepo: UserControllerService, + private snackBar: MatSnackBar ) { super(); this.assignmentForm = formBuilder.group({ @@ -355,7 +357,12 @@ export class AssignmentDetailComponent extends BaseMeetingComponent implements O * Adds the operator to list of candidates */ public async addSelf(): Promise { - await this.addCandidate({ userId: this.operator.operatorId! }); + if (!this.operator.isInMeeting(this.activeMeetingIdService.meetingId)) { + const infoMessage = this.translate.instant(`Action not possible. You have to be part of the meeting.`); + this.snackBar.open(infoMessage, this.translate.instant(`Ok`)); + } else { + await this.addCandidate({ userId: this.operator.operatorId! }); + } } /** diff --git a/client/src/app/site/pages/meetings/pages/chat/pages/chat-group-list/components/chat-group-detail-message-form/chat-group-detail-message-form.component.html b/client/src/app/site/pages/meetings/pages/chat/pages/chat-group-list/components/chat-group-detail-message-form/chat-group-detail-message-form.component.html index 78bce4c142..c80d75ae63 100644 --- a/client/src/app/site/pages/meetings/pages/chat/pages/chat-group-list/components/chat-group-detail-message-form/chat-group-detail-message-form.component.html +++ b/client/src/app/site/pages/meetings/pages/chat/pages/chat-group-list/components/chat-group-detail-message-form/chat-group-detail-message-form.component.html @@ -1,4 +1,9 @@ - + @if (currentMessage) {
{{ 'Edit' | translate }} @@ -25,14 +30,21 @@ } + @if (!isPartOfMeeting()) { + + + {{ 'You have to be part of the meeting to write messages.' | translate }} + + + } diff --git a/client/src/app/site/pages/meetings/pages/chat/pages/chat-group-list/components/chat-group-detail-message-form/chat-group-detail-message-form.component.ts b/client/src/app/site/pages/meetings/pages/chat/pages/chat-group-list/components/chat-group-detail-message-form/chat-group-detail-message-form.component.ts index 6a8873c65a..c8cb1250a8 100644 --- a/client/src/app/site/pages/meetings/pages/chat/pages/chat-group-list/components/chat-group-detail-message-form/chat-group-detail-message-form.component.ts +++ b/client/src/app/site/pages/meetings/pages/chat/pages/chat-group-list/components/chat-group-detail-message-form/chat-group-detail-message-form.component.ts @@ -1,8 +1,12 @@ import { Component, EventEmitter, Input, Output } from '@angular/core'; import { UntypedFormBuilder, UntypedFormControl, Validators } from '@angular/forms'; +import { MatSnackBar } from '@angular/material/snack-bar'; +import { TranslateService } from '@ngx-translate/core'; import { CHAT_MESSAGE_MAX_LENGTH } from 'src/app/gateways/repositories/chat/chat-message-repository.service'; import { KeyCode } from 'src/app/infrastructure/utils/key-code'; import { ViewChatMessage } from 'src/app/site/pages/meetings/pages/chat'; +import { ActiveMeetingIdService } from 'src/app/site/pages/meetings/services/active-meeting-id.service'; +import { OperatorService } from 'src/app/site/services/operator.service'; @Component({ selector: `os-chat-group-detail-message-form`, @@ -37,7 +41,13 @@ export class ChatGroupDetailMessageFormComponent { private _currentMessage: ViewChatMessage | null = null; - public constructor(fb: UntypedFormBuilder) { + public constructor( + fb: UntypedFormBuilder, + private operator: OperatorService, + private activeMeetingIdService: ActiveMeetingIdService, + private translate: TranslateService, + private snackBar: MatSnackBar + ) { this.messageForm = fb.control(``, [Validators.maxLength(CHAT_MESSAGE_MAX_LENGTH)]); } @@ -49,9 +59,14 @@ export class ChatGroupDetailMessageFormComponent { } public sendChatMessage(): void { - const content = this.messageForm.value?.trim() as string; - this.messageSent.emit(content); - this.resetMessageForm(); + if (!this.isPartOfMeeting()) { + const infoMessage = this.translate.instant(`Action not possible. You have to be part of the meeting.`); + this.snackBar.open(infoMessage, this.translate.instant(`Ok`)); + } else { + const content = this.messageForm.value?.trim() as string; + this.messageSent.emit(content); + this.resetMessageForm(); + } } public cancelEditingChatMessage(): void { @@ -63,4 +78,8 @@ export class ChatGroupDetailMessageFormComponent { this.currentMessage = null; this.messageForm.markAsPristine(); } + + public isPartOfMeeting(): boolean { + return this.operator.isInMeeting(this.activeMeetingIdService.meetingId); + } } diff --git a/client/src/app/site/pages/meetings/pages/motions/pages/motion-detail/pages/motion-form/components/amendment-create-wizard/amendment-create-wizard.component.ts b/client/src/app/site/pages/meetings/pages/motions/pages/motion-detail/pages/motion-form/components/amendment-create-wizard/amendment-create-wizard.component.ts index e75d048413..48dada0612 100644 --- a/client/src/app/site/pages/meetings/pages/motions/pages/motion-detail/pages/motion-form/components/amendment-create-wizard/amendment-create-wizard.component.ts +++ b/client/src/app/site/pages/meetings/pages/motions/pages/motion-detail/pages/motion-form/components/amendment-create-wizard/amendment-create-wizard.component.ts @@ -179,6 +179,9 @@ export class AmendmentCreateWizardComponent extends BaseMeetingComponent impleme amendmentParagraphs[paraNo] = this.contentForm.value[`text_` + paraNo]; } }); + const submitterMeetingUserId = this.operator.isInMeeting(this.activeMeetingId) + ? [this.operator.user.getMeetingUser(this.activeMeetingId)?.id] + : []; const motionCreate = { ...this.contentForm.value, title: this.translate.instant(`Amendment to`) + ` ` + this.motion.getNumberOrTitle(), @@ -186,6 +189,7 @@ export class AmendmentCreateWizardComponent extends BaseMeetingComponent impleme category_id: this.operator.hasPerms(Permission.motionCanManage) ? this.motion.category_id : undefined, lead_motion_id: this.motion.id, amendment_paragraphs: amendmentParagraphs, + submitter_meeting_user_ids: submitterMeetingUserId, workflow_id: this.meetingSettingsService.instant(`motions_default_amendment_workflow_id`) }; diff --git a/client/src/app/site/pages/meetings/pages/motions/pages/motion-detail/pages/motion-form/components/motion-form/motion-form.component.ts b/client/src/app/site/pages/meetings/pages/motions/pages/motion-detail/pages/motion-form/components/motion-form/motion-form.component.ts index 6f1f8f5cbf..3ee590af0a 100644 --- a/client/src/app/site/pages/meetings/pages/motions/pages/motion-detail/pages/motion-form/components/motion-form/motion-form.component.ts +++ b/client/src/app/site/pages/meetings/pages/motions/pages/motion-detail/pages/motion-form/components/motion-form/motion-form.component.ts @@ -251,6 +251,11 @@ export class MotionFormComponent extends BaseMeetingComponent implements OnInit } if (this.newMotion) { + if (update.submitter_ids.length === 0 && this.operator.isInMeeting(this.activeMeetingId)) { + update.submitter_meeting_user_ids = [this.operator.user.getMeetingUser(this.activeMeetingId).id]; + } else { + update.submitter_meeting_user_ids = update.submitter_ids; + } for (const key in update) { if (update[key] === null || update[key].length === 0) { delete update[key]; @@ -323,7 +328,7 @@ export class MotionFormComponent extends BaseMeetingComponent implements OnInit public async createNewSubmitter(username: string): Promise { const newUserObj = await this.createNewUser(username); - this.addNewUserToFormCtrl(newUserObj, `submitter_ids`); + this.addNewUserToFormCtrl(newUserObj, `submitter_meeting_user_ids`); } public async createNewSupporter(username: string): Promise { diff --git a/client/src/app/site/pages/meetings/pages/motions/pages/motion-detail/pages/motion-view/components/motion-manage-title/motion-manage-title.component.html b/client/src/app/site/pages/meetings/pages/motions/pages/motion-detail/pages/motion-view/components/motion-manage-title/motion-manage-title.component.html index a3164173fc..52f2e0560e 100644 --- a/client/src/app/site/pages/meetings/pages/motions/pages/motion-detail/pages/motion-view/components/motion-manage-title/motion-manage-title.component.html +++ b/client/src/app/site/pages/meetings/pages/motions/pages/motion-detail/pages/motion-view/components/motion-manage-title/motion-manage-title.component.html @@ -27,7 +27,7 @@ mat-icon-button matTooltip="{{ 'Mark as personal favorite' | translate }}" matTooltipPosition="right" - [hidden]="publicAccess" + [hidden]="publicAccess || isnotPartOfMeeting" (click)="setFavorite(!isFavorite)" > {{ isFavorite ? 'star' : 'star_border' }} diff --git a/client/src/app/site/pages/meetings/pages/motions/pages/motion-detail/pages/motion-view/components/motion-manage-title/motion-manage-title.component.ts b/client/src/app/site/pages/meetings/pages/motions/pages/motion-detail/pages/motion-view/components/motion-manage-title/motion-manage-title.component.ts index 20675d86b5..1d9af0c78a 100644 --- a/client/src/app/site/pages/meetings/pages/motions/pages/motion-detail/pages/motion-view/components/motion-manage-title/motion-manage-title.component.ts +++ b/client/src/app/site/pages/meetings/pages/motions/pages/motion-detail/pages/motion-view/components/motion-manage-title/motion-manage-title.component.ts @@ -35,6 +35,9 @@ export class MotionManageTitleComponent extends BaseMotionDetailChildComponent { @Input() public publicAccess: boolean; + @Input() + public isnotPartOfMeeting: boolean; + @Output() public updateCrMode = new EventEmitter(); diff --git a/client/src/app/site/pages/meetings/pages/motions/pages/motion-detail/pages/motion-view/components/motion-view/motion-view.component.html b/client/src/app/site/pages/meetings/pages/motions/pages/motion-detail/pages/motion-view/components/motion-view/motion-view.component.html index eeeb6f4d7f..7339121bd9 100644 --- a/client/src/app/site/pages/meetings/pages/motions/pages/motion-detail/pages/motion-view/components/motion-view/motion-view.component.html +++ b/client/src/app/site/pages/meetings/pages/motions/pages/motion-detail/pages/motion-view/components/motion-view/motion-view.component.html @@ -137,6 +137,7 @@