• Change FileBrowser Column "Update date" to "Creation date"

  • He we will discuss about how to make customization and improvement to the OpenKM source code.
He we will discuss about how to make customization and improvement to the OpenKM source code.
Forum rules: Please, before asking something see the documentation wiki or use the search feature of the forum. And remember we don't have a crystal ball or mental readers, so if you post about an issue tell us which OpenKM are you using and also the browser and operating system version. For more info read How to Report Bugs Effectively.
 #41766  by ofstab
 
For me, it is more important to be able to organise the contents of a folder by creation date rather than modified date. I have a routine that edits the NBS_CREATED field for each document I add to the document's own creation datetime, rather than defaulting to the upload to OpenKM time. This works nicely.

However, the FileBrowser only has a column for "Update date", so I cannot sort all the documents in a folder by their "Creation date" property. I have figured out how to do this, and I thought it might be useful to others struggling with this low level configuration of OpenKM to write something of a tutorial on how I achieved my task.

The Professional Edition has the facility to add custom columns to the FileBrowser based on your own metadata, so if you are using the Professional Edition, stop reading now, there is a better way to do this built in to your software. Community Edition users, continue.

First, the good news. OpenKM Community edition is open source, which means that you can actually change the source code to fit your own needs. This is excellent.

Next, the bad news. You need to be able to edit source code to do this. This is painful, if you are not an IT professional.

First of all you are going to need the Portable Development, which you can download from here: https://sourceforge.net/projects/openkmportabledev/

I am not going to cover setting this up. There is a useful readme file in in the downloaded archive that walks you through it. Suffice to say the only major problem I had was that the built in Maven software installed its repository folder (.m2) in my Documents folder. This should have been fine, but my Documents folder is mounted on a network drive, which gave me build errors.

To solve these I moved the .m2 repository to c:\, and created a new settings.xml file in c:\openkm-dev with the following contents:
Code: Select all
<settings>
  <localRepository>c:/.m2/repository</localRepository>
</settings>
In Eclipse I then set Windows/Preferences/Maven/User Settings to point to the new XML file. I got all this solution from http://wiki.openkm.com/index.php/Developer_Guide where it is listed as a solution to a different problem.

So far, so good.

My solution to displaying "Creation date" is to change the nature of the "Update date" column. This means that I lose the "Update date" column functionality. If you want a "Creation date" column AND an "Update date" column, then this approach is not for you.

To get me started I read these threads in the forums:

https://forum.openkm.com/viewtopic.php?f=4&t=12587
https://forum.openkm.com/viewtopic.php?f=4&t=5520
https://forum.openkm.com/viewtopic.php?f=4&t=12493

From those, I gathered that the files that we need to edit in Eclipse are

FileBrowser.java
In brief, this lets us change the column header text.

ExtendedScrollTable.java
This lets us change the data displayed in the column.

ExtenderColumnSorter.java
This lets us change the way the column is sorted.

Starting with FileBrowser.java (/openkm-6.3-community/src/main/java/com/openkm/frontend/client/widget/filebrowser/FileBrowser.java), you want to search for the string: "isLastModifiedVisible". That will take you to all the places that change what they do depending on whether or not the "Update date" column should be displayed.

The first mention is in the method:
Code: Select all
public void langRefresh()
It reads:
Code: Select all
		if (profileFileBrowser.isLastModifiedVisible()) {
			headerTable.setHTML(row, colLastModifiedIndex, Main.i18n("filebrowser.date.update"));
			fBController.addOrderByItem(Main.i18n("filebrowser.date.update"), String.valueOf(GWTPaginated.COL_DATE));
		}
If you read through the code for Main.i18n, you find that what is happening is that a Translation service is used which takes the string "filebrowser.date.update" as a key, and searches against it in the OpenKM MySQL database (assuming you are using MySQL, no idea how this works if you are using another database), in the table `okm_translation`.

I looked through that table to see if I could find a "Creation date" text linked to a key I could use to prevent me from having to code my own. Happily there was with the key 'dashboard.workflow.task.created'. I decided to borrow this key. This is a terrible idea by the way. If the key changes in the future my column name will change as well. I really should make my own key, but I am a) not an IT professional and b) lazy.

So I changed the code in
Code: Select all
public void langRefresh()
to be:
Code: Select all
		if (profileFileBrowser.isLastModifiedVisible()) {
			headerTable.setHTML(row, colLastModifiedIndex, Main.i18n("dashboard.workflow.task.created"));
			fBController.addOrderByItem(Main.i18n("dashboard.workflow.task.created"), String.valueOf(GWTPaginated.COL_DATE));
		}
The next mention of "isLastModifiedVisible" is in the method
Code: Select all
public void setProfileFileBrowser(GWTProfileFileBrowser profileFileBrowser, GWTProfilePagination profilePagination)
I made the same type of change to this, so mine now reads:
Code: Select all
if (profileFileBrowser.isLastModifiedVisible()) {
			headerTable.setHTML(row, col, Main.i18n("dashboard.workflow.task.created"));
			colLastModifiedIndex = col;
			ScrollTableHelper.setColumnWidth(table, col, Integer.parseInt(profileFileBrowser.getLastModifiedWidth()), ScrollTableHelper.MEDIUM);
			col++;
			fBController.addOrderByItem(Main.i18n("dashboard.workflow.task.created"), String.valueOf(GWTPaginated.COL_DATE));
		}
