Sunday, June 4, 2017

IBM Content Navigator Known Issues

Bug in resize of ecm.widget.FolderTree


noticed a bug in the FolderTree widget. It is setting its size based on the first ancestor widget, not parent dom node. That means if your FolderTree is in a div or anything not widget, it will take the size of the first ancestor widget, which can be a lot bigger than the dom element it is in and give you some weird behavior.
To fix this, wrap it in a BorderContainer, ContentPane or any sort of widget, or override the resize method to behave nicely with your configuration.
Here is the source of the issue, in the ecm.widget.FolderTree class:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/**
 * Resizes the tree.
 */
resize: function() {
    var pn = this.getParent();
    if (pn) {
        if (pn.titleBarNode != null) {
            domGeom.setMarginBox(this.domNode, domGeom.getContentBox(pn.containerNode));
        } else {
            domGeom.setMarginBox(this.domNode, domGeom.getContentBox(pn.domNode));
        }
    }
    if (this._tree && this._tree.domNode) {
        this._tree.resize(domGeom.getMarginBox(this.domNode));
    }
}
The this.getParent() is returning the first widget ancestor, so it will act nicely if your widget is directly in another widget (as you can see it knows how to deal with widget having a container node). But if like me, you added it in some nested div in a dialog, the first widget parent is the dialog itself, and it will set the size based on the dialog instead of the content area (which is a dojo attach-point), which is way to big. For my use case, I fixed it the following way:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
this.folderTree.resize = function () {
    var pn = this.getParent();
    // pn in our case is the BaseDialog widget, and we know our FolderTree
    // widget is the only one in the contentArea node, so we can fit the
    // whole space in the contentArea, of course that's really specific
    if (pn && pn.contentArea) {
        var box = domGeom.getContentBox(pn.contentArea);
        // GetContentBox returns the actual size and offsets of the parent,
        // we don't want to use the same offsets for the child
        domGeom.setMarginBox(this.domNode, {l: 0, t: 0, h: box.h, w: box.w});
    }
    if (this._tree && this._tree.domNode) {
        // Resizing the inner tree
        this._tree.resize(domGeom.getMarginBox(this.domNode));
    }
};
That works because the content dialog has a contentArea attach-point. However that’s really specific so the best way to work around this bug would be to just wrap your FolderTree in another widget.

Workplace XT File Type issue in ICN


We’ve seen that there is an inheritance problem in this post, we will now see that there is a problem of File Types filters. This issue needs to be addressed if you want to use the second work around of the former issue.

Symptom

