Script Creating Tree based folder structure

Started by bigyin, April 02, 2020, 20:25:49 PM

Previous topic - Next topic

bigyin

Hopefully simple question:

I want to create a folder tree by script.

I get making the the 1st layer (Business,Le Process) following sample script (JArchi) but

a) I want to make sub folders within sub folders and
b) I want to list all sub folders to see if they are already there so as to avoid duplicates

I am new to JArchi, but I cant find the correct API specification commands using selectors etc.

Would be grateful for any pointers.

Jean-Baptiste Sarrodie

Hi,

This example should help you:

//
// Create Subtree
//
// 2019 David GERARD
// 2020 JB Sarrodie
//
// Based on an original work from Jean-Baptiste SARRODIE,
// regarding temporal horizons and plateau management
//
// This script populates the default 'Views' folder of a
// model with a subtree, described in input in JSON, and
// adds the property to the created folders
// 

// # Variables 

//  - The following subtree description in JSON should be
//  externalized
//  - Have to use UTF-8 encoding!
var subtree = [
    {
        "Name": "Enterprise Architecture",
        "Plateau": "Current",
        "SubFolders": [
            {"Name": "Strategic Views",
             "SubFolders": [
                {"Name": "Roadmap",
                 "Plateau": "Target"               
                }
            ]},
            {"Name": "Business Views",
             "SubFolders": [
                {"Name": "Roadmap",
                 "Plateau": "Target"               
                }
            ]}
        ]},
    {
        "Name": "Applications",
        "Plateau": "Current",
        "SubFolders": [{
            "Name": "Usual name – Code from REFI",
            "SubFolders": [
                {"Name": "Roadmap",
                 "Plateau": "Target"               
                }
            ]
        }]},
    {
        "Name": "Projects",
        "Plateau": "Project",
        "SubFolders": [
            {"Name": "Project code – Project name"}
        ]}
];

//  - Find root folder called "Views"
var rootFolder = $(model).children('folder.Views').first(); 

//  - function which creates a folder in a folder and calls
//  itself if recursion is needed
function recursiveFolderCreate(currentRoot, currentArray){
    for(var i in currentArray){
        if (currentArray[i].hasOwnProperty('Name')) {
            //  - Check if a folder with the same name already exists
            var myFolder = $(currentRoot).children('.'+currentArray[i].Name).first();

            //  - If not, then create it
            if (! myFolder){
                myFolder = currentRoot.createFolder(currentArray[i].Name);
            }
           
            // - Set its 'Plateau' property if needed
            if (currentArray[i].Plateau){
                myFolder.prop("Plateau",currentArray[i].Plateau)
            }
        }
        //  - Check if there are folders to create below the current one
        if (currentArray[i].hasOwnProperty('SubFolders')) {
            recursiveFolderCreate(myFolder, currentArray[i].SubFolders);
        }
    }       
}

// # Main 
console.show();
console.clear();
recursiveFolderCreate(rootFolder, subtree);


Regards,

JB
If you value and use Archi, please consider making a donation!
Ask your ArchiMate related questions to the ArchiMate Community's Discussion Board.

bigyin

Thanks for this I used to create the recursive tree to meet the Service framework I wanted.
However having some difficulties, maybe my lack of JScript experience or JArchi, grateful for pointer
1) Folder traversing etc
-   As model setup - Create reference folder structure in each grouping (business, implementation etc) - for manageability aim to keep all elements related to a capability, service etc in defined folder (Folder 1\ Folder 2 \Folder 3 etc
-    Script creates a new service, prompts for information - creates folder for new service (Id), all related element, connections and the related views etc
Problem: I am having difficulty either
a)   putting the pointer in the relevant place in the tree (if below top level) e.g. Business\Folder 1\Folder 2\Folder 3\Service xxx before I create everything
b)   (preferred) Move the folder to a child in the structure, along with all the contents

Jean-Baptiste Sarrodie

Hi,

Quote from: bigyin on April 24, 2020, 15:20:40 PM
a)   putting the pointer in the relevant place in the tree (if below top level) e.g. Business\Folder 1\Folder 2\Folder 3\Service xxx before I create everything

For this you have to go through each folder :

var folder = $(model).children('folder.Business').children('folder.Folder 1').children('folder.Folder 2').children('folder.Folder 3').first();