The last mention of "isLastModifiedVisible" does not need any edits.

If you build OpenKM now, you will have changed the column heading to "Creation date" and nothing else. So let's change the data displayed.

You now want to be editing ExtendedScrollTable.java (/openkm-6.3-community/src/main/java/com/openkm/frontend/client/widget/filebrowser/ExtendedScrollTable.java). Again you want to seach for "isLastModifiedVisible". There are three results. The first is in the method
Code: Select all
public void addRow(GWTFolder folder, boolean update)
If the method name is not a good enough clue what this does is add a row to the filebrowser table when it is being displayed. As you might be able to see, this method takes as its input a folder object. I am concerned about displaying the Creation date of documents, not folders, but the code here is still useful. If you look down the method you will see this:
Code: Select all
 		if (profileFileBrowser.isLastModifiedVisible()) {
			DateTimeFormat dtf = DateTimeFormat.getFormat(Main.i18n("general.date.pattern"));
			dataTable.setHTML(row, col, dtf.format(folder.getCreated()));
			dataTable.getCellFormatter().setHorizontalAlignment(row, col++, HasHorizontalAlignment.ALIGN_CENTER);
		}
The important bit to look at is the "folder.getCreated()". This adds the creation date of folders to the "Update date" column in the filebrowser. I just want to do that with documents as well. Search for the next "isLastModifiedVisible", and you will come to the method:
Code: Select all
public void addRow(GWTDocument doc, boolean update)
That method takes a document object as an input, and does what we want. The if..loop that applies "isLastModifiedVisible" in mine now reads:
Code: Select all
 		if (profileFileBrowser.isLastModifiedVisible()) {
			DateTimeFormat dtf = DateTimeFormat.getFormat(Main.i18n("general.date.pattern"));
			dataTable.setHTML(row, col, dtf.format(doc.getCreated()));
			dataTable.getCellFormatter().setHorizontalAlignment(row, col++, HasHorizontalAlignment.ALIGN_CENTER);
		}
I changed doc.getLastModified() to doc.getCreated(). That is the only change you need to make in ExtendedScrollTable.java. If you build OpenKM now, you will find that the column now headed "Creation date" actual displays the creation dates of documents. However, if you attempt to SORT the column it will still sort based on the underlying "Update date".

To complete our task, you need to edit ExtenderColumnSorter.java (/openkm-6.3-community/src/main/java/com/openkm/frontend/client/widget/filebrowser/ExtendedColumnSorter.java). Searching for "isLastModifiedVisible" this time will not help. It takes you to one entry, which is in a method to help when other custom columns are added - not something I am covering here. Look for the method
Code: Select all
public void sort(int column, boolean ascending)
The name sounds promising! The method contains a Select...Case section of code which contains the following:
Code: Select all
case 5 :
	// Date
	if (data.get(Integer.parseInt(rowI[colDataIndex])) instanceof GWTFolder) {
		rowToOrder.setObject(((GWTFolder) data.get(Integer.parseInt(rowI[colDataIndex]))).getCreated()); 	// Date value
		rowToOrder.setDataId(""+ i);														 	// Actual position value
		elementToOrder.add(rowToOrder);
	} else if (data.get(Integer.parseInt(rowI[colDataIndex])) instanceof GWTMail) {  
		rowToOrder.setObject(((GWTMail) data.get(Integer.parseInt(rowI[colDataIndex]))).getReceivedDate()); // Date value
		rowToOrder.setDataId(""+ i);																 // Actual position value
		elementToOrder.add(rowToOrder);
	} else if (data.get(Integer.parseInt(rowI[colDataIndex])) instanceof GWTDocument) {  
		rowToOrder.setObject(((GWTDocument) data.get(Integer.parseInt(rowI[colDataIndex]))).getLastModified()); // Date value
		rowToOrder.setDataId(""+ i);																 // Actual position value
		elementToOrder.add(rowToOrder);
	}
	break;
