diff --git a/client/src/app/slides/motions/motion-block/motion-block-slide.component.html b/client/src/app/slides/motions/motion-block/motion-block-slide.component.html
index c8c20a481..ef6a614ce 100644
--- a/client/src/app/slides/motions/motion-block/motion-block-slide.component.html
+++ b/client/src/app/slides/motions/motion-block/motion-block-slide.component.html
@@ -4,14 +4,18 @@
Motion block – {{ data.data.motions.length }} motions
-
-
- {{ getMotionTitle(motion) }}
-
-
-
- {{ getRecommendationLabel(motion) }}
-
-
-
+
+
+
+
+ {{ getMotionTitle(i, j) }}
+
+
+
+ {{ getRecommendationLabel(i, j) }}
+
+
+ |
+
+
diff --git a/client/src/app/slides/motions/motion-block/motion-block-slide.component.scss b/client/src/app/slides/motions/motion-block/motion-block-slide.component.scss
index df20acc08..bcc603f4c 100644
--- a/client/src/app/slides/motions/motion-block/motion-block-slide.component.scss
+++ b/client/src/app/slides/motions/motion-block/motion-block-slide.component.scss
@@ -1,4 +1,9 @@
-.blockitem {
+table {
line-height: 1;
- margin-bottom: 10px;
+ width: 100%;
+ table-layout: fixed;
+}
+
+td {
+ min-width: 50%;
}
diff --git a/client/src/app/slides/motions/motion-block/motion-block-slide.component.ts b/client/src/app/slides/motions/motion-block/motion-block-slide.component.ts
index fb2506ec6..c2168abed 100644
--- a/client/src/app/slides/motions/motion-block/motion-block-slide.component.ts
+++ b/client/src/app/slides/motions/motion-block/motion-block-slide.component.ts
@@ -5,9 +5,14 @@ import { TranslateService } from '@ngx-translate/core';
import { MotionBlockSlideData, MotionBlockSlideMotionRepresentation } from './motion-block-slide-data';
import { MotionRepositoryService } from 'app/core/repositories/motions/motion-repository.service';
import { StateCssClassMapping } from 'app/site/motions/models/view-workflow';
-import { BaseMotionSlideComponent, MotionTitleInformation } from '../base/base-motion-slide';
+import { BaseMotionSlideComponent } from '../base/base-motion-slide';
import { SlideData } from 'app/core/core-services/projector-data.service';
+/**
+ * The row threshold to switch from one to a two column layout
+ */
+const TWO_COLUMNS_THRESHOLD = 8;
+
@Component({
selector: 'os-motion-block-slide',
templateUrl: './motion-block-slide.component.html',
@@ -28,7 +33,10 @@ export class MotionBlockSlideComponent extends BaseMotionSlideComponent) {
if (data && data.data.motions) {
data.data.motions = data.data.motions.sort((a, b) =>
- this.languageCollator.compare(this.getMotionIdentifier(a), this.getMotionIdentifier(b))
+ this.languageCollator.compare(
+ this.motionRepo.getIdentifierOrTitle(a),
+ this.motionRepo.getIdentifierOrTitle(b)
+ )
);
}
this._data = data;
@@ -38,30 +46,100 @@ export class MotionBlockSlideComponent extends BaseMotionSlideComponent TWO_COLUMNS_THRESHOLD) {
+ rows = Math.ceil(rows / 2);
+ }
+ return rows;
+ }
+
+ /**
+ * @returns an aray with [1, ..., this.rows]
+ */
+ public get rowsArray(): number[] {
+ const indices = [];
+ const rows = this.rows;
+ for (let i = 0; i < rows; i++) {
+ indices.push(i);
+ }
+ return indices;
+ }
+
+ /**
+ * @returns [0] or [0, 1] if one or two columns are used
+ */
+ public get columnsArray(): number[] {
+ if (this.motionsAmount > TWO_COLUMNS_THRESHOLD) {
+ return [0, 1];
+ } else {
+ return [0];
+ }
+ }
+
public constructor(translate: TranslateService, motionRepo: MotionRepositoryService) {
super(translate, motionRepo);
this.languageCollator = new Intl.Collator(this.translate.currentLang);
}
+ /**
+ * Get the motion for the cell given by i and j
+ *
+ * @param i the row
+ * @param j the column
+ */
+ private getMotion(i: number, j: number): MotionBlockSlideMotionRepresentation {
+ const index = i + this.rows * j;
+ return this.data.data.motions[index];
+ }
+
/**
* @returns the title of the given motion.
*/
- public getMotionTitle(motion: MotionTitleInformation): string {
- return this.motionRepo.getTitle(motion);
+ public getMotionTitle(i: number, j: number): string {
+ return this.motionRepo.getTitle(this.getMotion(i, j));
}
/**
* @returns the identifier (of title if identifier not availabe) of the given motion.
*/
- public getMotionIdentifier(motion: MotionTitleInformation): string {
- return this.motionRepo.getIdentifierOrTitle(motion);
+ public getMotionIdentifier(i: number, j: number): string {
+ return this.motionRepo.getIdentifierOrTitle(this.getMotion(i, j));
}
- public getStateCssColor(motion: MotionBlockSlideMotionRepresentation): string {
- return StateCssClassMapping[motion.recommendation.css_class] || '';
+ /**
+ * @returns true if the motion in cell i and j has a recommendation
+ */
+ public hasRecommendation(i: number, j: number): boolean {
+ return !!this.getMotion(i, j).recommendation;
}
- public getRecommendationLabel(motion: MotionBlockSlideMotionRepresentation): string {
+ /**
+ * @returns the css color for the state of the motion in cell i and j
+ */
+ public getStateCssColor(i: number, j: number): string {
+ return StateCssClassMapping[this.getMotion(i, j).recommendation.css_class] || '';
+ }
+
+ /**
+ * @returns the recommendation label for motion in cell i and j
+ */
+ public getRecommendationLabel(i: number, j: number): string {
+ const motion = this.getMotion(i, j);
let recommendation = this.translate.instant(motion.recommendation.name);
if (motion.recommendation_extension) {
recommendation +=
diff --git a/openslides/motions/projector.py b/openslides/motions/projector.py
index 01cb0699d..7625db93e 100644
--- a/openslides/motions/projector.py
+++ b/openslides/motions/projector.py
@@ -1,5 +1,5 @@
import re
-from typing import Any, Dict
+from typing import Any, Dict, Optional
from ..users.projector import get_user_name
from ..utils.projector import (
@@ -121,13 +121,16 @@ async def get_amendment_base_statute(amendment, all_data):
async def extend_reference_motion_dict(
all_data: AllData,
- recommendation: str,
+ recommendation: Optional[str],
referenced_motions: Dict[int, Dict[str, str]],
) -> None:
"""
Extends a dict of motion ids mapped to their title information.
The client can replace the placeholders in the recommendation correctly.
"""
+ if recommendation is None:
+ return
+
# Collect all meantioned motions via [motion:]
referenced_ids = [
int(id) for id in motion_placeholder_regex.findall(recommendation)