Quote from: bigyin on April 24, 2020, 15:20:40 PM
b)   (preferred) Move the folder to a child in the structure, along with all the contents

For this you have to get the new target folder and use .add()

var folder = $(model).children('folder.Business').children('folder.Folder 1').first();
var newParent = $(model).children('folder.Business').children('folder.Folder 2').children('folder.Folder 3').first();

// Lead to Business/Folder 2/Folder 3/Folder 1
newParent.add(folder);


Regards,

JB
If you value and use Archi, please consider making a donation!
Ask your ArchiMate related questions to the ArchiMate Community's Discussion Board.

bigyin

Thanks that's a big help.

One or two smaller questions

I can now create the tree and point to where in the tree to put things. I now need to know where I am in teh tree when a user selects the element by mouse.

- if a user has selected an element e.g. a Capability. I can identify by  var cap = $(selection).filter('capability').first();
- How Can I ask where in the folder structure the element selected is.  I tried selection using folder etc without success.

- How Can I get/read the current folder stricture - so I can use your child.child approach as pointer
e.g. I can script as function once I know how to do the discover/read  what childs are there.. I guess into array

Jean-Baptiste Sarrodie

Hi,

Quote from: bigyin on April 25, 2020, 08:42:26 AM
Thanks that's a big help.

Quote from: bigyin on April 25, 2020, 08:42:26 AM
I can now create the tree and point to where in the tree to put things. I now need to know where I am in teh tree when a user selects the element by mouse.

- if a user has selected an element e.g. a Capability. I can identify by  var cap = $(selection).filter('capability').first();
- How Can I ask where in the folder structure the element selected is.  I tried selection using folder etc without success.

Navigating the model is always done through a Collection. In this case you want to use .parent() or .parents():

var cap = //...
var capParentFolder = $(cap).parent().first(); // parent folder
var capParentFolders = $(cap).parents(); // Collection of parent folders hierarchy from the first parent to the root "Strategy" folder


Quote from: bigyin on April 25, 2020, 08:42:26 AM
- How Can I get/read the current folder stricture - so I can use your child.child approach as pointer
e.g. I can script as function once I know how to do the discover/read  what childs are there.. I guess into array

There is no "folder structure" per se. So you have to navigate the tree yourself using .children() and some loop.

Regards,

JB
If you value and use Archi, please consider making a donation!
Ask your ArchiMate related questions to the ArchiMate Community's Discussion Board.

projetnumero9

Hi,
FWIW, we carried on the thought about the folder structure creation and came up with:


// 
// Export Views Subtree to JSON 
// 
// 2020 David GERARD 
// 2020 JB SARRODIE 
// 
// Based on an original work from Jean-Baptiste SARRODIE, 
// 
// This script outputs in the console, 
// the Views subtree, in a .JSON format. 
// It is then intended to be used with Create Subtree.ajs. 
// 
 
// # Variables 
 
var subtree = [] ; 
var i = 0 ; 
 
// Show and clear console 
 
console.show(); 
console.clear(); 
 
// `selection` has to be a folder 
// can be Views or any subfolder as a starting point 
selection.filter("folder").each(function(folder){ 
    var subFolders = $(folder).children("folder"); 
    subFolders.each(function(f) { 
        subtree = exportSubtree(f, subtree, i); 
        i++; 
    }); 
}); 
 
// `JSON.stringify` allows to output hashmaps 
// in a readable string 
console.log(JSON.stringify(subtree)); 
 
// # Functions 
 
function exportSubtree(currentFolder, currentSubtree, indx){ 
    currentSubtree[indx] = { "Name" : currentFolder.name } ; 
    var currentSubFolders = $(currentFolder).children("folder"); 
    // Test if object is empty 
    if (!(currentSubFolders.isEmpty())){ 
        j=0; 
        currentSubtree[indx].SubFolders = {} ; 
        var tempSubtree = [] ; 
        currentSubFolders.each(function(f) { 
             tempSubtree = exportSubtree(f, tempSubtree, j); 
            j++; 
        }); 
        currentSubtree[indx].SubFolders = tempSubtree ; 
    } 
    indx++; 
    return currentSubtree; 



The exported folder structure does not include the properties, though.
Regards,

bigyin

Great addition t the tool box. Creating the JSON manually was a pain  :) :)