Skip to content

Commit

Permalink
Make duplicate-from mandatory, if 'required_duplicate_from' is set (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
reiterl authored Jul 30, 2024
1 parent 5689279 commit 23bad8f
Show file tree
Hide file tree
Showing 12 changed files with 68 additions and 8 deletions.
2 changes: 2 additions & 0 deletions client/src/app/domain/models/organizations/organization.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export class OrganizationSetting {
public limit_of_meetings!: number;
public limit_of_users!: number;
public default_language!: string;
public require_duplicate_from!: boolean;

public users_email_sender!: string; // default: OpenSlides
public users_email_subject!: string; // default: OpenSlides access data
Expand Down Expand Up @@ -70,6 +71,7 @@ export class Organization extends BaseModel<Organization> {
`limit_of_meetings`,
`limit_of_users`,
`default_language`,
`require_duplicate_from`,
`saml_enabled`,
`saml_login_button_text`,
`saml_attr_mapping`,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export class OrganizationRepositoryService extends BaseRepository<ViewOrganizati
`users_email_replyto`,
`users_email_sender`,
`users_email_subject`,
`require_duplicate_from`,
`saml_enabled`,
`saml_login_button_text`,
`saml_attr_mapping`,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,18 +127,20 @@
<span>{{ 'Edit' | translate }}</span>
</a>
}
@if (!meeting.isArchived) {
@if (!meeting.isArchived && !isCMAndRequireDuplicateFrom) {
<button mat-menu-item (click)="toggleTemplateMeeting()">
<mat-icon color="accent">
{{ isTemplateMeeting ? 'check_box' : 'check_box_outline_blank' }}
</mat-icon>
<span>{{ 'Public template' | translate }}</span>
</button>
}
<button mat-menu-item (click)="onDuplicate()">
<mat-icon>file_copy</mat-icon>
<span>{{ 'Duplicate' | translate }}</span>
</button>
@if (!isCMAndRequireDuplicateFrom) {
<button mat-menu-item (click)="onDuplicate()">
<mat-icon>file_copy</mat-icon>
<span>{{ 'Duplicate' | translate }}</span>
</button>
}
@if (meeting.isActive) {
<button mat-menu-item (click)="onArchive()">
<mat-icon>archive</mat-icon>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { MeetingService } from '../services/meeting.service';
export class CommitteeMeetingPreviewComponent {
@Input() public meeting!: ViewMeeting;
@Input() public committee!: ViewCommittee;
@Input() public isCMAndRequireDuplicateFrom!: boolean;

public readonly OML = OML;
public readonly CML = CML;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ <h2>{{ editMeetingLabel | translate }}</h2>
<mat-form-field subscriptSizing="dynamic">
<mat-label>{{ 'Duplicate from' | translate }}</mat-label>
<os-list-search-selector
[includeNone]="true"
[includeNone]="!isCommitteeManagerAndRequireDuplicateFrom"
[inputListValues]="availableMeetingsObservable"
[ngModel]="theDuplicateFromId"
[ngModelOptions]="{ standalone: true }"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,11 @@ export class MeetingEditComponent extends BaseComponent implements OnInit {
public availableMeetingsObservable: Observable<Selectable[]> | null = null;

public get isValid(): boolean {
if (this.isCommitteeManagerAndRequireDuplicateFrom) {
if (!this.theDuplicateFromId && this.isCreateView) {
return false;
}
}
return this.meetingForm?.valid;
}

Expand Down Expand Up @@ -112,6 +117,7 @@ export class MeetingEditComponent extends BaseComponent implements OnInit {
private committeeId!: Id;

private cameFromList = false;
private requireDuplicateFrom = false;

/**
* The operating user received from the OperatorService
Expand Down Expand Up @@ -164,9 +170,17 @@ export class MeetingEditComponent extends BaseComponent implements OnInit {
this._committee_users_set = new Set(committees.flatMap(committee => committee.user_ids ?? []));
})
);
this.subscriptions.push(
this.orgaSettings
.get(`require_duplicate_from`)
.subscribe((value: boolean) => (this.requireDuplicateFrom = value))
);

this.availableMeetingsObservable = this.orga.organizationObservable.pipe(
map(organization => {
if (this.isCommitteeManagerAndRequireDuplicateFrom) {
return [TEMPLATE_MEETINGS_LABEL, ...organization.template_meetings.sort(this.sortFn)];
}
return [
TEMPLATE_MEETINGS_LABEL,
...organization.template_meetings.sort(this.sortFn),
Expand Down Expand Up @@ -423,6 +437,10 @@ export class MeetingEditComponent extends BaseComponent implements OnInit {
}
}

public get isCommitteeManagerAndRequireDuplicateFrom(): boolean {
return this.requireDuplicateFrom && !this.operator.isOrgaManager;
}

private filterAccountsForCommitteeAdmins(accounts: ViewUser[]): ViewUser[] {
if (this.operator.hasOrganizationPermissions(OML.can_manage_users)) {
return accounts;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ <h1>
<os-committee-meeting-preview
class="meeting-preview-card"
[committee]="committee"
[isCMAndRequireDuplicateFrom]="isCMandRequireDuplicateFrom()"
[meeting]="meeting"
></os-committee-meeting-preview>
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { Id } from 'src/app/domain/definitions/key-types';
import { CML, OML } from 'src/app/domain/definitions/organization-permission';
import { Committee } from 'src/app/domain/models/comittees/committee';
import { ViewMeeting } from 'src/app/site/pages/meetings/view-models/view-meeting';
import { OrganizationSettingsService } from 'src/app/site/pages/organization/services/organization-settings.service';
import { OperatorService } from 'src/app/site/services/operator.service';
import { BaseUiComponent } from 'src/app/ui/base/base-ui-component';
import { PromptService } from 'src/app/ui/modules/prompt-dialog';
Expand All @@ -27,6 +28,7 @@ export class CommitteeDetailViewComponent extends BaseUiComponent {

public receiveExpanded = false;
public forwardingExpanded = false;
public requireDuplicateFrom = false;

public get canManageMeetingsInCommittee(): boolean {
return this.operator.hasCommitteePermissionsNonAdminCheck(this.committeeId, CML.can_manage);
Expand All @@ -42,7 +44,8 @@ export class CommitteeDetailViewComponent extends BaseUiComponent {
private router: Router,
private operator: OperatorService,
private committeeRepo: CommitteeControllerService,
private promptService: PromptService
private promptService: PromptService,
private orgaSettings: OrganizationSettingsService
) {
super();
this.subscriptions.push(
Expand All @@ -53,6 +56,9 @@ export class CommitteeDetailViewComponent extends BaseUiComponent {
}
})
);
this.subscriptions.push(
this.orgaSettings.get(`require_duplicate_from`).subscribe(value => (this.requireDuplicateFrom = value))
);
}

public onCreateMeeting(): void {
Expand All @@ -78,6 +84,10 @@ export class CommitteeDetailViewComponent extends BaseUiComponent {
return this.operator.isSuperAdmin;
}

public isCMandRequireDuplicateFrom(): boolean {
return this.requireDuplicateFrom && !this.isOrgaAdmin();
}

public canAccessCommittee(committee: Committee): boolean {
return (
this.operator.hasCommitteePermissions(committee.id, CML.can_manage) ||
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,18 @@ <h2>{{ 'General' | translate }}</h2>
}
</mat-select>
</mat-form-field>
<!-- require_duplicate_from -->
<section>
<mat-checkbox formControlName="require_duplicate_from">
{{ 'Enable meeting creation from templates only' | translate }}
</mat-checkbox>
<div class="checkbox-hint">
{{
'If this setting is activated, public meeting templates must have been created, as committee administrators can only create meetings based on public templates.'
| translate
}}
</div>
</section>
</div>
</mat-card-content>
</mat-card>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,11 @@
mat-card mat-card-content h2 {
margin-top: 0 !important;
}

.checkbox-hint {
padding-left: 16px;
padding-right: 16px;
padding-top: 0px;
padding-bottom: 0px;
font-size: 12px;
}
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ export class OrganizationSettingsComponent extends BaseComponent {
users_email_replyto: [this._currentOrgaSettings.users_email_replyto, [createEmailValidator()]],
users_email_sender: [this._currentOrgaSettings.users_email_sender],
users_email_subject: [this._currentOrgaSettings.users_email_subject],
default_language: [this._currentOrgaSettings.default_language]
default_language: [this._currentOrgaSettings.default_language],
require_duplicate_from: [this._currentOrgaSettings.require_duplicate_from ?? false]
};
if (this.operator.isSuperAdmin) {
rawSettingsForm = {
Expand Down
4 changes: 4 additions & 0 deletions client/src/app/site/services/operator.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,10 @@ export class OperatorService {
return this.hasOrganizationPermissions(OML.can_manage_organization);
}

public get isAccountAdmin(): boolean {
return this.hasOrganizationPermissions(OML.can_manage_users);
}

private get isCommitteeManager(): boolean {
return !!(this.user.committee_management_ids || []).length;
}
Expand Down

0 comments on commit 23bad8f

Please sign in to comment.