Forge Viewer_New model browser_Linked rvt files - autodesk-forge

Thank you all in advance for your help.
My problem is that in the model browser I can't see the elements organized by model. They are all seen together in no order. I have been able to load linked files via jobpayload with rootFilename. I have seen a lot of information about it but if someone has done it or has an idea of how to do it, I would greatly appreciate the help or start. All the best.

If the model is a composite Revit model translation, the host and linked RVT files are translated by a zip package, the model structure will be merged into a single tree, so it won't organize the tree structure by models.
However, we can tell which object is from the linked RVT. See the concept here:
https://stackoverflow.com/a/64672951
and here is a code example that I use this function to get their dbIds.
async getRevitLinkedElementIds(rvtLinkExternalIds, model) {
const modelKey = model.getModelKey();
const externalIdMap = this.modelExternalIdMaps[modelKey];
const entities = Object.entries(externalIdMap);
const linkedElementIds = rvtLinkExternalIds.map(instanceId => {
return entities.filter(entity => entity[0].includes(`${instanceId}/`)).map(entity => entity[1]);
})
.flat();
return linkedElementIds;
}
I think you can make use of the linkedElementIds, and then call model.getInstanceTree().getNodeParentId( dbId ) repeatedly until you get the root node id, so that you can get name of non-leaf nodes, e.g., Family Type, Family, and Category, to rebuild your own tree nodes using jstree.js. (Don't use non-leaf nodes' dbIds, since they are shared by the host and linked contents)
Afterward, you can build node data of the jstree.js like this for each models (host and links) to expand the tree structure of my custom panel in the code example.
[
{ id1, externalId: -1, type: 'revit-category', text: 'Curtain Panels' },
{ id2, externalId: -1, type: 'revit-family', text: 'System Panel' },
{ id3, externalId: -1, type: 'revit-family-type', text: 'Glazed' },
{ id4, externalId: '03d1b04e-ba90-4a0e-8fe2-eca95236e26a/ab343b7e-3705-4b87-bacc-33c06a6cee1d-000ee82e', type: 'revit-elements', text: 'System Panel [976942]' }
]

Related

Storing a Json value Security Threads using wordpress plugin

I'm performing an audit against OASP best practices, my goal is to identify all major security threads happening when I send the data from the frontend until it is saved in the database.
Context.
Json Data: It's a tree that grows/decreases according to the UI action, the JSON is formatting for a frontend function.
Frontend: custom UI, it generates a list of team members in a JS object and appends/removes from it, the data input is not stored in any HTML elements to prevent XSS, however not sure if there is any potential XSS in the code:
Function to create the element:
const newTeam = {
name,
emoji,
parent_id: parentTeamId,
children: [],
};
const newTree = insertTeam( newTeam );
Function to add the element to the nested groups:
export function insertTeam( team, root = tree ) {
if ( root.id === team.parent_id ) {
return {
...root,
children: [
...root.children,
{
...team,
// Using a simple time based ID for now.
id: `${ root.id }-${ Date.now() }`,
},
],
};
}
return {
...root,
children: root.children.map( ( childTree ) =>
insertTeam( team, childTree )
),
};
}
the data is stored in a hidden field in a form, the final format looks like this:
Var_Dump
string(756) "{\"id\":1,\"name\":\"MyCustomGroup.\",\"emoji\":\"πŸ•\",\"parent_id\":null,\"children\":[{\"id\":2,\"name\":\"Food\",\"emoji\":\"πŸ₯©\",\"parent_id\":1,\"children\":[]},{\"id\":3,\"name\":\"Canine Therapy\",\"emoji\":\"😌\",\"parent_id\":1,\"children\":[{\"id\":5,\"name\":\"Games\",\"emoji\":\"🎾\",\"parent_id\":3,\"children\":[{\"name\":\"rocket\",\"emoji\":\"πŸš€\",\"parent_id\":5,\"id\":\"5-1632455609334\",\"children\":[]}]}]},{\"name\":\"frog\",\"emoji\":\"🐸\",\"parent_id\":1,\"id\":\"1-1632456503102\",\"children\":[]},{\"name\":\"bear\",\"emoji\":\"🐻\",\"parent_id\":1,\"id\":\"1-1632456578430\",\"children\":[{\"name\":\"a\",\"emoji\":\"a\",\"parent_id\":\"1-1632456578430\",\"children\":[],\"id\":\"1-1632456578430-1632665530415\"}]}]}"
The backend: The backend is a Wordpress plugin, to insert the data I'm using $wpdb->insert process the string passed and for cleanup / sanitize I'm using:
wp_kses( $obj, array() )
I'm not an expert in security, but I can detect threads for XSS attacks, what else I'm missing? Also if you guys have some recommendations are welcome. Thanks.
OWASP security standards, as its name suggests, are only a compilation of standards security checks for web applications. In fact, the npm audit command check for outdated dependencies or known issues. That command doesn't accomplish an audit on the fly. Security issues are raised from several sources, like Node
I think you should try something like sonarqube
it's a great test tool and you can start from there

