Merge pull request #4382 from FinnStutzenstein/agendaSlide
Agenda item list slide
This commit is contained in:
commit
deb80ddf37
@ -67,7 +67,6 @@ import { SearchValueSelectorComponent } from './components/search-value-selector
|
|||||||
import { OpenSlidesDateAdapter } from './date-adapter';
|
import { OpenSlidesDateAdapter } from './date-adapter';
|
||||||
import { PromptDialogComponent } from './components/prompt-dialog/prompt-dialog.component';
|
import { PromptDialogComponent } from './components/prompt-dialog/prompt-dialog.component';
|
||||||
import { SortingListComponent } from './components/sorting-list/sorting-list.component';
|
import { SortingListComponent } from './components/sorting-list/sorting-list.component';
|
||||||
import { SpeakerListComponent } from 'app/site/agenda/components/speaker-list/speaker-list.component';
|
|
||||||
import { SortingTreeComponent } from './components/sorting-tree/sorting-tree.component';
|
import { SortingTreeComponent } from './components/sorting-tree/sorting-tree.component';
|
||||||
import { ChoiceDialogComponent } from './components/choice-dialog/choice-dialog.component';
|
import { ChoiceDialogComponent } from './components/choice-dialog/choice-dialog.component';
|
||||||
import { OsSortFilterBarComponent } from './components/os-sort-filter-bar/os-sort-filter-bar.component';
|
import { OsSortFilterBarComponent } from './components/os-sort-filter-bar/os-sort-filter-bar.component';
|
||||||
@ -215,7 +214,6 @@ import { CountdownTimeComponent } from './components/contdown-time/countdown-tim
|
|||||||
SearchValueSelectorComponent,
|
SearchValueSelectorComponent,
|
||||||
PromptDialogComponent,
|
PromptDialogComponent,
|
||||||
SortingListComponent,
|
SortingListComponent,
|
||||||
SpeakerListComponent,
|
|
||||||
SortingTreeComponent,
|
SortingTreeComponent,
|
||||||
ChoiceDialogComponent,
|
ChoiceDialogComponent,
|
||||||
OsSortFilterBarComponent,
|
OsSortFilterBarComponent,
|
||||||
|
@ -4,7 +4,7 @@ import { Routes, RouterModule } from '@angular/router';
|
|||||||
import { AgendaImportListComponent } from './components/agenda-import-list/agenda-import-list.component';
|
import { AgendaImportListComponent } from './components/agenda-import-list/agenda-import-list.component';
|
||||||
import { AgendaListComponent } from './components/agenda-list/agenda-list.component';
|
import { AgendaListComponent } from './components/agenda-list/agenda-list.component';
|
||||||
import { AgendaSortComponent } from './components/agenda-sort/agenda-sort.component';
|
import { AgendaSortComponent } from './components/agenda-sort/agenda-sort.component';
|
||||||
import { SpeakerListComponent } from './components/speaker-list/speaker-list.component';
|
import { ListOfSpeakersComponent } from './components/list-of-speakers/list-of-speakers.component';
|
||||||
import { TopicDetailComponent } from './components/topic-detail/topic-detail.component';
|
import { TopicDetailComponent } from './components/topic-detail/topic-detail.component';
|
||||||
|
|
||||||
const routes: Routes = [
|
const routes: Routes = [
|
||||||
@ -12,9 +12,9 @@ const routes: Routes = [
|
|||||||
{ path: 'import', component: AgendaImportListComponent },
|
{ path: 'import', component: AgendaImportListComponent },
|
||||||
{ path: 'topics/new', component: TopicDetailComponent },
|
{ path: 'topics/new', component: TopicDetailComponent },
|
||||||
{ path: 'sort-agenda', component: AgendaSortComponent },
|
{ path: 'sort-agenda', component: AgendaSortComponent },
|
||||||
{ path: 'speakers', component: SpeakerListComponent },
|
{ path: 'speakers', component: ListOfSpeakersComponent },
|
||||||
{ path: 'topics/:id', component: TopicDetailComponent },
|
{ path: 'topics/:id', component: TopicDetailComponent },
|
||||||
{ path: ':id/speakers', component: SpeakerListComponent }
|
{ path: ':id/speakers', component: ListOfSpeakersComponent }
|
||||||
];
|
];
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
|
@ -8,6 +8,7 @@ import { AgendaRoutingModule } from './agenda-routing.module';
|
|||||||
import { SharedModule } from '../../shared/shared.module';
|
import { SharedModule } from '../../shared/shared.module';
|
||||||
import { TopicDetailComponent } from './components/topic-detail/topic-detail.component';
|
import { TopicDetailComponent } from './components/topic-detail/topic-detail.component';
|
||||||
import { AgendaSortComponent } from './components/agenda-sort/agenda-sort.component';
|
import { AgendaSortComponent } from './components/agenda-sort/agenda-sort.component';
|
||||||
|
import { ListOfSpeakersComponent } from './components/list-of-speakers/list-of-speakers.component';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AppModule for the agenda and it's children.
|
* AppModule for the agenda and it's children.
|
||||||
@ -20,7 +21,8 @@ import { AgendaSortComponent } from './components/agenda-sort/agenda-sort.compon
|
|||||||
TopicDetailComponent,
|
TopicDetailComponent,
|
||||||
ItemInfoDialogComponent,
|
ItemInfoDialogComponent,
|
||||||
AgendaImportListComponent,
|
AgendaImportListComponent,
|
||||||
AgendaSortComponent
|
AgendaSortComponent,
|
||||||
|
ListOfSpeakersComponent
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
export class AgendaModule {}
|
export class AgendaModule {}
|
||||||
|
@ -127,6 +127,10 @@
|
|||||||
<span translate>Sort</span>
|
<span translate>Sort</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Project agenda -->
|
||||||
|
<os-projector-button [object]="itemListSlide" [menuItem]="true"></os-projector-button>
|
||||||
|
|
||||||
<!-- Current list of speakers -->
|
<!-- Current list of speakers -->
|
||||||
<button mat-menu-item routerLink="speakers">
|
<button mat-menu-item routerLink="speakers">
|
||||||
<mat-icon>mic</mat-icon>
|
<mat-icon>mic</mat-icon>
|
||||||
|
@ -18,6 +18,7 @@ import { PromptService } from 'app/core/ui-services/prompt.service';
|
|||||||
import { PdfDocumentService } from 'app/core/ui-services/pdf-document.service';
|
import { PdfDocumentService } from 'app/core/ui-services/pdf-document.service';
|
||||||
import { ViewportService } from 'app/core/ui-services/viewport.service';
|
import { ViewportService } from 'app/core/ui-services/viewport.service';
|
||||||
import { ViewItem } from '../../models/view-item';
|
import { ViewItem } from '../../models/view-item';
|
||||||
|
import { ProjectorElementBuildDeskriptor } from 'app/site/base/projectable';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List view for the agenda.
|
* List view for the agenda.
|
||||||
@ -49,6 +50,22 @@ export class AgendaListComponent extends ListViewBaseComponent<ViewItem, Item> i
|
|||||||
return this.operator.hasPerms('agenda.can_manage');
|
return this.operator.hasPerms('agenda.can_manage');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public itemListSlide: ProjectorElementBuildDeskriptor = {
|
||||||
|
getBasicProjectorElement: options => ({
|
||||||
|
name: 'agenda/item-list',
|
||||||
|
getIdentifiers: () => ['name']
|
||||||
|
}),
|
||||||
|
slideOptions: [
|
||||||
|
{
|
||||||
|
key: 'only_main_items',
|
||||||
|
displayName: 'Only main agenda items',
|
||||||
|
default: false
|
||||||
|
}
|
||||||
|
],
|
||||||
|
projectionDefaultName: 'agenda_all_items',
|
||||||
|
getDialogTitle: () => this.translate.instant('Item list')
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The usual constructor for components
|
* The usual constructor for components
|
||||||
* @param titleService Setting the browser tab title
|
* @param titleService Setting the browser tab title
|
||||||
|
@ -1,20 +1,21 @@
|
|||||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
import { SpeakerListComponent } from './speaker-list.component';
|
import { ListOfSpeakersComponent } from './list-of-speakers.component';
|
||||||
import { E2EImportsModule } from '../../../../../e2e-imports.module';
|
import { E2EImportsModule } from '../../../../../e2e-imports.module';
|
||||||
|
|
||||||
describe('SpeakerListComponent', () => {
|
describe('ListOfSpeakersComponent', () => {
|
||||||
let component: SpeakerListComponent;
|
let component: ListOfSpeakersComponent;
|
||||||
let fixture: ComponentFixture<SpeakerListComponent>;
|
let fixture: ComponentFixture<ListOfSpeakersComponent>;
|
||||||
|
|
||||||
beforeEach(async(() => {
|
beforeEach(async(() => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
imports: [E2EImportsModule]
|
imports: [E2EImportsModule],
|
||||||
|
declarations: [ListOfSpeakersComponent]
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
fixture = TestBed.createComponent(SpeakerListComponent);
|
fixture = TestBed.createComponent(ListOfSpeakersComponent);
|
||||||
component = fixture.componentInstance;
|
component = fixture.componentInstance;
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
});
|
});
|
@ -25,11 +25,11 @@ import { DurationService } from 'app/core/ui-services/duration.service';
|
|||||||
* The list of speakers for agenda items.
|
* The list of speakers for agenda items.
|
||||||
*/
|
*/
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'os-speaker-list',
|
selector: 'os-list-of-speakers',
|
||||||
templateUrl: './speaker-list.component.html',
|
templateUrl: './list-of-speakers.component.html',
|
||||||
styleUrls: ['./speaker-list.component.scss']
|
styleUrls: ['./list-of-speakers.component.scss']
|
||||||
})
|
})
|
||||||
export class SpeakerListComponent extends BaseViewComponent implements OnInit {
|
export class ListOfSpeakersComponent extends BaseViewComponent implements OnInit {
|
||||||
/**
|
/**
|
||||||
* Determine if the user is viewing the current list if speakers
|
* Determine if the user is viewing the current list if speakers
|
||||||
*/
|
*/
|
@ -11,7 +11,6 @@ import { MotionCommentSectionListComponent } from './components/motion-comment-s
|
|||||||
import { MotionDetailComponent } from './components/motion-detail/motion-detail.component';
|
import { MotionDetailComponent } from './components/motion-detail/motion-detail.component';
|
||||||
import { MotionImportListComponent } from './components/motion-import-list/motion-import-list.component';
|
import { MotionImportListComponent } from './components/motion-import-list/motion-import-list.component';
|
||||||
import { MotionListComponent } from './components/motion-list/motion-list.component';
|
import { MotionListComponent } from './components/motion-list/motion-list.component';
|
||||||
import { SpeakerListComponent } from '../agenda/components/speaker-list/speaker-list.component';
|
|
||||||
import { StatuteImportListComponent } from './components/statute-paragraph-list/statute-import-list/statute-import-list.component';
|
import { StatuteImportListComponent } from './components/statute-paragraph-list/statute-import-list/statute-import-list.component';
|
||||||
import { StatuteParagraphListComponent } from './components/statute-paragraph-list/statute-paragraph-list.component';
|
import { StatuteParagraphListComponent } from './components/statute-paragraph-list/statute-paragraph-list.component';
|
||||||
import { WorkflowListComponent } from './components/workflow-list/workflow-list.component';
|
import { WorkflowListComponent } from './components/workflow-list/workflow-list.component';
|
||||||
@ -32,7 +31,6 @@ const routes: Routes = [
|
|||||||
{ path: 'workflow', component: WorkflowListComponent },
|
{ path: 'workflow', component: WorkflowListComponent },
|
||||||
{ path: 'workflow/:id', component: WorkflowDetailComponent },
|
{ path: 'workflow/:id', component: WorkflowDetailComponent },
|
||||||
{ path: ':id', component: MotionDetailComponent },
|
{ path: ':id', component: MotionDetailComponent },
|
||||||
{ path: ':id/speakers', component: SpeakerListComponent },
|
|
||||||
{ path: ':id/create-amendment', component: AmendmentCreateWizardComponent }
|
{ path: ':id/create-amendment', component: AmendmentCreateWizardComponent }
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -0,0 +1,10 @@
|
|||||||
|
export interface SlideItem {
|
||||||
|
item_number: string;
|
||||||
|
title_information: object;
|
||||||
|
collection: string;
|
||||||
|
depth: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ItemListSlideData {
|
||||||
|
items: SlideItem[];
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
<div *ngIf="data">
|
||||||
|
<h1 translate>Agenda</h1>
|
||||||
|
|
||||||
|
<div
|
||||||
|
*ngFor="let item of data.data.items"
|
||||||
|
[ngStyle]="getItemStyle(item)"
|
||||||
|
[ngClass]="item.depth === 0 ? 'mainitem' : 'subitem'"
|
||||||
|
class="item"
|
||||||
|
>
|
||||||
|
<span *ngIf="item.item_number">{{ item.item_number }} ·</span>
|
||||||
|
{{ getTitle(item) }}
|
||||||
|
</div>
|
||||||
|
</div>
|
@ -0,0 +1,10 @@
|
|||||||
|
.item {
|
||||||
|
line-height: 34px;
|
||||||
|
}
|
||||||
|
.mainitem {
|
||||||
|
font-size: 110%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.subitem {
|
||||||
|
font-size: 90%;
|
||||||
|
}
|
@ -1,21 +1,21 @@
|
|||||||
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
import { UsersUserSlideComponent } from './users-user-slide.component';
|
import { ItemListSlideComponent } from './item-list-slide.component';
|
||||||
import { E2EImportsModule } from '../../../../e2e-imports.module';
|
import { E2EImportsModule } from '../../../../e2e-imports.module';
|
||||||
|
|
||||||
describe('UsersUserSlideComponent', () => {
|
describe('ItemListSlideComponent', () => {
|
||||||
let component: UsersUserSlideComponent;
|
let component: ItemListSlideComponent;
|
||||||
let fixture: ComponentFixture<UsersUserSlideComponent>;
|
let fixture: ComponentFixture<ItemListSlideComponent>;
|
||||||
|
|
||||||
beforeEach(async(() => {
|
beforeEach(async(() => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
imports: [E2EImportsModule],
|
imports: [E2EImportsModule],
|
||||||
declarations: [UsersUserSlideComponent]
|
declarations: [ItemListSlideComponent]
|
||||||
}).compileComponents();
|
}).compileComponents();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
fixture = TestBed.createComponent(UsersUserSlideComponent);
|
fixture = TestBed.createComponent(ItemListSlideComponent);
|
||||||
component = fixture.componentInstance;
|
component = fixture.componentInstance;
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
});
|
});
|
@ -0,0 +1,31 @@
|
|||||||
|
import { Component } from '@angular/core';
|
||||||
|
import { BaseSlideComponent } from 'app/slides/base-slide-component';
|
||||||
|
import { ItemListSlideData, SlideItem } from './item-list-slide-data';
|
||||||
|
import { CollectionStringMapperService } from 'app/core/core-services/collectionStringMapper.service';
|
||||||
|
import { isBaseAgendaContentObjectRepository } from 'app/core/repositories/base-agenda-content-object-repository';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'os-item-list-slide',
|
||||||
|
templateUrl: './item-list-slide.component.html',
|
||||||
|
styleUrls: ['./item-list-slide.component.scss']
|
||||||
|
})
|
||||||
|
export class ItemListSlideComponent extends BaseSlideComponent<ItemListSlideData> {
|
||||||
|
public constructor(private collectionStringMapperService: CollectionStringMapperService) {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
|
public getTitle(item: SlideItem): string {
|
||||||
|
const repo = this.collectionStringMapperService.getRepository(item.collection);
|
||||||
|
if (isBaseAgendaContentObjectRepository(repo)) {
|
||||||
|
return repo.getAgendaTitle(item.title_information);
|
||||||
|
} else {
|
||||||
|
throw new Error('The content object has no agenda based repository!');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public getItemStyle(item: SlideItem): object {
|
||||||
|
return {
|
||||||
|
'margin-left': 20 * item.depth + 'px'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
import { ItemListSlideModule } from './item-list-slide.module';
|
||||||
|
|
||||||
|
describe('ItemListSlideModule', () => {
|
||||||
|
let itemListSlideModule: ItemListSlideModule;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
itemListSlideModule = new ItemListSlideModule();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create an instance', () => {
|
||||||
|
expect(itemListSlideModule).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
@ -0,0 +1,7 @@
|
|||||||
|
import { NgModule } from '@angular/core';
|
||||||
|
|
||||||
|
import { makeSlideModule } from 'app/slides/base-slide-module';
|
||||||
|
import { ItemListSlideComponent } from './item-list-slide.component';
|
||||||
|
|
||||||
|
@NgModule(makeSlideModule(ItemListSlideComponent))
|
||||||
|
export class ItemListSlideModule {}
|
@ -5,6 +5,11 @@ import { ViewModelStoreService } from 'app/core/core-services/view-model-store.s
|
|||||||
import { ProjectorElement } from 'app/shared/models/core/projector';
|
import { ProjectorElement } from 'app/shared/models/core/projector';
|
||||||
|
|
||||||
export const allSlidesDynamicConfiguration: (SlideDynamicConfiguration & Slide)[] = [
|
export const allSlidesDynamicConfiguration: (SlideDynamicConfiguration & Slide)[] = [
|
||||||
|
{
|
||||||
|
slide: 'agenda/item-list',
|
||||||
|
scaleable: true,
|
||||||
|
scrollable: true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
slide: 'topics/topic',
|
slide: 'topics/topic',
|
||||||
scaleable: true,
|
scaleable: true,
|
||||||
|
@ -8,10 +8,18 @@ import { SlideManifest } from './slide-manifest';
|
|||||||
* is no such thing as "dynamic update" in this case..
|
* is no such thing as "dynamic update" in this case..
|
||||||
*/
|
*/
|
||||||
export const allSlides: SlideManifest[] = [
|
export const allSlides: SlideManifest[] = [
|
||||||
|
{
|
||||||
|
slide: 'agenda/item-list',
|
||||||
|
path: 'agenda/item-list',
|
||||||
|
loadChildren: './slides/agenda/item-list/item-list-slide.module#ItemListSlideModule',
|
||||||
|
verboseName: 'Agenda',
|
||||||
|
elementIdentifiers: ['name'],
|
||||||
|
canBeMappedToModel: false
|
||||||
|
},
|
||||||
{
|
{
|
||||||
slide: 'topics/topic',
|
slide: 'topics/topic',
|
||||||
path: 'topics/topic',
|
path: 'topics/topic',
|
||||||
loadChildren: './slides/agenda/topic/topic-slide.module#TopicSlideModule',
|
loadChildren: './slides/topics/topic/topic-slide.module#TopicSlideModule',
|
||||||
verboseName: 'Topic',
|
verboseName: 'Topic',
|
||||||
elementIdentifiers: ['name', 'id'],
|
elementIdentifiers: ['name', 'id'],
|
||||||
canBeMappedToModel: true
|
canBeMappedToModel: true
|
||||||
@ -35,7 +43,7 @@ export const allSlides: SlideManifest[] = [
|
|||||||
{
|
{
|
||||||
slide: 'users/user',
|
slide: 'users/user',
|
||||||
path: 'users/user',
|
path: 'users/user',
|
||||||
loadChildren: './slides/users/user/users-user-slide.module#UsersUserSlideModule',
|
loadChildren: './slides/users/user/user-slide.module#UserSlideModule',
|
||||||
verboseName: 'Participant',
|
verboseName: 'Participant',
|
||||||
elementIdentifiers: ['name', 'id'],
|
elementIdentifiers: ['name', 'id'],
|
||||||
canBeMappedToModel: true
|
canBeMappedToModel: true
|
||||||
|
3
client/src/app/slides/users/user/user-slide-data.ts
Normal file
3
client/src/app/slides/users/user/user-slide-data.ts
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
export interface UserSlideData {
|
||||||
|
user: string;
|
||||||
|
}
|
@ -0,0 +1,26 @@
|
|||||||
|
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { UserSlideComponent } from './user-slide.component';
|
||||||
|
import { E2EImportsModule } from '../../../../e2e-imports.module';
|
||||||
|
|
||||||
|
describe('UserSlideComponent', () => {
|
||||||
|
let component: UserSlideComponent;
|
||||||
|
let fixture: ComponentFixture<UserSlideComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
imports: [E2EImportsModule],
|
||||||
|
declarations: [UserSlideComponent]
|
||||||
|
}).compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(UserSlideComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
13
client/src/app/slides/users/user/user-slide.component.ts
Normal file
13
client/src/app/slides/users/user/user-slide.component.ts
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import { Component } from '@angular/core';
|
||||||
|
import { BaseSlideComponent } from 'app/slides/base-slide-component';
|
||||||
|
import { UserSlideData } from './user-slide-data';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'os-user-slide',
|
||||||
|
templateUrl: './user-slide.component.html'
|
||||||
|
})
|
||||||
|
export class UserSlideComponent extends BaseSlideComponent<UserSlideData> {
|
||||||
|
public constructor() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
}
|
13
client/src/app/slides/users/user/user-slide.module.spec.ts
Normal file
13
client/src/app/slides/users/user/user-slide.module.spec.ts
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import { UserSlideModule } from './user-slide.module';
|
||||||
|
|
||||||
|
describe('UserSlideModule', () => {
|
||||||
|
let userSlideModule: UserSlideModule;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
userSlideModule = new UserSlideModule();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create an instance', () => {
|
||||||
|
expect(userSlideModule).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
7
client/src/app/slides/users/user/user-slide.module.ts
Normal file
7
client/src/app/slides/users/user/user-slide.module.ts
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
import { NgModule } from '@angular/core';
|
||||||
|
|
||||||
|
import { makeSlideModule } from 'app/slides/base-slide-module';
|
||||||
|
import { UserSlideComponent } from './user-slide.component';
|
||||||
|
|
||||||
|
@NgModule(makeSlideModule(UserSlideComponent))
|
||||||
|
export class UserSlideModule {}
|
@ -1,3 +0,0 @@
|
|||||||
export interface UsersUserSlideData {
|
|
||||||
user: string;
|
|
||||||
}
|
|
@ -1,14 +0,0 @@
|
|||||||
import { Component } from '@angular/core';
|
|
||||||
import { BaseSlideComponent } from 'app/slides/base-slide-component';
|
|
||||||
import { UsersUserSlideData } from './users-user-slide-data';
|
|
||||||
|
|
||||||
@Component({
|
|
||||||
selector: 'os-users-user-slide',
|
|
||||||
templateUrl: './users-user-slide.component.html',
|
|
||||||
styleUrls: ['./users-user-slide.component.scss']
|
|
||||||
})
|
|
||||||
export class UsersUserSlideComponent extends BaseSlideComponent<UsersUserSlideData> {
|
|
||||||
public constructor() {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,13 +0,0 @@
|
|||||||
import { UsersUserSlideModule } from './users-user-slide.module';
|
|
||||||
|
|
||||||
describe('UsersUserSlideModule', () => {
|
|
||||||
let usersUserSlideModule: UsersUserSlideModule;
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
usersUserSlideModule = new UsersUserSlideModule();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should create an instance', () => {
|
|
||||||
expect(usersUserSlideModule).toBeTruthy();
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,7 +0,0 @@
|
|||||||
import { NgModule } from '@angular/core';
|
|
||||||
|
|
||||||
import { makeSlideModule } from 'app/slides/base-slide-module';
|
|
||||||
import { UsersUserSlideComponent } from './users-user-slide.component';
|
|
||||||
|
|
||||||
@NgModule(makeSlideModule(UsersUserSlideComponent))
|
|
||||||
export class UsersUserSlideModule {}
|
|
@ -1,5 +1,5 @@
|
|||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
from typing import Any, Dict, List, Tuple
|
from typing import Any, Dict, List
|
||||||
|
|
||||||
from ..users.projector import get_user_name
|
from ..users.projector import get_user_name
|
||||||
from ..utils.projector import (
|
from ..utils.projector import (
|
||||||
@ -16,9 +16,7 @@ from ..utils.projector import (
|
|||||||
# to be fast!
|
# to be fast!
|
||||||
|
|
||||||
|
|
||||||
def get_tree(
|
def get_flat_tree(all_data: AllData, parent_id: int = 0) -> List[Dict[str, Any]]:
|
||||||
all_data: AllData, parent_id: int = 0
|
|
||||||
) -> List[Tuple[int, List[Tuple[int, List[Any]]]]]:
|
|
||||||
"""
|
"""
|
||||||
Build the item tree from all_data.
|
Build the item tree from all_data.
|
||||||
|
|
||||||
@ -36,35 +34,51 @@ def get_tree(
|
|||||||
if item["type"] == 1: # only normal items
|
if item["type"] == 1: # only normal items
|
||||||
children[item["parent_id"] or 0].append(item["id"])
|
children[item["parent_id"] or 0].append(item["id"])
|
||||||
|
|
||||||
def get_children(
|
tree = []
|
||||||
item_ids: List[int]
|
|
||||||
) -> List[Tuple[int, List[Tuple[int, List[Any]]]]]:
|
|
||||||
return [
|
|
||||||
(all_data["agenda/item"][item_id]["title"], get_children(children[item_id]))
|
|
||||||
for item_id in item_ids
|
|
||||||
]
|
|
||||||
|
|
||||||
return get_children(children[parent_id])
|
def get_children(item_ids: List[int], depth: int) -> None:
|
||||||
|
for item_id in item_ids:
|
||||||
|
tree.append(
|
||||||
|
{
|
||||||
|
"item_number": all_data["agenda/item"][item_id]["item_number"],
|
||||||
|
"title_information": all_data["agenda/item"][item_id][
|
||||||
|
"title_information"
|
||||||
|
],
|
||||||
|
"collection": all_data["agenda/item"][item_id]["content_object"][
|
||||||
|
"collection"
|
||||||
|
],
|
||||||
|
"depth": depth,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
get_children(children[item_id], depth + 1)
|
||||||
|
|
||||||
|
get_children(children[parent_id], 0)
|
||||||
|
return tree
|
||||||
|
|
||||||
|
|
||||||
def items_slide(all_data: AllData, element: Dict[str, Any]) -> Dict[str, Any]:
|
def item_list_slide(all_data: AllData, element: Dict[str, Any]) -> Dict[str, Any]:
|
||||||
"""
|
"""
|
||||||
Item list slide.
|
Item list slide.
|
||||||
|
|
||||||
Returns all root items or all children of an item.
|
Returns all root items or all children of an item.
|
||||||
"""
|
"""
|
||||||
root_item_id = element.get("id") or None
|
only_main_items = element.get("only_main_items", True)
|
||||||
show_tree = element.get("tree") or False
|
|
||||||
|
|
||||||
if show_tree:
|
if only_main_items:
|
||||||
agenda_items = get_tree(all_data, root_item_id or 0)
|
|
||||||
else:
|
|
||||||
agenda_items = []
|
agenda_items = []
|
||||||
for item in sorted(
|
for item in sorted(
|
||||||
all_data["agenda/item"].values(), key=lambda item: item["weight"]
|
all_data["agenda/item"].values(), key=lambda item: item["weight"]
|
||||||
):
|
):
|
||||||
if item["parent_id"] == root_item_id and item["type"] == 1:
|
if item["parent_id"] is None and item["type"] == 1:
|
||||||
agenda_items.append(item["title"])
|
agenda_items.append(
|
||||||
|
{
|
||||||
|
"item_number": item["item_number"],
|
||||||
|
"title_information": item["title_information"],
|
||||||
|
"collection": item["content_object"]["collection"],
|
||||||
|
}
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
agenda_items = get_flat_tree(all_data)
|
||||||
|
|
||||||
return {"items": agenda_items}
|
return {"items": agenda_items}
|
||||||
|
|
||||||
@ -144,7 +158,7 @@ def current_list_of_speakers_slide(
|
|||||||
|
|
||||||
|
|
||||||
def register_projector_slides() -> None:
|
def register_projector_slides() -> None:
|
||||||
register_projector_slide("agenda/item-list", items_slide)
|
register_projector_slide("agenda/item-list", item_list_slide)
|
||||||
register_projector_slide("agenda/list-of-speakers", list_of_speakers_slide)
|
register_projector_slide("agenda/list-of-speakers", list_of_speakers_slide)
|
||||||
register_projector_slide(
|
register_projector_slide(
|
||||||
"agenda/current-list-of-speakers", current_list_of_speakers_slide
|
"agenda/current-list-of-speakers", current_list_of_speakers_slide
|
||||||
|
@ -12,8 +12,7 @@ def all_data():
|
|||||||
1: {
|
1: {
|
||||||
"id": 1,
|
"id": 1,
|
||||||
"item_number": "",
|
"item_number": "",
|
||||||
"title": "Item1",
|
"title_information": {"title": "item1"},
|
||||||
"title_with_type": "Item1",
|
|
||||||
"comment": None,
|
"comment": None,
|
||||||
"closed": False,
|
"closed": False,
|
||||||
"type": 1,
|
"type": 1,
|
||||||
@ -31,6 +30,7 @@ def all_data():
|
|||||||
"item_number": "",
|
"item_number": "",
|
||||||
"title": "item2",
|
"title": "item2",
|
||||||
"title_with_type": "item2",
|
"title_with_type": "item2",
|
||||||
|
"title_information": {"title": "item2"},
|
||||||
"comment": None,
|
"comment": None,
|
||||||
"closed": False,
|
"closed": False,
|
||||||
"type": 1,
|
"type": 1,
|
||||||
@ -49,6 +49,7 @@ def all_data():
|
|||||||
"item_number": "",
|
"item_number": "",
|
||||||
"title": "item3",
|
"title": "item3",
|
||||||
"title_with_type": "item3",
|
"title_with_type": "item3",
|
||||||
|
"title_information": {"title": "item3"},
|
||||||
"comment": None,
|
"comment": None,
|
||||||
"closed": True,
|
"closed": True,
|
||||||
"type": 2,
|
"type": 2,
|
||||||
@ -65,8 +66,7 @@ def all_data():
|
|||||||
4: {
|
4: {
|
||||||
"id": 4,
|
"id": 4,
|
||||||
"item_number": "",
|
"item_number": "",
|
||||||
"title": "item4",
|
"title_information": {"title": "item4"},
|
||||||
"title_with_type": "item4",
|
|
||||||
"comment": None,
|
"comment": None,
|
||||||
"closed": True,
|
"closed": True,
|
||||||
"type": 1,
|
"type": 1,
|
||||||
@ -85,33 +85,51 @@ def all_data():
|
|||||||
return all_data
|
return all_data
|
||||||
|
|
||||||
|
|
||||||
def test_items(all_data):
|
def test_main_items(all_data):
|
||||||
element: Dict[str, Any] = {}
|
element: Dict[str, Any] = {}
|
||||||
|
|
||||||
data = projector.items_slide(all_data, element)
|
data = projector.item_list_slide(all_data, element)
|
||||||
|
|
||||||
assert data == {"items": ["Item1", "item2"]}
|
assert data == {
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"collection": "topics/topic",
|
||||||
|
"item_number": "",
|
||||||
|
"title_information": {"title": "item1"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"collection": "topics/topic",
|
||||||
|
"item_number": "",
|
||||||
|
"title_information": {"title": "item2"},
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
def test_items_parent(all_data):
|
def test_all_items(all_data):
|
||||||
element: Dict[str, Any] = {"id": 1}
|
element: Dict[str, Any] = {"only_main_items": False}
|
||||||
|
|
||||||
data = projector.items_slide(all_data, element)
|
data = projector.item_list_slide(all_data, element)
|
||||||
|
|
||||||
assert data == {"items": ["item4"]}
|
assert data == {
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
def test_items_tree(all_data):
|
"collection": "topics/topic",
|
||||||
element: Dict[str, Any] = {"tree": True}
|
"depth": 0,
|
||||||
|
"item_number": "",
|
||||||
data = projector.items_slide(all_data, element)
|
"title_information": {"title": "item1"},
|
||||||
|
},
|
||||||
assert data == {"items": [("Item1", [("item4", [])]), ("item2", [])]}
|
{
|
||||||
|
"collection": "topics/topic",
|
||||||
|
"depth": 1,
|
||||||
def test_items_tree_parent(all_data):
|
"item_number": "",
|
||||||
element: Dict[str, Any] = {"tree": True, "id": 1}
|
"title_information": {"title": "item4"},
|
||||||
|
},
|
||||||
data = projector.items_slide(all_data, element)
|
{
|
||||||
|
"collection": "topics/topic",
|
||||||
assert data == {"items": [("item4", [])]}
|
"depth": 0,
|
||||||
|
"item_number": "",
|
||||||
|
"title_information": {"title": "item2"},
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user