You’ve created Entry Templates in Workplace XT, and also created a few File Type Categories gathering several MIME Types. You’ve used these Entry Templates by associating them on a folder to use them when adding document. You restricted them by File Type Category. For example ET 1 is only for Images (File Type Images gathering image/png, image/jpeg, …), ET 2 is only for office documents, and ET3 is for every king of document. That looks a little bit like that in Workplace XT:
wpxt_entrytemplate_associations
Problem is that in ICN, this does not work. You always get the generic entry template (in my case misc doc, or no Entry Template if they all have restrictions on the File Type Categories.

If you look in a sub-folders of the folder on which you did the association in Workplace XT, you can see something like that:
ICN_EntryTemplateIssue
Here is the problem, ICN does not understand  the file type. This makes sense because actually in the Workplace XT Entry Template association (which is an xml annotation on the folder), the File Type are stored as ID only, and the Workplace XT keeps the File Type Categories definitions in its Site Preferences document. Therefore ICN has no way to know that h16vy is actually the Images File Type filter in ICN, even the name can be different so how could it know!

How to fix that

You have to ways to fixing this.

Basic way

The first one is more like a workaround. You can redo all associations you’ve done in Workplace XT in ICN, on the exact same folders, using the Workplace XT Entry Template but this time using the ICN File Type filters. This is a lot of work but it will work. Or you can automatize that by writing a tool converting all annotation of MIME Type application/x-filenet-folderprefs-templates (xml content) to an ICN one (application/x-icn-folderprefs-template an json content). Obviously this tool will have to know the mapping WPXT File Type Category ID –> ICN File Type filter name (there is no ID in ICN, the ID is the name, which actually creates another problem). The tool should transform something like this:
to something like that:

 Smart way

The second way is more complex to implement but a lot more flexible and smart. The idea is to make ICN aware of the WPXT File Type Categories via a plugin sending the mapping to the client when it first connects. Then the plugin injects some code into the client so every times it retrieves a Entry Template association, it maps the unknown file type ID to an ICN equivalent. That’s more work but then it will instantly work for all existing associations and also for all future associations made in Workplace XT!
Here is briefly how to implement that. First you need to create a new plugin, the most complex part will be the Configuration Pane if you want it to be “smart” and fetch all Workplace XT File Type Categories by itself. It has to know the Object Store where is the WPXT Site Preferences Document, then fetch it and parse it. Then it offer you to map to an ICN File Type filter, and tries to do it automatically if name are the same. Here is what it looks for my plugin:
icn_filetypefix_plugin
You can also make it dumb and dirty :), and just use one text field and fill it with
1
id1=File Type In ICN 1;id2=File Type In ICN 2;id3=File Type In ICN 3
The admin would have to open the Site preferences document of Workplace XT to know the ID and ICN Settings to know the File Type in ICN but that’s so much quicker to implement ðŸ™‚
Then you need to inject that on the client so it can map File Type Categories when retrieving Entry Template Association, this is how I did that:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
require(["dojo/_base/declare",
         "dojo/_base/lang",
         "dojo/aspect",
         "ecm/model/Request"], function (
    declare,
    lang,
    aspect,
    Request
) {
    /**
     * Use this function to add any global JavaScript methods your plug-in requires.
     */
    var signalFileTypeFixPlugin = null;
    var _injectFileTypes = function (fileTypesArray) {
        // Build a hashmap for all file types
        var fileTypes = {}, k, curfileType;
        for (k = 0; k < fileTypesArray.length; k++) {
            curfileType = fileTypesArray[k];
            fileTypes[curfileType.id] = curfileType.name;
        }
        // aspect the retrieve template to change the file type
        aspect.before(ecm.model.Repository.prototype, "_retrieveEntryTemplatesCompleted", function (response) {
            var i, j, fileType;
            for (i = 0; i < response.datastore.items.length; i++) {
                var entryTemplateJSON = response.datastore.items[i];
                for (j = 0; j < entryTemplateJSON.fileTypes.length; j++) {
                    fileType = entryTemplateJSON.fileTypes[j];
                    if (fileTypes[fileType]) {
                        entryTemplateJSON.fileTypes[j] = fileTypes[fileType];
                    }
                }
            }
        });
        // Execute this method only on the first login or we will have several aspects
        if (signalFileTypeFixPlugin) {
            signalFileTypeFixPlugin.remove();
        }
    };
    var fileTypePluginDeployed = function () {
        var i;
        for (i = 0; i < ecm.model.desktop._plugins.length; i++) {
            if (ecm.model.desktop._plugins[i].id == "FileTypeFixPlugin") {
                return true;
            }
        }
        return false;
    };
    // Retrieve plugin configuration from the server and store it
    var _fetchFileTypes = function () {
        if (fileTypePluginDeployed() && ecm.model.desktop.id != 'admin') {
            Request.invokePluginService("FileTypeFixPlugin", "FetchWPXTFileTypesService", {
                requestCompleteCallback: function (response) {
                    if (response.filetypes) {
                        // Here we can inject the File Types in the desktop config
                        _injectFileTypes(response.filetypes);
                    } else {
                        console.log("Error when retrieving File Type in the FileTypeFixPlugin");
                    }
                }
            });
        }
    };
    // Function called on the onLogin even from desktop
    var _onLogin = function (repository) {
        _fetchFileTypes();
    };
    if (ecm.model.desktop.connected) {
        // recycleBinPath not retrieve yet
        _fetchFileTypes();
    } else {
        // dojo/on won't work because desktop does not fire events,
        // let use aspect to call our method at the end of the dektop.onLogin
        signalFileTypeFixPlugin = aspect.after(ecm.model.desktop, "onLogin", _onLogin);
    }
});
I chose to use the _retrieveEntryTemplatesCompleted function of the repository, since it’s called once per folder then entry templates are cached. That’s a minimal overwork for the client.
As you can see, I implemented a service which basically only returns the mapping set in the plugin configuration panel, which is stored in the plugin configuration. It does not fetch them from Workplace XT every times of course.
Here is a video illustrating the fix:
https://youtu.be/jyfEPFCDM-s

Not my post...just a good info so sharing here..

No comments:

Post a Comment