How can i get the list of link files from a translated compressed/zip of revit file?

I have translated a revit file with several link files. From viewer i can browse all elements from the root revit model including all elements from link files using 'Model Browser' default extension. Even i also created a custom extension from where i can isolate each object type's all elements.
Now, i want to create a extension like 'Model Browser', which will show Root file name as top or parent node and all link file's name as child node.I also want, by clicking each link file, all elements from that link file should isolate in the viewer and by clicking Root file, all elements including all link files elements should show .
For information, my application is built using C# and JavaScript in .Net platform.
Can anyone advice me which api, i can try? It would be also very helpful if someone share examples or url where i can get help.
Thanks in advance!
You can take advantage of the AecModelData to get linked models data and rebuild relationships from the PropertyDB inside Forge Viewer.
If an object is from the linked RVT, you can check its' external id. If the external id contains a slash symbol, then this means it is from a linked RVT. Here is an example:
Object extetnal id: ffa0b0a8-8aab-48f9-beb5-dba5d9b4968f-0010cfee/e021b7a9-1e57-428c-87db-8e087322cd49-0015a0f6
An instanceId from the linkedDocuments in the AECModelData: ffa0b0a8-8aab-48f9-beb5-dba5d9b4968f-0010cfee
You can see the GUID on the left side of the slash symbol matches the instance id mentioned above.
To get the linked RVT model name, we can reuse the instanceId from the linkedDocuments of the AECModelData to get the information we need again. Here is a code snippet for you, and assume the instance id is ffa0b0a8-8aab-48f9-beb5-dba5d9b4968f-0010cfee:
function getExternalIdMappingAsync( model ) {
return new Promise( ( resolve, reject ) => {
model.getExternalIdMapping(
map => resolve( map ),
error => reject( error )
);
});
}
function getPropertiesAsync( dbId, viewer ) {
return new Promise( ( resolve, reject ) => {
viewer.getProperties(
dbId,
result => resolve( result ),
error => reject( error )
);
});
}
//1. Get external id mapping for converting external id to Viewer's dbId
let externalIdMapping = await getExternalIdMappingAsync( viewer.model );
let dbId = externalIdMapping['ffa0b0a8-8aab-48f9-beb5-dba5d9b4968f-0010cfee'];
//2. Get properties of the linked model instance
let propResult = await getPropertiesAsync( dbId, viewer )
//3. Find the type name property for its value
let linkNameProp = propResult.properties.find( prop => prop.displayName == 'Type Name' || prop.attributeName == 'Type Name' );
let linkName = linkNameProp.displayValue; //!<<< This is linked RVT name
Here is the snapshot of my test:
Hope it helps~

How to create multiple pages from single json files in Gatsby

