-
Notifications
You must be signed in to change notification settings - Fork 31
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Feature/475/export 3d printer files (#2561)
* WIP: Download stl file #475 * WIP: Add Angular button for 3D file export #475 * WIP: Fix naming issue and Download function #475 * Add material design icons #475 * Fix Stl file download button with correct filename #475 * Fix button size and icon #475 * Revert download button #475 * Fix unused store variable #475 * Fix button look to match other buttons #475 * Add test file #475 * Refactor component file #475 * Refactor and clean up #475 * Add chnagelog entry #475 * Fix css and subscribe issues #475 * fix: re-add style but nest class names ref #475 * test: add basic test for template ref #475 * Fix typo #475 * Improve Tests #475 * Improve test naming #475 Co-authored-by: Torsten Knauf <[email protected]>
- Loading branch information
1 parent
131bed9
commit e744877
Showing
14 changed files
with
188 additions
and
4 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
9 changes: 9 additions & 0 deletions
9
visualization/app/codeCharta/ui/export3DMapButton/export3DMapButton.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 |
---|---|---|
@@ -0,0 +1,9 @@ | ||
<button | ||
mat-mini-fab | ||
class="export-3d-button" | ||
aria-label="3d print map" | ||
(click)="downloadStlFile()" | ||
title="Download stl file for 3D printing" | ||
> | ||
<mat-icon class="button-icon">view_in_ar</mat-icon> | ||
</button> |
26 changes: 26 additions & 0 deletions
26
visualization/app/codeCharta/ui/export3DMapButton/export3DMapButton.component.scss
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,26 @@ | ||
cc-export-threed-map-button { | ||
margin-left: 8px; | ||
.mat-flat-button.mat-accent, | ||
.mat-raised-button.mat-accent, | ||
.mat-fab.mat-accent, | ||
.mat-mini-fab.mat-accent { | ||
background-color: rgb(0, 150, 136); | ||
} | ||
.button-icon { | ||
font-size: 16px; | ||
line-height: 1.3; | ||
} | ||
span { | ||
padding: 0; | ||
margin: 0; | ||
} | ||
.mat-mini-fab { | ||
height: 25px; | ||
width: 25px; | ||
|
||
.mat-button-wrapper { | ||
display: block; | ||
padding: 0; | ||
} | ||
} | ||
} |
64 changes: 64 additions & 0 deletions
64
visualization/app/codeCharta/ui/export3DMapButton/export3DMapButton.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,64 @@ | ||
import { TestBed } from "@angular/core/testing" | ||
import { Export3DMapButtonComponent } from "./export3DMapButton.component" | ||
import { fireEvent, render } from "@testing-library/angular" | ||
import { Export3DMapButtonModule } from "./export3DMapButton.module" | ||
import { FileDownloader } from "../../util/fileDownloader" | ||
import { ThreeSceneService } from "../codeMap/threeViewer/threeSceneService" | ||
import { CodeMapMesh } from "../codeMap/rendering/codeMapMesh" | ||
import { stubDate } from "../../../../mocks/dateMock.helper" | ||
import { FILE_STATES } from "../../util/dataMocks" | ||
|
||
stubDate(new Date(Date.UTC(2018, 11, 14, 9, 39))) | ||
const newDate = "2018-12-14_09-39" | ||
|
||
const mockFileStates = FILE_STATES | ||
|
||
jest.mock("../../state/store/files/files.selector", () => ({ | ||
filesSelector: () => mockFileStates | ||
})) | ||
|
||
jest.mock("../../state/selectors/accumulatedData/accumulatedData.selector", () => ({ | ||
accumulatedDataSelector: () => ({ | ||
unifiedFileMeta: { fileName: "sample" } | ||
}) | ||
})) | ||
|
||
jest.mock("three/examples/jsm/exporters/STLExporter", () => ({ | ||
STLExporter: jest.fn(() => ({ parse: jest.fn().mockImplementation(() => null) })) | ||
})) | ||
|
||
describe("Export3DMapButtonComponent", () => { | ||
beforeEach(() => { | ||
TestBed.configureTestingModule({ | ||
imports: [Export3DMapButtonModule] | ||
}) | ||
}) | ||
|
||
it("should start download on click", async function () { | ||
const { container } = await render(Export3DMapButtonComponent, { excludeComponentDeclaration: true }) | ||
// mock download and therefore only verify the Angular binding. | ||
// A better approach would be, if the component would only fire an action | ||
// and an https://ngrx.io/guide/effects would do the side effect and logic. | ||
// Then we could test the logic in the effect without mocking a lot | ||
// and the component wouldn't need to know anything about store values | ||
// @ts-ignore | ||
const mockedDownload = jest.spyOn(ng.probe(container).componentInstance, "downloadStlFile").mockImplementation(() => null) | ||
|
||
const downloadButton = container.querySelector(".export-3d-button") | ||
expect(downloadButton).not.toBe(null) | ||
|
||
fireEvent.click(downloadButton) | ||
expect(mockedDownload).toHaveBeenCalledTimes(1) | ||
}) | ||
it("should download STL file with the right file name", async function () { | ||
const { container } = await render(Export3DMapButtonComponent, { excludeComponentDeclaration: true }) | ||
const downloadButton = container.querySelector(".export-3d-button") | ||
|
||
const downloadData = jest.spyOn(FileDownloader, "downloadData").mockImplementation(() => null) | ||
ThreeSceneService.mapMeshInstance = { getThreeMesh: jest.fn() } as unknown as CodeMapMesh | ||
|
||
fireEvent.click(downloadButton) | ||
|
||
expect(downloadData).toHaveBeenCalledWith(null, `sample_${newDate}.stl`) | ||
}) | ||
}) |
44 changes: 44 additions & 0 deletions
44
visualization/app/codeCharta/ui/export3DMapButton/export3DMapButton.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,44 @@ | ||
import "./export3DMapButton.component.scss" | ||
import { Component, Inject, OnDestroy } from "@angular/core" | ||
import { FileDownloader } from "../../util/fileDownloader" | ||
import { STLExporter } from "three/examples/jsm/exporters/STLExporter" | ||
import { ThreeSceneService } from "../codeMap/threeViewer/threeSceneService" | ||
import { FileNameHelper } from "../../util/fileNameHelper" | ||
import { isDeltaState } from "../../model/files/files.helper" | ||
import { Store } from "../../state/angular-redux/store" | ||
import { accumulatedDataSelector } from "../../state/selectors/accumulatedData/accumulatedData.selector" | ||
import { filesSelector } from "../../state/store/files/files.selector" | ||
import { FileState } from "../../model/files/files" | ||
import { Mesh } from "three" | ||
|
||
@Component({ | ||
selector: "cc-export-threed-map-button", | ||
template: require("./export3DMapButton.component.html") | ||
}) | ||
export class Export3DMapButtonComponent implements OnDestroy { | ||
private fileName: string | ||
private files: FileState[] | ||
private exporter = new STLExporter() | ||
private storeSubscriptions = [] | ||
constructor(@Inject(Store) store: Store) { | ||
this.storeSubscriptions.push( | ||
store.select(accumulatedDataSelector).subscribe(accumulatedData => { | ||
this.fileName = accumulatedData.unifiedFileMeta?.fileName | ||
}), | ||
store.select(filesSelector).subscribe(files => { | ||
this.files = files | ||
}) | ||
) | ||
} | ||
|
||
downloadStlFile() { | ||
const threeMesh: Mesh = ThreeSceneService.mapMeshInstance.getThreeMesh() | ||
const exportedBinaryFile = this.exporter.parse(threeMesh, { binary: true }) | ||
const fileName = `${FileNameHelper.getNewFileName(this.fileName, isDeltaState(this.files))}.stl` | ||
FileDownloader.downloadData(exportedBinaryFile, fileName) | ||
} | ||
|
||
ngOnDestroy(): void { | ||
for (const subscription of this.storeSubscriptions) subscription.unsubscribe() | ||
} | ||
} |
11 changes: 11 additions & 0 deletions
11
visualization/app/codeCharta/ui/export3DMapButton/export3DMapButton.module.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,11 @@ | ||
import { CommonModule } from "@angular/common" | ||
import { NgModule } from "@angular/core" | ||
import { Export3DMapButtonComponent } from "./export3DMapButton.component" | ||
import { MaterialModule } from "../../../material/material.module" | ||
|
||
@NgModule({ | ||
imports: [CommonModule, MaterialModule], | ||
declarations: [Export3DMapButtonComponent], | ||
exports: [Export3DMapButtonComponent] | ||
}) | ||
export class Export3DMapButtonModule {} |
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
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
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