Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ at-top-bar {
top: variables.$toolbar-height;
bottom: 0;
width: 100%;
overflow: scroll;
overflow: auto;
}

.view-content {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,12 @@ import { EditComponentTitleComponent } from '../edit-component-title/edit-compon
@if (advancedMode) {
<edit-component-advanced class="h-full" [component]="component" />
} @else {
<edit-component-title class="block pt-4" [componentContent]="data.componentContent" />
@if (showComponentTitles) {
<edit-component-title class="block pt-4" [componentContent]="data.componentContent" />
}
<edit-component
class="block h-full pb-4"
[class.pt-4]="!showComponentTitles"
[componentContent]="data.componentContent"
[nodeId]="data.nodeId"
/>
Expand Down Expand Up @@ -84,6 +87,7 @@ export class EditComponentDialogComponent {
protected componentIndex: number;
protected componentTypeIcon: string;
protected componentTypeLabel: string;
protected showComponentTitles: boolean;

constructor(
private componentInfoService: ComponentInfoService,
Expand All @@ -101,5 +105,6 @@ export class EditComponentDialogComponent {
this.componentTypeLabel = this.componentInfoService
.getInfo(this.data.componentContent.type)
.getLabel();
this.showComponentTitles = this.projectService.getThemeSettings().showComponentTitles;
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
<div class="project-info-authoring">
<mat-tab-group animationDuration="0ms">
<mat-tab-group dynamicHeight animationDuration="0ms">
<mat-tab>
<ng-template mat-tab-label>
<mat-icon>settings</mat-icon>&nbsp;<span i18n>General</span>
</ng-template>
<div class="flex flex-col gap-5 mt-4">
<div class="flex flex-col gap-4 mt-4">
<div>
@for (metadataField of metadataAuthoring.fields; track metadataField) {
@if (metadataField.key === 'title') {
Expand All @@ -25,8 +25,8 @@
}
}
</div>
<div class="flex flex-col gap-4 p-3">
<div class="project-icon-label flex flex-row items-center gap-4">
<div class="flex flex-col gap-4">
<div class="project-icon flex flex-row items-center gap-4">
<span i18n>Unit Icon</span>
<button mat-raised-button color="primary" (click)="toggleEditProjectIconMode()" i18n>
Edit
Expand All @@ -37,10 +37,9 @@
<img [src]="projectIcon" class="project-icon" />
</div>
} @else if (isShowProjectIconError) {
<div class="project-icon-error">
<p class="red mb-4" i18n>This unit does not have a unit icon.</p>
<p class="red" i18n>Click the edit button to set one.</p>
</div>
<p class="warn" i18n>
This unit does not have a unit icon. Click the edit button to set one.
</p>
} @else if (isShowProjectIconLoading) {
<div>
<mat-spinner />
Expand All @@ -62,7 +61,7 @@
<img
role="button"
tabindex="0"
class="project-icon-to-choose"
class="cursor-pointer"
src="/projectIcons/{{ projectIcon }}"
(click)="setFeaturedProjectIcon(projectIcon)"
(keydown.enter)="setFeaturedProjectIcon(projectIcon)"
Expand All @@ -77,6 +76,31 @@
</div>
</div>
</mat-tab>
<mat-tab>
<ng-template mat-tab-label>
<mat-icon>palette</mat-icon>&nbsp;<span i18n>Theme</span>
</ng-template>
<div class="flex flex-col gap-4 mt-4 p-3">
<mat-slide-toggle
color="primary"
[(ngModel)]="themeSettings.showComponentTitles"
(ngModelChange)="save()"
i18n
>
Show activity titles
</mat-slide-toggle>
@if (themeSettings.showComponentTitles) {
<mat-slide-toggle
color="primary"
[(ngModel)]="themeSettings.showComponentTypeIcons"
(ngModelChange)="save()"
i18n
>
Show activity type icons
</mat-slide-toggle>
}
</div>
</mat-tab>
<mat-tab>
<ng-template mat-tab-label>
<mat-icon>translate</mat-icon>&nbsp;<span i18n>Language</span>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,29 +1,8 @@
.project-info-authoring {
.project-icon-label {
margin-bottom: 10px;
}

.project-icon-container {
width: 200px;
height: 200px;
display: flex;
align-items: center;
justify-content: center
}

.project-icon {
width: 200px;
}

.project-icon-error {
border: 1px solid black;
padding: 20px;
}

.project-icon-to-choose {
cursor: pointer;
}

.mat-mdc-tab-header {
margin: 0 -16px;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,40 @@ import { provideHttpClient, withInterceptorsFromDi } from '@angular/common/http'
import { UserService } from '../../../../app/services/user.service';
import { MockComponent, MockProviders } from 'ng-mocks';
import { EditProjectLanguageSettingComponent } from '../project-info/edit-project-language-setting/edit-project-language-setting.component';
import { EditUnitResourcesComponent } from '../edit-unit-resources/edit-unit-resources.component';
import { ThemeSettings } from '../../common/ThemeSettings';
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
import { By } from '@angular/platform-browser';

describe('ProjectInfoAuthoringComponent', () => {
let component: ProjectInfoAuthoringComponent;
let fixture: ComponentFixture<ProjectInfoAuthoringComponent>;
let teacherProjectService: TeacherProjectService;

beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [ProjectInfoAuthoringComponent, MockComponent(EditProjectLanguageSettingComponent)],
imports: [
NoopAnimationsModule,
ProjectInfoAuthoringComponent,
MockComponent(EditProjectLanguageSettingComponent),
MockComponent(EditUnitResourcesComponent)
],
providers: [
MockProviders(ConfigService, TeacherProjectService, UserService),
provideHttpClient(withInterceptorsFromDi())
]
}).compileComponents();
spyOn(TestBed.inject(TeacherProjectService), 'getProjectMetadata').and.returnValue({
authors: []

teacherProjectService = TestBed.inject(TeacherProjectService);
spyOn(teacherProjectService, 'getProjectMetadata').and.returnValue({
authors: [],
resources: []
});
spyOn(teacherProjectService, 'getThemeSettings').and.returnValue(new ThemeSettings());
spyOn(teacherProjectService, 'saveProject').and.stub();
spyOn(TestBed.inject(ConfigService), 'getConfigParam').and.returnValue('{ "fields": [] }');
spyOn(TestBed.inject(UserService), 'getUserId').and.returnValue(1);

fixture = TestBed.createComponent(ProjectInfoAuthoringComponent);
component = fixture.componentInstance;
fixture.detectChanges();
Expand All @@ -32,4 +48,52 @@ describe('ProjectInfoAuthoringComponent', () => {
it('should create', () => {
expect(component).toBeTruthy();
});

it('should initialize themeSettings on init', () => {
expect(component['themeSettings']).toBeDefined();
expect(component['themeSettings'].showComponentTitles).toBeTrue();
expect(component['themeSettings'].showComponentTypeIcons).toBeTrue();
});

it('should save project when save is called', () => {
component['save']();
expect(teacherProjectService.saveProject).toHaveBeenCalled();
});

describe('Theme tab slide toggles', () => {
beforeEach(() => {
const tabGroup = fixture.debugElement.query(By.css('mat-tab-group')).componentInstance;
tabGroup.selectedIndex = 1;
fixture.detectChanges();
});

it('should display slide-toggles when theme tab is rendered', () => {
const toggles = fixture.debugElement.queryAll(By.css('mat-slide-toggle'));
expect(toggles.length).toBe(2);
expect(toggles[0].nativeElement.textContent).toContain('Show activity titles');
expect(toggles[1].nativeElement.textContent).toContain('Show activity type icons');
});

it('should hide activity type icons toggle when showComponentTitles is false', () => {
component['themeSettings'].showComponentTitles = false;
fixture.detectChanges();
const toggles = fixture.debugElement.queryAll(By.css('mat-slide-toggle'));
expect(toggles.length).toBe(1);
expect(toggles[0].nativeElement.textContent).toContain('Show activity titles');
});

it('should show activity type icons toggle when showComponentTitles is true', () => {
component['themeSettings'].showComponentTitles = false;
fixture.detectChanges();
expect(fixture.debugElement.queryAll(By.css('mat-slide-toggle')).length).toBe(1);
component['themeSettings'].showComponentTitles = true;
fixture.detectChanges();
expect(fixture.debugElement.queryAll(By.css('mat-slide-toggle')).length).toBe(2);
});

it('should call saveProject when save is invoked from slide toggle change', () => {
component['save']();
expect(teacherProjectService.saveProject).toHaveBeenCalled();
});
});
});
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { Component, ViewEncapsulation } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { MatButtonModule } from '@angular/material/button';
import { MatCheckboxModule } from '@angular/material/checkbox';
import { MatDialog } from '@angular/material/dialog';
import { MatProgressSpinnerModule } from '@angular/material/progress-spinner';
import { MatRadioModule } from '@angular/material/radio';
import { MatSlideToggleModule } from '@angular/material/slide-toggle';
import { Subject, debounceTime } from 'rxjs';
import { ConfigService } from '../../services/configService';
import { TeacherProjectService } from '../../services/teacherProjectService';
Expand All @@ -20,11 +22,13 @@ import { MatIconModule } from '@angular/material/icon';
imports: [
EditProjectLanguageSettingComponent,
EditUnitResourcesComponent,
FormsModule,
MatButtonModule,
MatCheckboxModule,
MatIconModule,
MatProgressSpinnerModule,
MatRadioModule,
MatSlideToggleModule,
MatTabsModule,
TranslatableInputComponent,
TranslatableTextareaComponent
Expand All @@ -42,6 +46,7 @@ export class ProjectInfoAuthoringComponent {
metadataChanged: Subject<void> = new Subject<void>();
projectIcon: string = '';
projectIcons: any = [];
protected themeSettings: any;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Give type?

Suggested change
protected themeSettings: any;
protected themeSettings: ThemeSettings;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Give type?

Suggested change
protected themeSettings: any;
protected themeSettings: ThemeSettings;


constructor(
private configService: ConfigService,
Expand All @@ -50,6 +55,7 @@ export class ProjectInfoAuthoringComponent {
) {}

ngOnInit(): void {
this.themeSettings = this.projectService.getThemeSettings();
this.metadata = this.projectService.getProjectMetadata();
if (this.metadata.resources == null) {
this.metadata.resources = [];
Expand Down Expand Up @@ -237,7 +243,7 @@ export class ProjectInfoAuthoringComponent {
this.isShowProjectIconLoading = true;
}

private save(): void {
protected save(): void {
this.projectService.saveProject();
}
}
9 changes: 9 additions & 0 deletions src/assets/wise5/common/ThemeSettings.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export class ThemeSettings {
hidePossibleScores?: boolean = false;
showComponentTitles?: boolean = true;
showComponentTypeIcons?: boolean = true;

constructor(init?: Partial<ThemeSettings>) {
Object.assign(this, init);
}
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
@if (title || hasPrompt || component.content.maxScore) {
@if (showTitle || hasPrompt || component.content.maxScore) {
<div class="flex justify-between gap-1 mb-4">
<div class="flex flex-col gap-3">
@if (title) {
@if (showTitle) {
<div class="mat-headline-6 primary !mb-0">
<mat-icon class="align-sub">{{ icon }}</mat-icon> {{ title }}
@if (showIcon) {
<mat-icon class="align-sub">{{ icon }}</mat-icon>
}
{{ title }}
</div>
}
@if (hasPrompt) {
Expand Down
Loading