I am new to node.js and react but I love gatsby.js. I have followed all the tutorials that I can find and it's such a great tool.
However one of the main reasons why I want to use it is I have a file json with 1000 different records in and I would like to generate a new page for each record.
I believe I have come to the conclusion that I need to learn more about the gatsby-node.js file and am aware of the following resource but are there any tutorials or other examples on this topic that maybe a little easier to follow:
https://www.gatsbyjs.org/docs/creating-and-modifying-pages/#creating-pages-in-gatsby-nodejs
The example you were referring to should already give you a good idea. The basic concept is to import the JSON file, loop over it and run createPage for each of the items in your JSON source. So given an example source file like:
pages.json
[{
"page": "name-1"
}, {
"page": "name-2"
}]
You can then use the Node API to create pages for each:
gatsby-node.js
const path = require('path');
const data = require('./pages.json');
exports.createPages = ({ boundActionCreators }) => {
const { createPage } = boundActionCreators;
// Your component that should be rendered for every item in JSON.
const template = path.resolve(`src/template.js`);
// Create pages for each JSON entry.
data.forEach(({ page }) => {
const path = page;
createPage({
path,
component: template,
// Send additional data to page from JSON (or query inside template)
context: {
path
}
});
});
};

Sending complex JSON with fetch, save, and delete on a model or collection

We have an internal API that was specifically built to be used with a new piece of software I'm building that runs on Backbone. The API has a single URL and takes JSON as input to determine what it needs to return. It essentially allows me to build custom queries with JSON that return exactly what I'm looking for.
Thing is this JSON can get pretty verbose and is often 3–4 levels deep, but sometimes may just be a few lines and just 1 level deep.
First question first: How do I send a string of JSON along with the ID when I do a fetch()? Do I have to set these parameters as the model or collection's defaults?
Here is an example of a really simple string to get a specific user's info
{
"which" : "object",
"object" : {
"type" : "customer",
"place" : "store",
"customerID" : "14"
}
}
As others have suggested it will likely be challenging to work with SOAP, but it shouldn't be impossible. Backbone models and collections communicate with the server through the sync operation; you should be able to customize that. I think something along these lines might get the ball rolling (for models):
Backbone.SoapyModel = Backbone.Model.extend({
sync: function(method, model, options) {
// force POST for all SOAP calls
method = 'create';
options = _.extend(options, {
// Setting the data property will send the model's state
// to the server. Add whatever complexity is needed here:
data: JSON.stringify({
"which" : "object",
"object" : model.toJSON()
}),
// Set the request's content type
contentType: 'application/json'
});
// Defer the rest to Backbone
return Backbone.sync.apply(this, [method, model, options]);
}
});
var SoapyModelImpl = Backbone.SoapyModel.extend({
url: '/test'
});
var soapTest = new SoapyModelImpl({
id: 42,
name: 'bob',
address: '12345 W Street Dr',
phone: '867 5304'
});
soapTest.fetch();

EXTJS 3.4 Load JSON data into a TREE dynamically

I need to load JSON data into a Tree or TreePanel.
The JSON data does not come from a file or retrived from a URL but is built on the fly.
I cannot find any examples.
Can anyone help?
While I was trying to create a Treegrid afetr searching something in a search filed (need to pass this in the URL) i found some strange behaviour.
How I created here is the logic:
Created a Tree class with rootVisible: false and store:mystore
My store has no proxy{} as I had to set this dynamically from controller
Inside the store autoLoad:false was there
Used mystore.load() to load the data into tree
Request was going for 2 times
A blank root node in the tree although I have no root node.
I fixed it in the following way... not sure to wat extend this is correct. Any better solution please share
Tree class(View)
Didn’t define any treestore inside tree view
rootVisible: false
Inside the controller
search: function(button){
var searchText = this.getSearchField().value;
//created a store instance
var mystore = Ext.data.StoreManager.lookup('MyTreeStore');
mystore.setProxy({
type: 'ajax',
url: 'app/searchid/'+searchText;
});
var mytree = Ext.create('AM.view.MyTree',{store:mystore});
Ext.getCmp('tn').add(mytree);
//DON’T USE store.load() method As we have set rootVisible: false so it will automatically try to load the store or will send the request
}
Store file
Ext.define('AM.store.BomTreeStore', {
extend: 'Ext.data.TreeStore',
model: 'AM.model.BomTree',
autoLoad: false,
folderSort: true
});
Any better solution to this plz share :)
You can do it by progammatically creating a root node.
Iterate through your data and keep appending child nodes to your root node.
It has been explained quite well here:
ExtJS: How to create static and dynamic trees