dataview view impl
This commit is contained in:
parent
d948742963
commit
303448d766
4 changed files with 174 additions and 85 deletions
|
|
@ -49,6 +49,16 @@ import jakarta.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The DataViewController is used to display a data view
|
* The DataViewController is used to display a data view
|
||||||
|
* <p>
|
||||||
|
* The controller uses a cacheId provided together with the uniqueId of the
|
||||||
|
* dataViewDefinition in the URL. The bean reads optional cached query data form
|
||||||
|
* a session scoped cache EJB and reloads the last state. This is useful for
|
||||||
|
* situations where the user navigates to a new page (e.g. open a workitem) and
|
||||||
|
* late uses browser history back.
|
||||||
|
* <p>
|
||||||
|
* Note: This bean is ConversationScoped, because it uses the
|
||||||
|
* CustomFormController which expects conversion scope!
|
||||||
|
*
|
||||||
*
|
*
|
||||||
* @author rsoika
|
* @author rsoika
|
||||||
* @version 1.0
|
* @version 1.0
|
||||||
|
|
@ -59,7 +69,11 @@ import jakarta.servlet.http.HttpServletRequest;
|
||||||
public class DataViewController extends ViewController {
|
public class DataViewController extends ViewController {
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
private List<CustomFormSection> sections;
|
private List<CustomFormSection> sections = null;
|
||||||
|
private List<ItemCollection> viewItemDefinitions = null;
|
||||||
|
protected ItemCollection dataDefinition = null;
|
||||||
|
private ItemCollection filter;
|
||||||
|
private String query;
|
||||||
private String errorMessage;
|
private String errorMessage;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
|
|
@ -77,9 +91,8 @@ public class DataViewController extends ViewController {
|
||||||
@Inject
|
@Inject
|
||||||
ViewHandler viewHandler;
|
ViewHandler viewHandler;
|
||||||
|
|
||||||
protected ItemCollection data = null;
|
@Inject
|
||||||
private ItemCollection filter;
|
DataViewDefinitionController dataViewDefinitionController;
|
||||||
private String query;
|
|
||||||
|
|
||||||
private static Logger logger = Logger.getLogger(DataViewController.class.getName());
|
private static Logger logger = Logger.getLogger(DataViewController.class.getName());
|
||||||
|
|
||||||
|
|
@ -118,7 +131,7 @@ public class DataViewController extends ViewController {
|
||||||
// alternative 'workitem=...'
|
// alternative 'workitem=...'
|
||||||
uniqueid = paramMap.get("workitem");
|
uniqueid = paramMap.get("workitem");
|
||||||
}
|
}
|
||||||
data = documentService.load(uniqueid);
|
dataDefinition = documentService.load(uniqueid);
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.info("> cacheid=" + cacheid);
|
logger.info("> cacheid=" + cacheid);
|
||||||
|
|
@ -130,8 +143,10 @@ public class DataViewController extends ViewController {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Init new Filter....
|
// Init new Filter....
|
||||||
if (data != null) {
|
if (dataDefinition != null) {
|
||||||
filter.setItemValue("txtWorkflowEditorCustomForm", data.getItemValue("form"));
|
filter.setItemValue("txtWorkflowEditorCustomForm", dataDefinition.getItemValue("form"));
|
||||||
|
viewItemDefinitions = DataViewDefinitionController
|
||||||
|
.computeDataViewItemDefinitions(dataDefinition);
|
||||||
|
|
||||||
customFormController.computeFieldDefinition(filter);
|
customFormController.computeFieldDefinition(filter);
|
||||||
sections = customFormController.getSections();
|
sections = customFormController.getSections();
|
||||||
|
|
@ -151,13 +166,17 @@ public class DataViewController extends ViewController {
|
||||||
}
|
}
|
||||||
|
|
||||||
public ItemCollection getDefinition() {
|
public ItemCollection getDefinition() {
|
||||||
return data;
|
return dataDefinition;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<CustomFormSection> getSections() {
|
public List<CustomFormSection> getSections() {
|
||||||
return sections;
|
return sections;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<ItemCollection> getViewItemDefinitions() {
|
||||||
|
return viewItemDefinitions;
|
||||||
|
}
|
||||||
|
|
||||||
public ItemCollection getFilter() {
|
public ItemCollection getFilter() {
|
||||||
return filter;
|
return filter;
|
||||||
}
|
}
|
||||||
|
|
@ -188,7 +207,7 @@ public class DataViewController extends ViewController {
|
||||||
reset();
|
reset();
|
||||||
|
|
||||||
// build new query from template
|
// build new query from template
|
||||||
query = data.getItemValueString("query");
|
query = dataDefinition.getItemValueString("query");
|
||||||
|
|
||||||
List<String> filterItems = filter.getItemNames();
|
List<String> filterItems = filter.getItemNames();
|
||||||
for (String itemName : filterItems) {
|
for (String itemName : filterItems) {
|
||||||
|
|
@ -227,28 +246,28 @@ public class DataViewController extends ViewController {
|
||||||
return query;
|
return query;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
// /**
|
||||||
* Returns the current workItem. If no workitem is defined the method
|
// * Returns the current workItem. If no workitem is defined the method
|
||||||
* Instantiates a empty ItemCollection.
|
// * Instantiates a empty ItemCollection.
|
||||||
*
|
// *
|
||||||
* @return - current workItem or null if not set
|
// * @return - current workItem or null if not set
|
||||||
*/
|
// */
|
||||||
public ItemCollection getData() {
|
// public ItemCollection getData() {
|
||||||
// do initialize an empty workItem here if null
|
// // do initialize an empty workItem here if null
|
||||||
if (data == null) {
|
// if (data == null) {
|
||||||
reset();
|
// reset();
|
||||||
}
|
// }
|
||||||
return data;
|
// return data;
|
||||||
}
|
// }
|
||||||
|
|
||||||
/**
|
// /**
|
||||||
* Set the current workItem
|
// * Set the current workItem
|
||||||
*
|
// *
|
||||||
* @param workitem - new reference or null to clear the current workItem.
|
// * @param workitem - new reference or null to clear the current workItem.
|
||||||
*/
|
// */
|
||||||
public void setData(ItemCollection document) {
|
// public void setData(ItemCollection document) {
|
||||||
this.data = document;
|
// this.data = document;
|
||||||
}
|
// }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method navigates back in the page index and caches the current page
|
* This method navigates back in the page index and caches the current page
|
||||||
|
|
|
||||||
|
|
@ -30,17 +30,14 @@ import java.util.Map;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import org.imixs.workflow.ItemCollection;
|
import org.imixs.workflow.ItemCollection;
|
||||||
import org.imixs.workflow.engine.DocumentEvent;
|
|
||||||
import org.imixs.workflow.exceptions.AccessDeniedException;
|
import org.imixs.workflow.exceptions.AccessDeniedException;
|
||||||
import org.imixs.workflow.faces.data.AbstractDataController;
|
import org.imixs.workflow.faces.data.AbstractDataController;
|
||||||
import org.imixs.workflow.faces.data.DocumentController;
|
import org.imixs.workflow.faces.data.DocumentController;
|
||||||
import org.imixs.workflow.office.forms.ChildItemController;
|
|
||||||
|
|
||||||
import com.oracle.svm.core.annotate.Inject;
|
import com.oracle.svm.core.annotate.Inject;
|
||||||
|
|
||||||
import jakarta.annotation.PostConstruct;
|
import jakarta.annotation.PostConstruct;
|
||||||
import jakarta.enterprise.context.ConversationScoped;
|
import jakarta.enterprise.context.ConversationScoped;
|
||||||
import jakarta.enterprise.event.Observes;
|
|
||||||
import jakarta.faces.context.ExternalContext;
|
import jakarta.faces.context.ExternalContext;
|
||||||
import jakarta.faces.context.FacesContext;
|
import jakarta.faces.context.FacesContext;
|
||||||
import jakarta.inject.Named;
|
import jakarta.inject.Named;
|
||||||
|
|
@ -59,9 +56,6 @@ public class DataViewDefinitionController extends AbstractDataController {
|
||||||
|
|
||||||
protected List<ItemCollection> attributeList = null;
|
protected List<ItemCollection> attributeList = null;
|
||||||
|
|
||||||
@Inject
|
|
||||||
ChildItemController childItemController;
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
DocumentController documentController;
|
DocumentController documentController;
|
||||||
|
|
||||||
|
|
@ -103,22 +97,71 @@ public class DataViewDefinitionController extends AbstractDataController {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the current worktItem
|
* Set the current dataview definition.
|
||||||
|
* The method computes the attributes.
|
||||||
*
|
*
|
||||||
* @param workitem - new reference or null to clear the current workItem.
|
* @param document - the DataView definition
|
||||||
*/
|
*/
|
||||||
public void setData(ItemCollection document) {
|
// public void setData(ItemCollection document) {
|
||||||
this.data = document;
|
// this.data = document;
|
||||||
|
// attributeList = computeDataViewItemDefinitions(this.data);
|
||||||
|
// }
|
||||||
|
|
||||||
attributeList = new ArrayList<ItemCollection>();
|
@Override
|
||||||
List<Object> mapItems = data.getItemValue("dataview.items");
|
public void load(String uniqueid) {
|
||||||
|
|
||||||
|
super.load(uniqueid);
|
||||||
|
attributeList = computeDataViewItemDefinitions(this.data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a List of ItemCollection instances representing the view column
|
||||||
|
* description.
|
||||||
|
* Each column has the items:
|
||||||
|
*
|
||||||
|
* name,label,format,convert
|
||||||
|
*
|
||||||
|
* @param dataViewDefinition
|
||||||
|
* @return
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public static List<ItemCollection> computeDataViewItemDefinitions(ItemCollection dataViewDefinition) {
|
||||||
|
|
||||||
|
ArrayList<ItemCollection> result = new ArrayList<ItemCollection>();
|
||||||
|
List<Object> mapItems = dataViewDefinition.getItemValue("dataview.items");
|
||||||
for (Object mapOderItem : mapItems) {
|
for (Object mapOderItem : mapItems) {
|
||||||
if (mapOderItem instanceof Map) {
|
if (mapOderItem instanceof Map) {
|
||||||
ItemCollection itemCol = new ItemCollection((Map) mapOderItem);
|
ItemCollection itemCol = new ItemCollection((Map) mapOderItem);
|
||||||
attributeList.add(itemCol);
|
// check label
|
||||||
|
String itemLabel = itemCol.getItemValueString("item.label");
|
||||||
|
if (itemLabel.isEmpty()) {
|
||||||
|
itemCol.setItemValue("item.label", itemLabel);
|
||||||
|
}
|
||||||
|
// check type
|
||||||
|
String itemType = itemCol.getItemValueString("item.type");
|
||||||
|
if (itemType.isEmpty()) {
|
||||||
|
itemCol.setItemValue("item.type", "xs:string");
|
||||||
|
}
|
||||||
|
result.add(itemCol);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if no columns are defined we create the default columns
|
||||||
|
if (result.size() == 0) {
|
||||||
|
ItemCollection itemCol = new ItemCollection();
|
||||||
|
itemCol.setItemValue("item.name", "$workflowSummary");
|
||||||
|
itemCol.setItemValue("item.label", "Name");
|
||||||
|
itemCol.setItemValue("item.type", "xs:anyURI");
|
||||||
|
result.add(itemCol);
|
||||||
|
|
||||||
|
itemCol = new ItemCollection();
|
||||||
|
itemCol.setItemValue("item.name", "$modified");
|
||||||
|
itemCol.setItemValue("item.label", "Modified");
|
||||||
|
itemCol.setItemValue("item.type", "xs:date");
|
||||||
|
result.add(itemCol);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -133,9 +176,18 @@ public class DataViewDefinitionController extends AbstractDataController {
|
||||||
.getExternalContext();
|
.getExternalContext();
|
||||||
String sUser = externalContext.getRemoteUser();
|
String sUser = externalContext.getRemoteUser();
|
||||||
data.replaceItemValue("$editor", sUser);
|
data.replaceItemValue("$editor", sUser);
|
||||||
|
|
||||||
|
List<Map> mapItemList = new ArrayList<Map>();
|
||||||
|
logger.fine("Convert attribute items into Map...");
|
||||||
|
// implode attributes
|
||||||
|
for (ItemCollection attrItem : attributeList) {
|
||||||
|
ItemCollection ding = (ItemCollection) attrItem.clone();
|
||||||
|
mapItemList.add(ding.getAllItems());
|
||||||
|
}
|
||||||
|
data.replaceItemValue("dataview.items", mapItemList);
|
||||||
|
|
||||||
data = this.getDocumentService().save(data);
|
data = this.getDocumentService().save(data);
|
||||||
|
|
||||||
logger.finest("......ItemCollection saved");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String openTestView() {
|
public String openTestView() {
|
||||||
|
|
@ -152,34 +204,35 @@ public class DataViewDefinitionController extends AbstractDataController {
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public void onEvent(@Observes DocumentEvent event) {
|
// public void onEvent(@Observes DocumentEvent event) {
|
||||||
|
|
||||||
if (event == null || event.getDocument() == null || !"dataview".equals(event.getDocument().getType())) {
|
// if (event == null || event.getDocument() == null ||
|
||||||
return;
|
// !"dataview".equals(event.getDocument().getType())) {
|
||||||
}
|
// return;
|
||||||
// update attribute list
|
// }
|
||||||
if (event.getEventType() == DocumentEvent.ON_DOCUMENT_SAVE) {
|
// // update attribute list
|
||||||
|
// if (event.getEventType() == DocumentEvent.ON_DOCUMENT_SAVE) {
|
||||||
|
|
||||||
// convert the option ItemCollection elements into a List of Map
|
// // convert the option ItemCollection elements into a List of Map
|
||||||
if (attributeList != null) {
|
// if (attributeList != null) {
|
||||||
List<Map> mapItemList = new ArrayList<Map>();
|
// List<Map> mapItemList = new ArrayList<Map>();
|
||||||
logger.fine("Convert option items into Map...");
|
// logger.fine("Convert option items into Map...");
|
||||||
// iterate over all items..
|
// // iterate over all items..
|
||||||
for (ItemCollection attrItem : attributeList) {
|
// for (ItemCollection attrItem : attributeList) {
|
||||||
ItemCollection ding = (ItemCollection) attrItem.clone();
|
// ItemCollection ding = (ItemCollection) attrItem.clone();
|
||||||
mapItemList.add(ding.getAllItems());
|
// mapItemList.add(ding.getAllItems());
|
||||||
}
|
// }
|
||||||
event.getDocument().replaceItemValue("dataview.items", mapItemList);
|
// event.getDocument().replaceItemValue("dataview.items", mapItemList);
|
||||||
|
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
// update attribute list
|
// // update attribute list
|
||||||
if (event.getEventType() == DocumentEvent.ON_DOCUMENT_LOAD) {
|
// if (event.getEventType() == DocumentEvent.ON_DOCUMENT_LOAD) {
|
||||||
|
|
||||||
}
|
// }
|
||||||
|
|
||||||
}
|
// }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a new attribute object.
|
* Adds a new attribute object.
|
||||||
|
|
|
||||||
|
|
@ -100,8 +100,11 @@
|
||||||
<span class="typcn typcn-lightbulb"></span>
|
<span class="typcn typcn-lightbulb"></span>
|
||||||
Attribute definitions for the vew result. An attribute can adapt single item
|
Attribute definitions for the vew result. An attribute can adapt single item
|
||||||
values. Each item of
|
values. Each item of
|
||||||
the attribute list can define an optional label, converter, format and
|
the attribute list can define an optional label, xs datatype and format.
|
||||||
aggregator.
|
<br />
|
||||||
|
Convert - xml datatypes: xs:string (default), xs:decimal, xs:date,
|
||||||
|
xs:dateTime,
|
||||||
|
xs:anyURI
|
||||||
|
|
||||||
</p>
|
</p>
|
||||||
<f:ajax render="attributelist" onevent="updateAttributeList">
|
<f:ajax render="attributelist" onevent="updateAttributeList">
|
||||||
|
|
@ -109,7 +112,7 @@
|
||||||
<tr>
|
<tr>
|
||||||
<th style="width: 250px">Item</th>
|
<th style="width: 250px">Item</th>
|
||||||
<th style="width: 250px;">Label</th>
|
<th style="width: 250px;">Label</th>
|
||||||
<th style="width: 200px;">Convert</th>
|
<th style="width: 200px;">Type</th>
|
||||||
<th style="">Format</th>
|
<th style="">Format</th>
|
||||||
<th style="width: 100px">
|
<th style="width: 100px">
|
||||||
<!-- actions -->
|
<!-- actions -->
|
||||||
|
|
@ -128,7 +131,7 @@
|
||||||
style="width:100%;" />
|
style="width:100%;" />
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<h:inputText value="#{attribute.item['item.convert']}"
|
<h:inputText value="#{attribute.item['item.type']}"
|
||||||
style="width:100%;" />
|
style="width:100%;" />
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
|
|
|
||||||
|
|
@ -109,24 +109,38 @@
|
||||||
<h:dataTable id="view_body" styleClass="imixsdatatable" value="#{searchResult}"
|
<h:dataTable id="view_body" styleClass="imixsdatatable" value="#{searchResult}"
|
||||||
var="record">
|
var="record">
|
||||||
|
|
||||||
<h:column>
|
|
||||||
<f:facet name="header">#{message.name}</f:facet>
|
|
||||||
<h:link outcome="/pages/workitems/workitem.xhtml?faces-redirect=true"
|
|
||||||
styleClass="imixs-viewentry-main-link">
|
|
||||||
<h:outputText value="#{record.item['$workflowsummary']}" />
|
|
||||||
<f:param name="id" value="#{record.item['$uniqueid']}" />
|
|
||||||
</h:link>
|
|
||||||
</h:column>
|
|
||||||
|
|
||||||
|
|
||||||
<h:column>
|
|
||||||
<f:facet name="header">#{message.modified}</f:facet>
|
|
||||||
<h:outputText value="#{record.item['$modified']}">
|
|
||||||
<f:convertDateTime timeZone="#{message.timeZone}" type="both"
|
|
||||||
pattern="#{message.dateTimePattern}" />
|
|
||||||
</h:outputText>
|
|
||||||
|
|
||||||
</h:column>
|
<c:forEach items="#{dataViewController.viewItemDefinitions}" var="columnDef">
|
||||||
|
|
||||||
|
|
||||||
|
<h:column rendered="#{columnDef.item['item.type'] eq 'xs:anyURI'}">
|
||||||
|
<f:facet name="header">#{columnDef.item['item.label']}</f:facet>
|
||||||
|
<h:link outcome="/pages/workitems/workitem.xhtml?faces-redirect=true"
|
||||||
|
styleClass="imixs-viewentry-main-link">
|
||||||
|
<h:outputText value="#{record.item[columnDef.item['item.name']]}" />
|
||||||
|
<f:param name="id" value="#{record.item['$uniqueid']}" />
|
||||||
|
</h:link>
|
||||||
|
</h:column>
|
||||||
|
|
||||||
|
<h:column rendered="#{columnDef.item['item.type'] eq 'xs:string'}">
|
||||||
|
<f:facet name="header">#{columnDef.item['item.label']}</f:facet>
|
||||||
|
<h:outputText value="#{record.item[columnDef.item['item.name']]}" />
|
||||||
|
</h:column>
|
||||||
|
|
||||||
|
<h:column rendered="#{columnDef.item['item.type'] eq 'xs:date'}">
|
||||||
|
<f:facet name="header">#{columnDef.item['item.label']}</f:facet>
|
||||||
|
<h:outputText value="#{record.item[columnDef.item['item.name']]}">
|
||||||
|
<f:convertDateTime timeZone="#{message.timeZone}" type="both"
|
||||||
|
pattern="#{message.dateTimePattern}" />
|
||||||
|
</h:outputText>
|
||||||
|
|
||||||
|
|
||||||
|
</h:column>
|
||||||
|
</c:forEach>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</h:dataTable>
|
</h:dataTable>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue