fixed URL xeokit tries to download attachments from with subdirectory (#8837)

* fixed URL xeokit tries to download attachments from with subdirectory

* DRYing up path to IFC model attachment files in XeokitServer

Also finally typing XeokitServer in TypeScript.

* Cleanup after review:

- Remove unnecessary imports
- Use string interpolation in PathHelper

Co-authored-by: Wieland Lindenthal <w.lindenthal@forkmerge.com>
pull/8851/head
Markus Kahl 4 years ago committed by GitHub
parent 593cc7ad05
commit 4b720c0abb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      frontend/src/app/modules/bim/ifc_models/ifc-viewer/ifc-viewer.service.ts
  2. 1
      frontend/src/app/modules/bim/ifc_models/xeokit/xeokit-server.d.ts
  3. 78
      frontend/src/app/modules/bim/ifc_models/xeokit/xeokit-server.js
  4. 76
      frontend/src/app/modules/bim/ifc_models/xeokit/xeokit-server.ts
  5. 2
      frontend/src/app/modules/common/gon/gon.service.ts
  6. 89
      frontend/src/app/modules/common/path-helper/path-helper.service.ts

@ -47,7 +47,7 @@ export class IFCViewerService extends ViewerBridgeService {
public newViewer(elements:XeokitElements, projects:any[]) {
import('@xeokit/xeokit-bim-viewer/dist/main').then((XeokitViewerModule:any) => {
let server = new XeokitServer();
let server = new XeokitServer(this.pathHelper);
let viewerUI = new XeokitViewerModule.BIMViewer(server, elements);
viewerUI.on("queryPicked", (event:any) => {

@ -1,78 +0,0 @@
import {utils} from "@xeokit/xeokit-sdk/src/viewer/scene/utils";
/**
* Default server client which loads content via HTTP from the file system.
*/
class XeokitServer {
/**
*
* @param cfg
* @param.cfg.dataDir Base directory for content.
*/
constructor(cfg = {}) {
this._dataDir = cfg.dataDir || "";
}
/**
* Gets the manifest of all projects.
* @param done
* @param error
*/
getProjects(done, _error) {
done({ projects: window.gon.ifc_models.projects });
}
/**
* Gets a manifest for a project.
* @param projectId
* @param done
* @param error
*/
getProject(projectData, done, _error) {
var manifestData = {
id: projectData[0].id,
name: projectData[0].name,
models: window.gon.ifc_models.models,
viewerContent: {
modelsLoaded: window.gon.ifc_models.shown_models
},
viewerConfigs: {
saoEnabled: true // Needs to be enabled by default if we want to use it selectively on the available models.
}
};
done(manifestData);
}
/**
* Gets metadata for a model within a project.
* @param projectId
* @param modelId
* @param done
* @param error
*/
getMetadata(_projectId, modelId, done, error) {
const attachmentId = window.gon.ifc_models.metadata_attachment_ids[modelId];
console.log(`Loading model metadata for: ${attachmentId}`);
utils.loadJSON(this.attachmentUrl(attachmentId), done, error);
}
/**
* Gets geometry for a model within a project.
* @param projectId
* @param modelId
* @param done
* @param error
*/
getGeometry(projectId, modelId, done, error) {
const attachmentId = window.gon.ifc_models.xkt_attachment_ids[modelId];
console.log(`Loading model geometry for: ${attachmentId}`);
utils.loadArraybuffer(this.attachmentUrl(attachmentId), done, error);
}
attachmentUrl(attachmentId) {
return "/api/v3/attachments/" + attachmentId + "/content";
}
}
export {XeokitServer};

@ -0,0 +1,76 @@
// @ts-ignore
import {utils} from "@xeokit/xeokit-sdk/src/viewer/scene/utils";
import {PathHelperService} from "../../../common/path-helper/path-helper.service";
import {IFCGonDefinition} from "../pages/viewer/ifc-models-data.service";
/**
* Default server client which loads content via HTTP from the file system.
*/
export class XeokitServer {
private ifcModels:IFCGonDefinition;
/**
*
* @param config
* @param.config.pathHelper instance of PathHelperService.
*/
constructor(private pathHelper:PathHelperService) {
this.ifcModels = window.gon.ifc_models;
}
/**
* Gets the manifest of all projects.
* @param done
* @param error
*/
getProjects(done:Function, _error:Function) {
done({ projects: this.ifcModels.projects });
}
/**
* Gets a manifest for a project.
* @param projectId
* @param done
* @param error
*/
getProject(projectData:any, done:Function, _error:Function) {
var manifestData = {
id: projectData[0].id,
name: projectData[0].name,
models: this.ifcModels.models,
viewerContent: {
modelsLoaded: this.ifcModels.shown_models
},
viewerConfigs: {
saoEnabled: true // Needs to be enabled by default if we want to use it selectively on the available models.
}
};
done(manifestData);
}
/**
* Gets metadata for a model within a project.
* @param projectId
* @param modelId
* @param done
* @param error
*/
getMetadata(_projectId:string, modelId:number, done:Function, error:Function) {
const attachmentId = this.ifcModels.metadata_attachment_ids[modelId];
console.log(`Loading model metadata for: ${attachmentId}`);
utils.loadJSON(this.pathHelper.attachmentContentPath(attachmentId), done, error);
}
/**
* Gets geometry for a model within a project.
* @param projectId
* @param modelId
* @param done
* @param error
*/
getGeometry(projectId:string, modelId:number, done:Function, error:Function) {
const attachmentId = this.ifcModels.xkt_attachment_ids[modelId];
console.log(`Loading model geometry for: ${attachmentId}`);
utils.loadArraybuffer(this.pathHelper.attachmentContentPath(attachmentId), done, error);
}
}

@ -27,6 +27,7 @@
// ++
import {Injectable} from "@angular/core";
import {IFCGonDefinition} from "../../bim/ifc_models/pages/viewer/ifc-models-data.service";
declare global {
interface Window {
@ -36,6 +37,7 @@ declare global {
export interface GonType {
[key:string]:unknown;
ifc_models:IFCGonDefinition;
}
@Injectable({ providedIn: 'root' })

@ -45,10 +45,10 @@ class Apiv3Paths {
* @param context
*/
public previewMarkup(context:string) {
let base = this.apiV3Base + '/render/markdown';
let base = `${this.apiV3Base}/render/markdown`;
if (context) {
return base + `?context=${context}`;
return `${base}?context=${context}`;
} else {
return base;
}
@ -85,7 +85,7 @@ class Apiv3Paths {
@Injectable({ providedIn: 'root' })
export class PathHelperService {
public readonly appBasePath = window.appBasePath ? window.appBasePath : '';
public readonly appBasePath = window.appBasePath || '';
public readonly api = {
v3: new Apiv3Paths(this.appBasePath)
};
@ -95,21 +95,25 @@ export class PathHelperService {
}
public attachmentDownloadPath(attachmentIdentifier:string, slug:string|undefined) {
let path = this.staticBase + '/attachments/' + attachmentIdentifier;
let path = `${this.staticBase}/attachments/${attachmentIdentifier}`;
if (slug) {
return path + "/" + slug;
return `${path}/${slug}`;
} else {
return path;
}
}
public attachmentContentPath(attachmentIdentifier:number|string) {
return `${this.staticBase}/attachments/${attachmentIdentifier}/content`;
}
public ifcModelsPath(projectIdentifier:string) {
return this.staticBase + `/projects/${projectIdentifier}/ifc_models`;
return `${this.staticBase}/projects/${projectIdentifier}/ifc_models`;
}
public bimDetailsPath(projectIdentifier:string, workPackageId:string, viewpoint:number|string|null = null) {
let path = this.projectPath(projectIdentifier) + `/bcf/split/details/${workPackageId}`;
let path = `${this.projectPath(projectIdentifier)}/bcf/split/details/${workPackageId}`;
if (viewpoint !== null) {
path += `?viewpoint=${viewpoint}`;
@ -119,95 +123,95 @@ export class PathHelperService {
}
public highlightingCssPath() {
return this.staticBase + '/highlighting/styles';
return `${this.staticBase}/highlighting/styles`;
}
public forumPath(projectIdentifier:string, forumIdentifier:string) {
return this.projectForumPath(projectIdentifier) + '/' + forumIdentifier;
return `${this.projectForumPath(projectIdentifier)}/${forumIdentifier}`;
}
public keyboardShortcutsHelpPath() {
return this.staticBase + '/help/keyboard_shortcuts';
return `${this.staticBase}/help/keyboard_shortcuts`;
}
public messagePath(messageIdentifier:string) {
return this.staticBase + '/topics/' + messageIdentifier;
return `${this.staticBase}/topics/${messageIdentifier}`;
}
public myPagePath() {
return this.staticBase + '/my/page';
return `${this.staticBase}/my/page`;
}
public newsPath(newsId:string) {
return this.staticBase + '/news/' + newsId;
return `${this.staticBase}/news/${newsId}`;
}
public loginPath() {
return this.staticBase + '/login';
return `${this.staticBase}/login`;
}
public projectsPath() {
return this.staticBase + '/projects';
return `${this.staticBase}/projects`;
}
public projectPath(projectIdentifier:string) {
return this.projectsPath() + '/' + projectIdentifier;
return `${this.projectsPath()}/${projectIdentifier}`;
}
public projectActivityPath(projectIdentifier:string) {
return this.projectPath(projectIdentifier) + '/activity';
return `${this.projectPath(projectIdentifier)}/activity`;
}
public projectForumPath(projectIdentifier:string) {
return this.projectPath(projectIdentifier) + '/forums';
return `${this.projectPath(projectIdentifier)}/forums`;
}
public projectCalendarPath(projectId:string) {
return this.projectPath(projectId) + '/work_packages/calendar';
return `${this.projectPath(projectId)}/work_packages/calendar`;
}
public projectMembershipsPath(projectId:string) {
return this.projectPath(projectId) + '/members';
return `${this.projectPath(projectId)}/members`;
}
public projectNewsPath(projectId:string) {
return this.projectPath(projectId) + '/news';
return `${this.projectPath(projectId)}/news`;
}
public projectTimeEntriesPath(projectIdentifier:string) {
return this.projectPath(projectIdentifier) + '/cost_reports';
return `${this.projectPath(projectIdentifier)}/cost_reports`;
}
public projectWikiPath(projectId:string) {
return this.projectPath(projectId) + '/wiki';
return `${this.projectPath(projectId)}/wiki`;
}
public projectWorkPackagePath(projectId:string, wpId:string|number) {
return this.projectWorkPackagesPath(projectId) + '/' + wpId;
return `${this.projectWorkPackagesPath(projectId)}/${wpId}`;
}
public projectWorkPackagesPath(projectId:string) {
return this.projectPath(projectId) + '/work_packages';
return `${this.projectPath(projectId)}/work_packages`;
}
public projectWorkPackageNewPath(projectId:string) {
return this.projectWorkPackagesPath(projectId) + '/new';
return `${this.projectWorkPackagesPath(projectId)}/new`;
}
public projectBoardsPath(projectIdentifier:string|null) {
if (projectIdentifier) {
return this.projectPath(projectIdentifier) + '/boards';
return `${this.projectPath(projectIdentifier)}/boards`;
} else {
return this.staticBase + '/boards';
return `${this.staticBase}/boards`;
}
}
public projectDashboardsPath(projectIdentifier:string) {
return this.projectPath(projectIdentifier) + '/dashboards';
return `${this.projectPath(projectIdentifier)}/dashboards`;
}
public timeEntriesPath(workPackageId:string|number) {
var suffix = '/time_entries';
let suffix = '/time_entries';
if (workPackageId) {
return this.workPackagePath(workPackageId) + suffix;
@ -217,51 +221,50 @@ export class PathHelperService {
}
public usersPath() {
return this.staticBase + '/users';
return `${this.staticBase}/users`;
}
public userPath(id:string|number) {
return this.usersPath() + '/' + id;
return `${this.usersPath()}/${id}`;
}
public versionsPath() {
return this.staticBase + '/versions';
return `${this.staticBase}/versions`;
}
public versionEditPath(id:string|number) {
return this.staticBase + '/versions/' + id + '/edit';
return `${this.staticBase}/versions/${id}/edit`;
}
public versionShowPath(id:string|number) {
return this.staticBase + '/versions/' + id;
return `${this.staticBase}/versions/${id}`;
}
public workPackagesPath() {
return this.staticBase + '/work_packages';
return `${this.staticBase}/work_packages`;
}
public workPackagePath(id:string|number) {
return this.staticBase + '/work_packages/' + id;
return `${this.staticBase}/work_packages/${id}`;
}
public workPackageCopyPath(workPackageId:string|number) {
return this.workPackagePath(workPackageId) + '/copy';
return `${this.workPackagePath(workPackageId)}/copy`;
}
public workPackageDetailsCopyPath(projectIdentifier:string, workPackageId:string|number) {
return this.projectWorkPackagesPath(projectIdentifier) + '/details/' + workPackageId + '/copy';
return `${this.projectWorkPackagesPath(projectIdentifier)}/details/${workPackageId}/copy`;
}
public workPackagesBulkDeletePath() {
return this.workPackagesPath() + '/bulk';
return `${this.workPackagesPath()}/bulk`;
}
public projectLevelListPath() {
return this.projectsPath() + '/level_list.json';
return `${this.projectsPath()}/level_list.json`;
}
public textFormattingHelp() {
return this.staticBase + '/help/text_formatting';
return `${this.staticBase}/help/text_formatting`;
}
}

Loading…
Cancel
Save