-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(NodeAuthoring): Toggle Edit/Preview component (#1994)
Co-authored-by: Jonathan Lim-Breitbart <[email protected]>
- Loading branch information
1 parent
00ea8b6
commit 5ceb195
Showing
31 changed files
with
552 additions
and
889 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
88 changes: 54 additions & 34 deletions
88
src/assets/wise5/authoringTool/components/component-authoring.component.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,45 +1,65 @@ | ||
import { | ||
ApplicationRef, | ||
Component, | ||
ComponentRef, | ||
ElementRef, | ||
EnvironmentInjector, | ||
Input, | ||
ViewChild, | ||
createComponent | ||
} from '@angular/core'; | ||
import { Component, EventEmitter, Input, Output } from '@angular/core'; | ||
import { ComponentContent } from '../../common/ComponentContent'; | ||
import { components } from '../../components/Components'; | ||
import { PreviewComponentComponent } from './preview-component/preview-component.component'; | ||
import { EditComponentComponent } from './edit-component/edit-component.component'; | ||
import { ComponentFactory } from '../../common/ComponentFactory'; | ||
import { Component as WISEComponent } from '../../common/Component'; | ||
import { TeacherProjectService } from '../../services/teacherProjectService'; | ||
import { MatTooltipModule } from '@angular/material/tooltip'; | ||
|
||
@Component({ | ||
imports: [PreviewComponentComponent, EditComponentComponent, MatTooltipModule], | ||
selector: 'component-authoring', | ||
standalone: true, | ||
template: '<div #component></div>' | ||
styles: [ | ||
` | ||
preview-component { | ||
display: block; | ||
position: relative; | ||
cursor: pointer; | ||
} | ||
preview-component:hover { | ||
outline: 3px dashed #aaaaaa; | ||
outline-offset: 8px; | ||
} | ||
preview-component:after { | ||
content: ''; | ||
position: absolute; | ||
top: 0; | ||
left: 0; | ||
right: 0; | ||
bottom: 0; | ||
} | ||
` | ||
], | ||
template: `@if (editing) { | ||
<edit-component [componentContent]="componentContent" [nodeId]="nodeId" /> | ||
} @else { | ||
<preview-component | ||
role="button" | ||
tabindex="0" | ||
(click)="editComponentEvent.emit()" | ||
(keyup.enter)="editComponentEvent.emit()" | ||
[component]="component" | ||
[disabled]="true" | ||
matTooltip="Edit content" | ||
i18n-matTooltip | ||
/> | ||
}` | ||
}) | ||
export class ComponentAuthoringComponent { | ||
@Input() private componentContent: ComponentContent; | ||
@ViewChild('component') private componentElementRef: ElementRef; | ||
private componentRef: ComponentRef<any>; | ||
@Input() private nodeId: string; | ||
protected component: WISEComponent; | ||
@Input() componentContent: ComponentContent; | ||
@Input() editing: boolean; | ||
@Output() editComponentEvent: EventEmitter<void> = new EventEmitter<void>(); | ||
@Input() nodeId: string; | ||
|
||
constructor( | ||
private applicationRef: ApplicationRef, | ||
private injector: EnvironmentInjector | ||
) {} | ||
constructor(private projectService: TeacherProjectService) {} | ||
|
||
ngAfterViewInit(): void { | ||
this.componentRef = createComponent(components[this.componentContent.type].authoring, { | ||
hostElement: this.componentElementRef.nativeElement, | ||
environmentInjector: this.injector | ||
}); | ||
Object.assign(this.componentRef.instance, { | ||
componentContent: this.componentContent, | ||
nodeId: this.nodeId | ||
}); | ||
this.applicationRef.attachView(this.componentRef.hostView); | ||
} | ||
|
||
ngOnDestroy(): void { | ||
this.componentRef.destroy(); | ||
ngOnChanges(): void { | ||
this.component = new ComponentFactory().getComponent( | ||
this.projectService.injectAssetPaths(this.componentContent), | ||
this.nodeId | ||
); | ||
} | ||
} |
75 changes: 75 additions & 0 deletions
75
src/assets/wise5/authoringTool/components/edit-component/edit-component.component.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
import { ComponentFixture, TestBed } from '@angular/core/testing'; | ||
import { EditComponentComponent } from './edit-component.component'; | ||
import { Component } from '@angular/core'; | ||
import { components } from '../../../components/Components'; | ||
import { ComponentContent } from '../../../common/ComponentContent'; | ||
|
||
@Component({ | ||
selector: 'mock-authoring', | ||
template: '<div>Mock Authoring Component</div>' | ||
}) | ||
class MockAuthoringComponent { | ||
componentContent: any; | ||
nodeId: string; | ||
} | ||
|
||
describe('EditComponentComponent', () => { | ||
let component: EditComponentComponent; | ||
let fixture: ComponentFixture<EditComponentComponent>; | ||
const mockComponentContent = { | ||
type: 'mockComponent' | ||
}; | ||
const mockNodeId = 'node1'; | ||
|
||
beforeEach(async () => { | ||
components['mockComponent'] = { | ||
authoring: MockAuthoringComponent | ||
}; | ||
|
||
await TestBed.configureTestingModule({ | ||
imports: [EditComponentComponent] | ||
}).compileComponents(); | ||
|
||
fixture = TestBed.createComponent(EditComponentComponent); | ||
component = fixture.componentInstance; | ||
component.componentContent = mockComponentContent as ComponentContent; | ||
component.nodeId = mockNodeId; | ||
fixture.detectChanges(); | ||
}); | ||
|
||
it('should create', () => { | ||
expect(component).toBeTruthy(); | ||
}); | ||
|
||
it('should create the dynamic component after view init', () => { | ||
component.ngAfterViewInit(); | ||
fixture.detectChanges(); | ||
const componentElement = fixture.nativeElement.querySelector('div'); | ||
expect(componentElement.textContent).toContain('Mock Authoring Component'); | ||
}); | ||
|
||
it('should pass inputs to the dynamic component', () => { | ||
component.ngAfterViewInit(); | ||
fixture.detectChanges(); | ||
const componentInstance = (component as any).componentRef.instance; | ||
expect(componentInstance.componentContent).toBe(mockComponentContent); | ||
expect(componentInstance.nodeId).toBe(mockNodeId); | ||
}); | ||
|
||
it('should destroy the component reference on destroy', () => { | ||
component.ngAfterViewInit(); | ||
const destroySpy = spyOn((component as any).componentRef, 'destroy'); | ||
component.ngOnDestroy(); | ||
expect(destroySpy).toHaveBeenCalled(); | ||
}); | ||
|
||
it('should focus the host element after timeout', (done) => { | ||
component.ngAfterViewInit(); | ||
fixture.detectChanges(); | ||
setTimeout(() => { | ||
const hostElement = fixture.nativeElement.querySelector('div'); | ||
expect(document.activeElement).toBe(hostElement); | ||
done(); | ||
}, 0); | ||
}); | ||
}); |
47 changes: 47 additions & 0 deletions
47
src/assets/wise5/authoringTool/components/edit-component/edit-component.component.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
import { | ||
ApplicationRef, | ||
Component, | ||
ComponentRef, | ||
ElementRef, | ||
EnvironmentInjector, | ||
Input, | ||
ViewChild, | ||
createComponent | ||
} from '@angular/core'; | ||
import { ComponentContent } from '../../../common/ComponentContent'; | ||
import { components } from '../../../components/Components'; | ||
|
||
@Component({ | ||
selector: 'edit-component', | ||
standalone: true, | ||
template: '<div #component tabindex="-1"></div>' | ||
}) | ||
export class EditComponentComponent { | ||
@Input() componentContent: ComponentContent; | ||
@ViewChild('component') private componentElementRef: ElementRef; | ||
private componentRef: ComponentRef<any>; | ||
@Input() nodeId: string; | ||
|
||
constructor( | ||
private applicationRef: ApplicationRef, | ||
private injector: EnvironmentInjector | ||
) {} | ||
|
||
ngAfterViewInit(): void { | ||
const hostElement = this.componentElementRef.nativeElement; | ||
this.componentRef = createComponent(components[this.componentContent.type].authoring, { | ||
hostElement: hostElement, | ||
environmentInjector: this.injector | ||
}); | ||
Object.assign(this.componentRef.instance, { | ||
componentContent: this.componentContent, | ||
nodeId: this.nodeId | ||
}); | ||
this.applicationRef.attachView(this.componentRef.hostView); | ||
setTimeout(() => hostElement.focus()); | ||
} | ||
|
||
ngOnDestroy(): void { | ||
this.componentRef.destroy(); | ||
} | ||
} |
10 changes: 0 additions & 10 deletions
10
...authoringTool/components/preview-component-button/preview-component-button.component.html
This file was deleted.
Oops, something went wrong.
31 changes: 0 additions & 31 deletions
31
...5/authoringTool/components/preview-component-button/preview-component-button.component.ts
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
8 changes: 5 additions & 3 deletions
8
.../wise5/authoringTool/concurrent-authors-message/concurrent-authors-message.component.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
<div class="warn"> | ||
<b>{{ message }}</b> | ||
</div> | ||
@if (message) { | ||
<div class="concurrent-authors"> | ||
<b class="warn">{{ message }}</b> | ||
</div> | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.