dataViews first working draft!
This commit is contained in:
parent
174b230509
commit
d948742963
5 changed files with 143 additions and 29 deletions
|
|
@ -0,0 +1,64 @@
|
|||
/*******************************************************************************
|
||||
* Imixs Workflow Technology
|
||||
* Copyright (C) 2003, 2008 Imixs Software Solutions GmbH,
|
||||
* http://www.imixs.com
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You can receive a copy of the GNU General Public
|
||||
* License at http://www.gnu.org/licenses/gpl.html
|
||||
*
|
||||
* Contributors:
|
||||
* Imixs Software Solutions GmbH - initial API and implementation
|
||||
* Ralph Soika
|
||||
*
|
||||
*******************************************************************************/
|
||||
package org.imixs.workflow.office.dataview;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.imixs.workflow.ItemCollection;
|
||||
|
||||
import jakarta.enterprise.context.SessionScoped;
|
||||
import jakarta.inject.Named;
|
||||
|
||||
/**
|
||||
* The DataViewCache implements a sessionScoped cache for the dataView filter.
|
||||
* The cache uses the cacheId provided in the URL - see DataViewController
|
||||
* onLoad
|
||||
*
|
||||
* @author rsoika
|
||||
* @version 1.0
|
||||
*/
|
||||
@Named
|
||||
@SessionScoped
|
||||
public class DataViewCache implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private Map<String, ItemCollection> dataViewStates = new ConcurrentHashMap<>();
|
||||
|
||||
public void put(String key, ItemCollection data) {
|
||||
dataViewStates.put(key, data);
|
||||
}
|
||||
|
||||
public ItemCollection get(String key) {
|
||||
ItemCollection result = dataViewStates.get(key);
|
||||
if (result == null) {
|
||||
// init new empty cache object!
|
||||
result = new ItemCollection();
|
||||
dataViewStates.put(key, result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
@ -24,7 +24,6 @@
|
|||
package org.imixs.workflow.office.dataview;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.logging.Level;
|
||||
|
|
@ -42,7 +41,7 @@ import org.imixs.workflow.office.forms.CustomFormSection;
|
|||
|
||||
import jakarta.annotation.PostConstruct;
|
||||
import jakarta.enterprise.context.Conversation;
|
||||
import jakarta.enterprise.context.SessionScoped;
|
||||
import jakarta.enterprise.context.ConversationScoped;
|
||||
import jakarta.faces.context.FacesContext;
|
||||
import jakarta.inject.Inject;
|
||||
import jakarta.inject.Named;
|
||||
|
|
@ -55,13 +54,17 @@ import jakarta.servlet.http.HttpServletRequest;
|
|||
* @version 1.0
|
||||
*/
|
||||
@Named
|
||||
@SessionScoped
|
||||
// @SessionScoped
|
||||
@ConversationScoped
|
||||
public class DataViewController extends ViewController {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
private List<CustomFormSection> sections;
|
||||
private String errorMessage;
|
||||
|
||||
@Inject
|
||||
DataViewCache dataViewCache;
|
||||
|
||||
@Inject
|
||||
private Conversation conversation;
|
||||
|
||||
|
|
@ -91,22 +94,16 @@ public class DataViewController extends ViewController {
|
|||
this.setLoadStubs(false);
|
||||
}
|
||||
|
||||
public ItemCollection getDefinition() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public List<CustomFormSection> getSections() {
|
||||
return sections;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method loads the custom form sections
|
||||
*/
|
||||
public void onLoad() {
|
||||
if (filter == null) {
|
||||
filter = new ItemCollection();
|
||||
}
|
||||
// super.onLoad();
|
||||
|
||||
String cacheid = null;
|
||||
logger.info("> onload...");
|
||||
|
||||
// Important: start a new conversation beause of the usage of the
|
||||
// CustomFormController!
|
||||
startConversation();
|
||||
|
||||
FacesContext facesContext = FacesContext.getCurrentInstance();
|
||||
|
|
@ -115,6 +112,7 @@ public class DataViewController extends ViewController {
|
|||
FacesContext fc = FacesContext.getCurrentInstance();
|
||||
Map<String, String> paramMap = fc.getExternalContext().getRequestParameterMap();
|
||||
// try to extract the uniqueid form the query string...
|
||||
cacheid = paramMap.get("cacheid");
|
||||
String uniqueid = paramMap.get("id");
|
||||
if (uniqueid == null || uniqueid.isEmpty()) {
|
||||
// alternative 'workitem=...'
|
||||
|
|
@ -123,20 +121,43 @@ public class DataViewController extends ViewController {
|
|||
data = documentService.load(uniqueid);
|
||||
}
|
||||
|
||||
logger.info("> cacheid=" + cacheid);
|
||||
if (cacheid != null && !cacheid.isEmpty()) {
|
||||
filter = dataViewCache.get(cacheid);
|
||||
} else {
|
||||
filter = new ItemCollection();
|
||||
}
|
||||
|
||||
try {
|
||||
// Init new Filter....
|
||||
if (data != null) {
|
||||
filter.setItemValue("txtWorkflowEditorCustomForm", data.getItemValue("form"));
|
||||
// filter.setItemValue("date.from", new Date());
|
||||
|
||||
customFormController.computeFieldDefinition(filter);
|
||||
sections = customFormController.getSections();
|
||||
|
||||
logger.info(" < cached page index=" + filter.getItemValueInteger("pageIndex"));
|
||||
this.setPageIndex(filter.getItemValueInteger("pageIndex"));
|
||||
if (!filter.getItemValueString("query").isEmpty()) {
|
||||
query = filter.getItemValueString("query");
|
||||
// Prefetch data to update total count and page count
|
||||
viewHandler.getData(this);
|
||||
}
|
||||
}
|
||||
} catch (ModelException e) {
|
||||
} catch (ModelException | QueryException e) {
|
||||
logger.warning("Failed to load dataview definition: " + e.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public ItemCollection getDefinition() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public List<CustomFormSection> getSections() {
|
||||
return sections;
|
||||
}
|
||||
|
||||
public ItemCollection getFilter() {
|
||||
return filter;
|
||||
}
|
||||
|
|
@ -165,9 +186,8 @@ public class DataViewController extends ViewController {
|
|||
*/
|
||||
public void run() throws QueryException {
|
||||
reset();
|
||||
Date date = filter.getItemValueDate("date.from");
|
||||
logger.info("x date=" + date);
|
||||
|
||||
// build new query from template
|
||||
query = data.getItemValueString("query");
|
||||
|
||||
List<String> filterItems = filter.getItemNames();
|
||||
|
|
@ -191,6 +211,7 @@ public class DataViewController extends ViewController {
|
|||
query = query.replaceAll("(?i)\\{" + Pattern.quote(itemName) + "\\}", itemValue);
|
||||
}
|
||||
logger.info("query=" + query);
|
||||
filter.setItemValue("query", query);
|
||||
|
||||
// Prefetch data to update total count and page count
|
||||
viewHandler.getData(this);
|
||||
|
|
@ -221,13 +242,31 @@ public class DataViewController extends ViewController {
|
|||
}
|
||||
|
||||
/**
|
||||
* Set the current worktItem
|
||||
* Set the current workItem
|
||||
*
|
||||
* @param workitem - new reference or null to clear the current workItem.
|
||||
*/
|
||||
public void setData(ItemCollection document) {
|
||||
this.data = document;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method navigates back in the page index and caches the current page
|
||||
* index
|
||||
*/
|
||||
public void back() {
|
||||
viewHandler.back(this);
|
||||
filter.setItemValue("pageIndex", this.getPageIndex());
|
||||
}
|
||||
|
||||
/**
|
||||
* This method navigates forward in the page index and caches the current page
|
||||
* index
|
||||
*/
|
||||
public void forward() {
|
||||
viewHandler.forward(this);
|
||||
filter.setItemValue("pageIndex", this.getPageIndex());
|
||||
logger.info("-> forward to page " + this.getPageIndex());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -239,7 +278,8 @@ public class DataViewController extends ViewController {
|
|||
((HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest())
|
||||
.getSession().getMaxInactiveInterval() * 1000);
|
||||
conversation.begin();
|
||||
logger.log(Level.FINEST, "......start new conversation, id={0}", conversation.getId());
|
||||
logger.log(Level.INFO, "......start new conversation, id={0}",
|
||||
conversation.getId());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -90,6 +90,18 @@ public class DataViewDefinitionController extends AbstractDataController {
|
|||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns a unique view URI to be used zu display the View Data.
|
||||
* The uri contains a unique random ID to support caching over different browser
|
||||
* tabs
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getViewURI() {
|
||||
return "/pages/dataviews/data.xhtml?id=" + data.getUniqueID() + "&cacheid=" + System.currentTimeMillis()
|
||||
+ "&faces-redirect=true";
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the current worktItem
|
||||
*
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@
|
|||
<h1><span class="typcn typcn-edit"></span> Query Definition
|
||||
<span style="font-size: 1rem;margin-left:20px;">
|
||||
<h:outputLink
|
||||
value="#{facesContext.externalContext.requestContextPath}/pages/dataviews/data.xhtml?id=#{dataViewDefinitionController.data.uniqueID}&faces-redirect=true"
|
||||
value="#{facesContext.externalContext.requestContextPath}#{dataViewDefinitionController.viewURI}"
|
||||
target="dataview"><span class="typcn typcn-camera-outline"
|
||||
style="font-size: 1.2rem;"></span> Test View
|
||||
</h:outputLink>
|
||||
|
|
@ -182,7 +182,7 @@
|
|||
<h1><span class="typcn typcn-th-list-outline"></span> Form Definition<span
|
||||
style="font-size: 1rem;margin-left:20px;">
|
||||
<h:outputLink
|
||||
value="#{facesContext.externalContext.requestContextPath}/pages/dataviews/data.xhtml?id=#{dataViewDefinitionController.data.uniqueID}&faces-redirect=true"
|
||||
value="#{facesContext.externalContext.requestContextPath}#{dataViewDefinitionController.viewURI}"
|
||||
target="dataview"><span class="typcn typcn-camera-outline"
|
||||
style="font-size: 1.2rem;"></span> Test View
|
||||
</h:outputLink>
|
||||
|
|
@ -213,7 +213,7 @@
|
|||
<h1><span class="typcn typcn-news"></span> Template<span
|
||||
style="font-size: 1rem;margin-left:20px;">
|
||||
<h:outputLink
|
||||
value="#{facesContext.externalContext.requestContextPath}/pages/dataviews/data.xhtml?id=#{dataViewDefinitionController.data.uniqueID}&faces-redirect=true"
|
||||
value="#{facesContext.externalContext.requestContextPath}#{dataViewDefinitionController.viewURI}"
|
||||
target="dataview"><span class="typcn typcn-camera-outline"
|
||||
style="font-size: 1.2rem;"></span> Test View
|
||||
</h:outputLink>
|
||||
|
|
|
|||
|
|
@ -89,13 +89,11 @@
|
|||
</span>
|
||||
</div>
|
||||
|
||||
<h:commandButton actionListener="#{viewHandler.back(dataViewController)}"
|
||||
style="height: 31px;" disabled="#{dataViewController.pageIndex==0}"
|
||||
value="◀◀ #{message.prev}">
|
||||
<h:commandButton actionListener="#{dataViewController.back()}" style="height: 31px;"
|
||||
disabled="#{dataViewController.pageIndex==0}" value="◀◀ #{message.prev}">
|
||||
<f:ajax render="dataview_result_id" onevent="updateDataView" />
|
||||
</h:commandButton>
|
||||
<h:commandButton actionListener="#{viewHandler.forward(dataViewController)}"
|
||||
style="height: 31px;"
|
||||
<h:commandButton actionListener="#{dataViewController.forward()}" style="height: 31px;"
|
||||
disabled="#{dataViewController.endOfList or dataViewController.getTotalPages() le 1}"
|
||||
value="#{message.next} ▶▶">
|
||||
<f:ajax render="dataview_result_id" onevent="updateDataView" />
|
||||
|
|
|
|||
Loading…
Reference in a new issue