Product

 View Only

[Workaround] Filter on location/release in embedded filters and have multi-level embedded filters

  • 1.  [Workaround] Filter on location/release in embedded filters and have multi-level embedded filters

    Posted 10-17-2022 14:02
    Edited by Jan Kastning 10-18-2022 00:32

    Hi all,

    I am not sure if someone already posted this, but I though sharing this might help some of you:

    Although the Jama GUI is not capable of using the location or release field in embedded filters or embedding filters over multiple levels, the rest of Jama seems to be capable of doing so.

    If you create a new filter and click on "View in list" Jama will use the search query in the site address / URL. This query can be altered to filter on location/release on embedded filters and also embed filters over multiple levels.

    See the following example where all "A"-items are linked togeter and also all "B"-items (CR A -> CUS A -> ... -> SWUD A -> SWUT A) over 8 layers total:

    Basically, I altered the search query to filter for:
    CR with location under <project root node> and which has downlink to CUS which has downlink to SYRA which ... has downlink to SWUD which has downlinkt to SWUT which is in Folder A.


    This also works for releases in embedded filter. When changing the query to "... has downlink to SWUT which is in Folder A or is in release XYZ" and "CR B" being release "XYZ", both items are shown:

    Because I don't think doing this manually is a good idea, please see the following python script I wrote (See this site if you do not have python installed). You just have to fill in the BaseLink (top most filter search query = URL in your browser when you hit "View in List" on a new filter) and the list of replacments (replacing from top to bottom). For each embedded query you have to do the same process as for the base link (you can use the full URL). For location/release embedding: The API ID of an item can be found in the URL when clicking on an item:

    Your unique replacement text (e.g., JAMA_REPLACE_MEx) must be in a name field with "contains word"-logic:


    The script will output the link for your search query.
    Please have mercy regarding my coding style.. I am not a software engineer ;)

    #Create the filter search query and for any field you want to be replaced use the field "Name" + "contains word" + a unique word (e.g. "JAMA_REPLACE_MEx").
    
    #Top most search query
    BaseLink = "QUERY LINK HERE"
    
    #Put any replacement here, columns:
    #1: Type of replacement ("Embed", "Release" or "Location")
    #2: Text to know which field to replace
    #3: API ID of parent item for "Location" or "Release" | Full link including search query for "Embed"
    Replacements = [
                    ["Embed","JAMA_REPLACE_ME1","QUERY LINK HERE"]
                    ,["Embed","JAMA_REPLACE_ME2","QUERY LINK HERE"]
                    ,["Embed","JAMA_REPLACE_ME3","QUERY LINK HERE"]
                    ,["Embed","JAMA_REPLACE_ME4","QUERY LINK HERE"]
                    ,["Embed","JAMA_REPLACE_ME5","QUERY LINK HERE"]
                    ,["Embed","JAMA_REPLACE_ME6","QUERY LINK HERE"]
                    ,["Location","JAMA_REPLACE_ME7","API ID HERE"]
                    ,["Release","JAMA_REPLACE_ME8","API ID HERE"]
                   ]
    
    #Jama properties for location/release field, might be different on your Jama installation
    LocationField_Id = "2005"
    LocationField_DataType = "1007"
    LocationField_Type = "3"
    ReleaseField_Id = "260"
    ReleaseField_DataType = "7"
    ReleaseField_Type = "1"
    
    #The variable OutputLink is altered according to the Replacements list above in the given order:
    OutputLink = BaseLink
    for row in Replacements:
        if row[0] == "Location":
            #Find position of value to be replaced in link text
            ReplacementIndex_Value_Start = OutputLink.find(row[1])
            #Find respective search field
            ReplacementIndex_Field_Start = OutputLink.rfind("%22field%22%3A%7B%22id%22",0,ReplacementIndex_Value_Start) + 17   #Search for     "field":{"id"
            ReplacementIndex_Field_End = OutputLink.rfind("%7D%2C%22operator%22%3A",0,ReplacementIndex_Value_Start) + 0        #Search for     },"operator":
            #Build replacement field (location)
            LocationFieldReplacementText = "%22id%22%3A"+LocationField_Id+"%2C"
            LocationFieldReplacementText += "%22name%22%3A%22parent%22%2C"
            LocationFieldReplacementText += "%22display%22%3A%22Location%22%2C"
            LocationFieldReplacementText += "%22fieldDataType%22%3A"+LocationField_DataType+"%2C"
            LocationFieldReplacementText += "%22type%22%3A"+LocationField_Type
            #Find CONTAINS_WORD operator and replace with IS_UNDER operator
            StartIndex_CONTAINSWORD = OutputLink.find("CONTAINS_WORD",ReplacementIndex_Field_End)
            EndIndex_CONTAINSWORD = StartIndex_CONTAINSWORD + 13                                                                #13 = Lenght of CONTAINS_WORD
            OutputLink = OutputLink[:StartIndex_CONTAINSWORD] + "IS_UNDER" + OutputLink[EndIndex_CONTAINSWORD:]  
            #Rebuild search query by 
            OutputLink = OutputLink[:ReplacementIndex_Field_Start] + LocationFieldReplacementText + OutputLink[ReplacementIndex_Field_End:]
            
            #Replace first occurence JAMA_REPLACE_MEx with parent item ID
            OutputLink = OutputLink.replace(row[1],row[2],1)
    
        elif row[0] == "Release":
            #Find position of value to be replaced in link text
            ReplacementIndex_Value_Start = OutputLink.find(row[1])
            #Find respective search field
            ReplacementIndex_Field_Start = OutputLink.rfind("%22field%22%3A%7B%22id%22",0,ReplacementIndex_Value_Start) + 17   #Search for     "field":{"id"
            ReplacementIndex_Field_End = OutputLink.rfind("%7D%2C%22operator%22%3A",0,ReplacementIndex_Value_Start) + 0        #Search for     },"operator":
            #Build replacement field (location)
            ReleaseFieldReplacementText = "%22id%22%3A"+ReleaseField_Id+"%2C"
            ReleaseFieldReplacementText += "%22name%22%3A%22release%22%2C"
            ReleaseFieldReplacementText += "%22display%22%3A%22Release%22%2C"
            ReleaseFieldReplacementText += "%22fieldDataType%22%3A"+ReleaseField_DataType+"%2C"
            ReleaseFieldReplacementText += "%22type%22%3A"+ReleaseField_Type
            #Find CONTAINS_WORD operator and replace with IS_UNDER operator
            StartIndex_CONTAINSWORD = OutputLink.find("CONTAINS_WORD",ReplacementIndex_Field_End)
            EndIndex_CONTAINSWORD = StartIndex_CONTAINSWORD + 13                                                                #13 = Lenght of CONTAINS_WORD
            OutputLink = OutputLink[:StartIndex_CONTAINSWORD] + "EQUALS" + OutputLink[EndIndex_CONTAINSWORD:]  
            #Rebuild search query by 
            OutputLink = OutputLink[:ReplacementIndex_Field_Start] + ReleaseFieldReplacementText + OutputLink[ReplacementIndex_Field_End:]
            
            #Replace first occurence JAMA_REPLACE_MEx with release item ID
            OutputLink = OutputLink.replace(row[1],row[2],1)
    
        elif row[0] == "Embed":
            #Find position of value to be replaced in link text
            ReplacementIndex_Value_Start = OutputLink.find(row[1])
            #Find start of respective search field
            ReplacementIndex_Field_Start = OutputLink.rfind("%5B%7B%22parentId%22%3A",0,ReplacementIndex_Value_Start) + 6       #Search for     [{"parentId":
            #Find end of respective search field (closing curly bracket)
            curindex = OutputLink.find("%7B",ReplacementIndex_Field_Start-3)
            opencounter = 1
            while opencounter > 0:
                index_nextopen = OutputLink.find("%7B",curindex+3)
                index_nextclose = OutputLink.find("%7D",curindex+3)
                if index_nextopen < index_nextclose:
                    curindex = index_nextopen
                    opencounter += 1
                else:
                    curindex = index_nextclose
                    opencounter -= 1
            ReplacementIndex_Field_End = curindex
            #Extract replacement query from given filter link
            EmbedFilterLink = row[2]
            ReplacerIndex_Field_Start = EmbedFilterLink.find("%22parentId%22%3A2",0)    #Search for "parentID":2
            #Find end of block (closing curly bracket)
            curindex = EmbedFilterLink.find("%7B",ReplacerIndex_Field_Start-3)
            opencounter = 1
            while opencounter > 0:
                index_nextopen = EmbedFilterLink.find("%7B",curindex+3)
                index_nextclose = EmbedFilterLink.find("%7D",curindex+3)
                if index_nextopen < index_nextclose:
                    curindex = index_nextopen
                    opencounter += 1
                else:
                    curindex = index_nextclose
                    opencounter -= 1
            ReplacerIndex_Field_End = curindex        
            
            OutputLink = OutputLink[:ReplacementIndex_Field_Start] + EmbedFilterLink[ReplacerIndex_Field_Start:ReplacerIndex_Field_End] + OutputLink[ReplacementIndex_Field_End:]
    
        else:
            #Ignore row
            pass
    
    print(OutputLink)​

    Please note:
    • You should filter on location (e.g., project root node) at least on the top level filter otherwise Jama will give you all results over all projects in your Jama instance.
    • In the script you can only check for "is under" or "is in release" for now, but checking for e.g., "is not under" is not that complicated. I will try to add this until end of this week.
    • I did not care about the id and parent id attribute in the filter query. Fortunately, it works in our Jama (. If you have any troubles with this working in your Jama, maybe check the id's first.
    • In theory the other attributes of a filter should not be impacted by the script, but I didn't run any tests on more complex filters. Please feel free to share your expierence with the script.
    • You can still edit the top level filter but if you try to edit the embedded filter you will receive the following prompt
    • The best part: You can actually save the filter with the altered embedded filters! It seems it's just the Jama GUI not being able to handle this process. Just open the filter link, click on "View to edit" and save the filter.

    Hope this helps some of you, any feedback is welcome!

    BR,
    Jan

    ------------------------------
    Jan Kastning
    System Engineer
    Panasonic Industrial Devices Europe GmbH
    ------------------------------