This code is run if the variable correctedColumn is 5. Why is this of interest? In the file /openkm-6.3-community/src/main/java/com/openkm/frontend/client/constants/ui/UIDesktopConstants.java:
Code: Select all
FILEBROWSER_COLUMN_LASTMODIFIED = 5
So, this case is run if we are dealing with the LastModified Column (how the method knows this, I have not worked out). I made the same change to the last "else if" which runs if the data type is a GWTDocument, that I made in the last file. I changed the "setOject" to grab the "Date value" from getCreated() instead of getLastModified(), so my select...case for '5' is now:
Code: Select all
case 5 :
	// Date
	if (data.get(Integer.parseInt(rowI[colDataIndex])) instanceof GWTFolder) {
		rowToOrder.setObject(((GWTFolder) data.get(Integer.parseInt(rowI[colDataIndex]))).getCreated()); 	// Date value
		rowToOrder.setDataId(""+ i);														 	// Actual position value
		elementToOrder.add(rowToOrder);
	} else if (data.get(Integer.parseInt(rowI[colDataIndex])) instanceof GWTMail) {  
		rowToOrder.setObject(((GWTMail) data.get(Integer.parseInt(rowI[colDataIndex]))).getReceivedDate()); // Date value
		rowToOrder.setDataId(""+ i);																 // Actual position value
		elementToOrder.add(rowToOrder);
	} else if (data.get(Integer.parseInt(rowI[colDataIndex])) instanceof GWTDocument) {  
		rowToOrder.setObject(((GWTDocument) data.get(Integer.parseInt(rowI[colDataIndex]))).getCreated()); // Date value
		rowToOrder.setDataId(""+ i);																 // Actual position value
		elementToOrder.add(rowToOrder);
	}
	break;
If you now build OpenKM, you will find your LastModified column is now headed "Creation date", displays the Creation date of documents, and is sorted by the document's creation date.

Job done. I hope this had been useful.
 #41934  by creya
 
concerning changing java code to accomplish the tasks described in this thread, is there a best practice on how to organize updated java files so that new releases/versions of OKM do not affect our changed code? or even not to break it? Can anyone show some link on how to deal with this?
 #41944  by ofstab
 
creya wrote:concerning changing java code to accomplish the tasks described in this thread, is there a best practice on how to organize updated java files so that new releases/versions of OKM do not affect our changed code? or even not to break it? Can anyone show some link on how to deal with this?
I suspect the answer to this from the project authors will be that changes like this would just have to be made to the underlying source each time there is a new release.

At best, if I had any idea how to make a patch file in Eclipse (which I do not), and there was no major underlying changes to the source in the three files mentioned, then you could just apply the patch each time the source changed, and it would quickly restore the changes.

I recall in some older threads on the system that some thought was being given to including the Professional Edition custom columns to the Community Edition at some point in the future. So this problem is one with a limited lifespan.
 #41945  by creya
 
ofstab thnx for your feedback.

Concerning "I recall in some older threads on the system that some thought was being given to including the Professional Edition custom columns to the Community Edition at some point in the future. So this problem is one with a limited lifespan.", the custom columns in the professional version include only metadata columns.
So, we will still need to change code at some point, and our code needs to coexist with OKM code, and it should not be a nightware to update when new versions of OKM are available.

There are many methods such code changes are handled with other opensource projects e.g. code can be changed and placed in a special folder where such code take precedence over OKM code: simple and effective method.

I am wondering if such a scheme, if any, is available with OKM... hopefully one of the experts in this project will shed some light on this issue.
 #41959  by jllort
 
About respecting your code changes if you create a patch we can investigate if can be incorporated in default source code or not. I advance probably not, because you have changed a column, if you had incorporated a new one, will be more easy to maintaining with actual source code ( then users could enable or disable from profiles the columns).

We are periodically updating the source code, when you update from the repository will identify on merge if there are problems or not. I suspect not much, because in this section of code we usually are not applying changes.
 #41977  by ofstab
 
the custom columns in the professional version include only metadata columns.
So, we will still need to change code at some point, and our code needs to coexist with OKM code, and it should not be a nightware to update when new versions of OKM are available.
You are quite right, my mistake. I have a custom written outlook plugin that uses the API, which auto generates custom metadata, and I was planning on just adding a created date custom metadata category, and then adding a custom column reflecting that metadata category if/when the feature trickles down. You are right that it would not solve all such problems.
if you create a patch we can investigate if can be incorporated in default source code or not. I advance probably not, because you have changed a column
Thanks for this - have not worked out how to generate a patch file from Eclipse, or indeed anywhere else. My fault of course, will need to further my coding education. I suspect you are right though and it is a fundamental chance to the code. What would be needed is either an entirely new column, or the option to switch between created/modified columns to be backwards compatible.

I also have not figured out how to do that, but it would be a neater solution than that which I set out above.
 #41984  by creya
 
Jllort:

Very often, we need to store/view documents within a folder based on some arbitrary order i.e. based on a sequence number which designates the place (order) of documents within the folder.

Having an attribute named "order" or "sequence" as part of the "properties" section of the UI, and which can be easily changed by users to change the place of a document within a folder, so that a certain sequence is respected... this would be a great help for anyone who needs to store files in a certain order within a folder... so, I was thinking about creating some patch to accommodate this feature, but am afraid about maintenance in the future as new version of OKM come out.

Any recommendation?
Thnx
 #41991  by jllort
 
On next release we will include extra columns. I do not know exactly when because we are involved on several things at same time and until will not be closed we will not going for releasing next version. If you now create a new column ( not removing the actual ) later will be more easy to introduce and maintaining this feature. Take a look at Profiles, from there you can hide a column ( there should be added yours ).

About Us

OpenKM is part of the management software. A management software is a program that facilitates the accomplishment of administrative tasks. OpenKM is a document management system that allows you to manage business content and workflow in a more efficient way. Document managers guarantee data protection by establishing information security for business content.