From d1677f9c7eb6211563b52ddf31a79b6f9a54d1e2 Mon Sep 17 00:00:00 2001 From: Lorenzo Tilve Date: Fri, 7 Aug 2009 13:39:55 +0200 Subject: [PATCH] ItEr20S06XestionDaComunidadeItEr19S06: Added "ganttzk-demo-webapp" demo site to repository --- ganttzk-demo-webapp/pom.xml | 74 ++++ .../org/navalplanner/web/common/Level.java | 5 + .../web/common/OnlyOneVisible.java | 29 ++ .../org/navalplanner/web/common/Util.java | 312 ++++++++++++++++ .../web/common/components/TwoWaySelector.java | 268 ++++++++++++++ .../common/typeconverters/DateConverter.java | 26 ++ .../web/error/PageForErrorOnEvent.java | 48 +++ .../web/planner/DataForPlanner.java | 206 +++++++++++ .../navalplanner/web/planner/ShareBean.java | 68 ++++ .../web/planner/SplittingController.java | 81 +++++ .../main/resources/metainfo/zk/lang-addon.xml | 14 + .../navalplanner-webapp-spring-config.xml | 28 ++ .../src/main/webapp/META-INF/context.xml | 8 + .../main/webapp/WEB-INF/i3-label.properties | 46 +++ .../webapp/WEB-INF/i3-label_en_US.properties | 46 +++ .../src/main/webapp/WEB-INF/web.xml | 105 ++++++ .../src/main/webapp/WEB-INF/zk.xml | 11 + .../common/components/twowayselector.zul | 42 +++ .../src/main/webapp/common/css/login_v01.css | 46 +++ .../main/webapp/common/css/navalpro_v01.css | 89 +++++ .../main/webapp/common/css/navalpro_zk.css | 117 ++++++ .../src/main/webapp/common/error.jsp | 12 + .../src/main/webapp/common/error.zul | 21 ++ .../src/main/webapp/common/event_error.zul | 14 + .../src/main/webapp/common/img/axuda.gif | Bin 0 -> 1360 bytes .../main/webapp/common/img/degradado_azul.gif | Bin 0 -> 2336 bytes .../src/main/webapp/common/img/flechitas.gif | Bin 0 -> 46 bytes .../main/webapp/common/img/ganttzk-demo.png | Bin 0 -> 4585 bytes .../src/main/webapp/common/img/linea_down.gif | Bin 0 -> 49 bytes .../webapp/common/img/linea_pie_login.gif | Bin 0 -> 47 bytes .../webapp/common/img/logos_aplicacion.gif | Bin 0 -> 8197 bytes .../webapp/common/img/migas_separacion.gif | Bin 0 -> 106 bytes .../src/main/webapp/common/img/pestana1.gif | Bin 0 -> 2523 bytes .../main/webapp/common/img/pestana_activa.gif | Bin 0 -> 2452 bytes .../main/webapp/common/img/pestana_sobre.gif | Bin 0 -> 3006 bytes .../main/webapp/common/img/sub_separacion.gif | Bin 0 -> 59 bytes .../common/layout/template_ganttzk_demo.zul | 46 +++ .../src/main/webapp/common/page_not_found.zul | 19 + .../src/main/webapp/planner/css/ganttzk.css | 335 ++++++++++++++++++ .../src/main/webapp/planner/main.zul | 46 +++ pom.xml | 1 + 41 files changed, 2163 insertions(+) create mode 100644 ganttzk-demo-webapp/pom.xml create mode 100644 ganttzk-demo-webapp/src/main/java/org/navalplanner/web/common/Level.java create mode 100644 ganttzk-demo-webapp/src/main/java/org/navalplanner/web/common/OnlyOneVisible.java create mode 100644 ganttzk-demo-webapp/src/main/java/org/navalplanner/web/common/Util.java create mode 100644 ganttzk-demo-webapp/src/main/java/org/navalplanner/web/common/components/TwoWaySelector.java create mode 100644 ganttzk-demo-webapp/src/main/java/org/navalplanner/web/common/typeconverters/DateConverter.java create mode 100644 ganttzk-demo-webapp/src/main/java/org/navalplanner/web/error/PageForErrorOnEvent.java create mode 100644 ganttzk-demo-webapp/src/main/java/org/navalplanner/web/planner/DataForPlanner.java create mode 100644 ganttzk-demo-webapp/src/main/java/org/navalplanner/web/planner/ShareBean.java create mode 100644 ganttzk-demo-webapp/src/main/java/org/navalplanner/web/planner/SplittingController.java create mode 100755 ganttzk-demo-webapp/src/main/resources/metainfo/zk/lang-addon.xml create mode 100644 ganttzk-demo-webapp/src/main/resources/navalplanner-webapp-spring-config.xml create mode 100644 ganttzk-demo-webapp/src/main/webapp/META-INF/context.xml create mode 100644 ganttzk-demo-webapp/src/main/webapp/WEB-INF/i3-label.properties create mode 100644 ganttzk-demo-webapp/src/main/webapp/WEB-INF/i3-label_en_US.properties create mode 100644 ganttzk-demo-webapp/src/main/webapp/WEB-INF/web.xml create mode 100644 ganttzk-demo-webapp/src/main/webapp/WEB-INF/zk.xml create mode 100644 ganttzk-demo-webapp/src/main/webapp/common/components/twowayselector.zul create mode 100644 ganttzk-demo-webapp/src/main/webapp/common/css/login_v01.css create mode 100644 ganttzk-demo-webapp/src/main/webapp/common/css/navalpro_v01.css create mode 100644 ganttzk-demo-webapp/src/main/webapp/common/css/navalpro_zk.css create mode 100644 ganttzk-demo-webapp/src/main/webapp/common/error.jsp create mode 100644 ganttzk-demo-webapp/src/main/webapp/common/error.zul create mode 100644 ganttzk-demo-webapp/src/main/webapp/common/event_error.zul create mode 100644 ganttzk-demo-webapp/src/main/webapp/common/img/axuda.gif create mode 100644 ganttzk-demo-webapp/src/main/webapp/common/img/degradado_azul.gif create mode 100644 ganttzk-demo-webapp/src/main/webapp/common/img/flechitas.gif create mode 100644 ganttzk-demo-webapp/src/main/webapp/common/img/ganttzk-demo.png create mode 100644 ganttzk-demo-webapp/src/main/webapp/common/img/linea_down.gif create mode 100644 ganttzk-demo-webapp/src/main/webapp/common/img/linea_pie_login.gif create mode 100644 ganttzk-demo-webapp/src/main/webapp/common/img/logos_aplicacion.gif create mode 100644 ganttzk-demo-webapp/src/main/webapp/common/img/migas_separacion.gif create mode 100644 ganttzk-demo-webapp/src/main/webapp/common/img/pestana1.gif create mode 100644 ganttzk-demo-webapp/src/main/webapp/common/img/pestana_activa.gif create mode 100644 ganttzk-demo-webapp/src/main/webapp/common/img/pestana_sobre.gif create mode 100644 ganttzk-demo-webapp/src/main/webapp/common/img/sub_separacion.gif create mode 100644 ganttzk-demo-webapp/src/main/webapp/common/layout/template_ganttzk_demo.zul create mode 100644 ganttzk-demo-webapp/src/main/webapp/common/page_not_found.zul create mode 100644 ganttzk-demo-webapp/src/main/webapp/planner/css/ganttzk.css create mode 100644 ganttzk-demo-webapp/src/main/webapp/planner/main.zul diff --git a/ganttzk-demo-webapp/pom.xml b/ganttzk-demo-webapp/pom.xml new file mode 100644 index 000000000..2ebd74928 --- /dev/null +++ b/ganttzk-demo-webapp/pom.xml @@ -0,0 +1,74 @@ + + + 4.0.0 + + org.navalplanner + navalplanner + 1.0.0 + + ganttzk-demo-webapp + war + Naval Planner Web Client Module + + + ganttzk-demo-webapp + + + + + + org.springframework + spring + + + + org.beanshell + bsh + + + + commons-fileupload + commons-fileupload + + + + org.zkoss.zk + zul + + + org.zkoss.zk + zkplus + + + org.zkoss.zk + zk + + + org.zkoss.zk + zkex + + + + org.navalplanner + navalplanner-gantt-zk + + + org.easymock + easymock + + + junit + junit + + + org.hibernate + hibernate-validator + + + javax.servlet + servlet-api + + + + diff --git a/ganttzk-demo-webapp/src/main/java/org/navalplanner/web/common/Level.java b/ganttzk-demo-webapp/src/main/java/org/navalplanner/web/common/Level.java new file mode 100644 index 000000000..6c5f612e0 --- /dev/null +++ b/ganttzk-demo-webapp/src/main/java/org/navalplanner/web/common/Level.java @@ -0,0 +1,5 @@ +package org.navalplanner.web.common; + +public enum Level { + INFO, WARNING, ERROR; +} \ No newline at end of file diff --git a/ganttzk-demo-webapp/src/main/java/org/navalplanner/web/common/OnlyOneVisible.java b/ganttzk-demo-webapp/src/main/java/org/navalplanner/web/common/OnlyOneVisible.java new file mode 100644 index 000000000..fdc22db90 --- /dev/null +++ b/ganttzk-demo-webapp/src/main/java/org/navalplanner/web/common/OnlyOneVisible.java @@ -0,0 +1,29 @@ +package org.navalplanner.web.common; + +import java.util.Arrays; +import java.util.List; + +import org.zkoss.zk.ui.Component; + +/** + * Utility for enforcing that only one of the supplied component is visible.
+ * @author Óscar González Fernández + */ +public class OnlyOneVisible { + + private List components; + + public OnlyOneVisible(Component... components) { + this.components = Arrays.asList(components); + showOnly(null); + } + + public void showOnly(Component component) { + for (Component c : components) { + if (c != null) { + c.setVisible(component != null && c.equals(component)); + } + } + } + +} diff --git a/ganttzk-demo-webapp/src/main/java/org/navalplanner/web/common/Util.java b/ganttzk-demo-webapp/src/main/java/org/navalplanner/web/common/Util.java new file mode 100644 index 000000000..c6f6c2fe2 --- /dev/null +++ b/ganttzk-demo-webapp/src/main/java/org/navalplanner/web/common/Util.java @@ -0,0 +1,312 @@ +package org.navalplanner.web.common; + +import java.math.BigDecimal; +import java.util.Date; + +import org.zkoss.zk.ui.Component; +import org.zkoss.zk.ui.event.Event; +import org.zkoss.zk.ui.event.EventListener; +import org.zkoss.zk.ui.event.Events; +import org.zkoss.zk.ui.event.InputEvent; +import org.zkoss.zkplus.databind.DataBinder; +import org.zkoss.zul.Checkbox; +import org.zkoss.zul.Datebox; +import org.zkoss.zul.Decimalbox; +import org.zkoss.zul.Intbox; +import org.zkoss.zul.Textbox; + +/** + * Utilities class.
+ * + * @author Óscar González Fernández + * @author Manuel Rego Casasnovas + */ +public class Util { + + public static void reloadBindings(Component... toReload) { + for (Component reload : toReload) { + DataBinder binder = Util.getBinder(reload); + if (binder != null) { + binder.loadComponent(reload); + } + } + } + + public static void saveBindings(Component... toReload) { + for (Component reload : toReload) { + DataBinder binder = Util.getBinder(reload); + if (binder != null) { + binder.saveComponent(reload); + } + } + } + + public static DataBinder getBinder(Component component) { + return (DataBinder) component.getVariable("binder", false); + } + + /** + * Generic interface to represent a class with a typical get method. + * + * @author Manuel Rego Casasnovas + * + * @param + * The type of the variable to be returned. + */ + public static interface Getter { + /** + * Typical get method that returns a variable. + * + * @return A variable of type . + */ + public T get(); + } + + /** + * Generic interface to represent a class with a typical set method. + * + * @author Manuel Rego Casasnovas + * + * @param + * The type of the variable to be set. + */ + public static interface Setter { + /** + * Typical set method to store a variable. + * + * @param value + * A variable of type to be set. + */ + public void set(T value); + } + + /** + * Binds a {@link Textbox} with a {@link Getter}. The {@link Getter} will be + * used to get the value that is going to be showed in the {@link Textbox}. + * + * @param textBox + * The {@link Textbox} to be bound + * @param getter + * The {@link Getter} interface that will implement a get method. + * @return The {@link Textbox} bound + */ + public static Textbox bind(Textbox textBox, Getter getter) { + textBox.setValue(getter.get()); + textBox.setDisabled(true); + return textBox; + } + + /** + * Binds a {@link Textbox} with a {@link Getter}. The {@link Getter} will be + * used to get the value that is going to be showed in the {@link Textbox}. + * The {@link Setter} will be used to store the value inserted by the user + * in the {@link Textbox}. + * + * @param textBox + * The {@link Textbox} to be bound + * @param getter + * The {@link Getter} interface that will implement a get method. + * @param setter + * The {@link Setter} interface that will implement a set method. + * @return The {@link Textbox} bound + */ + public static Textbox bind(final Textbox textBox, + final Getter getter, final Setter setter) { + textBox.setValue(getter.get()); + textBox.addEventListener("onChange", new EventListener() { + + @Override + public void onEvent(Event event) throws Exception { + InputEvent newInput = (InputEvent) event; + String value = newInput.getValue(); + setter.set(value); + textBox.setValue(getter.get()); + } + }); + return textBox; + } + + /** + * Binds a {@link Intbox} with a {@link Getter}. The {@link Getter} will be + * used to get the value that is going to be showed in the {@link Intbox}. + * + * @param intBox + * The {@link Intbox} to be bound + * @param getter + * The {@link Getter} interface that will implement a get method. + * @return The {@link Intbox} bound + */ + public static Intbox bind(Intbox intBox, Getter getter) { + intBox.setValue(getter.get()); + intBox.setDisabled(true); + return intBox; + } + + /** + * Binds a {@link Intbox} with a {@link Getter}. The {@link Getter} will be + * used to get the value that is going to be showed in the {@link Intbox}. + * The {@link Setter} will be used to store the value inserted by the user + * in the {@link Intbox}. + * + * @param intBox + * The {@link Intbox} to be bound + * @param getter + * The {@link Getter} interface that will implement a get method. + * @param setter + * The {@link Setter} interface that will implement a set method. + * @return The {@link Intbox} bound + */ + public static Intbox bind(final Intbox intBox, + final Getter getter, final Setter setter) { + intBox.setValue(getter.get()); + intBox.addEventListener("onChange", new EventListener() { + + @Override + public void onEvent(Event event) throws Exception { + InputEvent newInput = (InputEvent) event; + String value = newInput.getValue(); + setter.set(Integer.valueOf(value)); + intBox.setValue(getter.get()); + } + }); + return intBox; + } + + /** + * Binds a {@link Datebox} with a {@link Getter}. The {@link Getter} will be + * used to get the value that is going to be showed in the {@link Datebox}. + * + * @param dateBox + * The {@link Datebox} to be bound + * @param getter + * The {@link Getter} interface that will implement a get method. + * @return The {@link Datebox} bound + */ + public static Datebox bind(final Datebox dateBox, + final Getter getter) { + dateBox.setValue(getter.get()); + dateBox.setDisabled(true); + return dateBox; + } + + /** + * Binds a {@link Datebox} with a {@link Getter}. The {@link Getter} will be + * used to get the value that is going to be showed in the {@link Datebox}. + * The {@link Setter} will be used to store the value inserted by the user + * in the {@link Datebox}. + * + * @param dateBox + * The {@link Datebox} to be bound + * @param getter + * The {@link Getter} interface that will implement a get method. + * @param setter + * The {@link Setter} interface that will implement a set method. + * @return The {@link Datebox} bound + */ + public static Datebox bind(final Datebox dateBox, + final Getter getter, final Setter setter) { + dateBox.setValue(getter.get()); + dateBox.addEventListener("onChange", new EventListener() { + + @Override + public void onEvent(Event event) throws Exception { + setter.set(dateBox.getValue()); + dateBox.setValue(getter.get()); + } + }); + return dateBox; + } + + /** + * Binds a {@link Decimalbox} with a {@link Getter}. The {@link Getter} will + * be used to get the value that is going to be showed in the + * {@link Decimalbox}. + * + * @param decimalBox + * The {@link Decimalbox} to be bound + * @param getter + * The {@link Getter} interface that will implement a get method. + * @return The {@link Decimalbox} bound + */ + public static Decimalbox bind(final Decimalbox decimalBox, + final Getter getter) { + decimalBox.setValue(getter.get()); + decimalBox.setDisabled(true); + return decimalBox; + } + + /** + * Binds a {@link Decimalbox} with a {@link Getter}. The {@link Getter} will + * be used to get the value that is going to be showed in the + * {@link Decimalbox}. The {@link Setter} will be used to store the value + * inserted by the user in the {@link Decimalbox}. + * + * @param decimalBox + * The {@link Decimalbox} to be bound + * @param getter + * The {@link Getter} interface that will implement a get method. + * @param setter + * The {@link Setter} interface that will implement a set method. + * @return The {@link Decimalbox} bound + */ + public static Decimalbox bind(final Decimalbox decimalBox, + final Getter getter, final Setter setter) { + decimalBox.setValue(getter.get()); + decimalBox.addEventListener("onChange", new EventListener() { + + @Override + public void onEvent(Event event) throws Exception { + setter.set(decimalBox.getValue()); + decimalBox.setValue(getter.get()); + } + }); + return decimalBox; + } + + /** + * Binds a {@link Checkbox} with a {@link Getter}. The {@link Getter} will + * be used to get the value that is going to be showed in the + * {@link Checkbox}. + * + * @param decimalBox + * The {@link Checkbox} to be bound + * @param getter + * The {@link Getter} interface that will implement a get method. + * @return The {@link Checkbox} bound + */ + public static Checkbox bind(final Checkbox checkBox, + final Getter getter) { + checkBox.setChecked(getter.get()); + checkBox.setDisabled(true); + return checkBox; + } + + /** + * Binds a {@link Checkbox} with a {@link Getter}. The {@link Getter} will + * be used to get the value that is going to be showed in the + * {@link Checkbox}. The {@link Setter} will be used to store the value + * inserted by the user in the {@link Checkbox}. + * + * @param decimalBox + * The {@link Checkbox} to be bound + * @param getter + * The {@link Getter} interface that will implement a get method. + * @param setter + * The {@link Setter} interface that will implement a set method. + * @return The {@link Checkbox} bound + */ + public static Checkbox bind(final Checkbox checkBox, + final Getter getter, final Setter setter) { + checkBox.setChecked(getter.get()); + checkBox.addEventListener(Events.ON_CHECK, new EventListener() { + + @Override + public void onEvent(Event event) throws Exception { + setter.set(checkBox.isChecked()); + checkBox.setChecked(getter.get()); + } + }); + return checkBox; + } + +} diff --git a/ganttzk-demo-webapp/src/main/java/org/navalplanner/web/common/components/TwoWaySelector.java b/ganttzk-demo-webapp/src/main/java/org/navalplanner/web/common/components/TwoWaySelector.java new file mode 100644 index 000000000..d6c7e5f1a --- /dev/null +++ b/ganttzk-demo-webapp/src/main/java/org/navalplanner/web/common/components/TwoWaySelector.java @@ -0,0 +1,268 @@ +package org.navalplanner.web.common.components; + +import java.beans.BeanInfo; +import java.beans.IntrospectionException; +import java.beans.Introspector; +import java.beans.PropertyDescriptor; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.navalplanner.web.common.Util; +import org.zkoss.lang.Objects; +import org.zkoss.zk.ui.HtmlMacroComponent; +import org.zkoss.zul.Listbox; +import org.zkoss.zul.Listcell; +import org.zkoss.zul.Listitem; +import org.zkoss.zul.ListitemRenderer; + +/** + * ZK macro component that shows two {@link Listbox} allowing to move objects + * between each other. + * + * In the {@link Listbox} on the left you will have the assigned objects and in + * the right the possible other objects to be assigned. + * + * Finally it provides methods to get the current assigned and unassigned + * objects. + * + * @author Manuel Rego Casasnovas + */ +public class TwoWaySelector extends HtmlMacroComponent { + + /** + * A {@link Set} of objects that are assigned (so they're shown on the left + * {@link Listbox}) + */ + private Set assignedObjects = new HashSet(); + + /** + * Title for the left {@link Listbox} (where assigned objects are shown) + */ + private String assignedTitle = "Assigned"; + + /** + * A {@link Set} of objects that are not assigned (so they're shown on the + * right {@link Listbox}) + */ + private Set unassignedObjects = new HashSet(); + + /** + * Title for the right {@link Listbox} (where unassigned objects are shown) + */ + private String unassignedTitle = "Unassigned"; + + /** + * A {@link List} of properties to be shown on the {@link Listbox} for each + * object. + */ + private List columns = null; + + /** + * {@link ListitemRenderer} that knows how to paint an object according to + * the {@link List} stored in the columns attribute. If columns is null then + * the object will be rendered as a string. + * + * @author Manuel Rego Casasnovas + */ + private ListitemRenderer renderer = new ListitemRenderer() { + @Override + public void render(Listitem item, Object data) throws Exception { + + Class klass = data.getClass(); + Map propertiesByName = getProperties(klass); + + // If a list of attributes is defined + if (columns != null) { + // For each attribute + for (String column : columns) { + // Call the method to get the information + PropertyDescriptor propertyDescriptor = propertiesByName + .get(column); + if (propertyDescriptor == null) { + throw new RuntimeException( + "Unknown attribute '" + + column + "' in class " + klass.getName()); + } + + String label = Objects.toString(propertyDescriptor + .getReadMethod().invoke(data)); + + // Add a new Listcell + item.appendChild(new Listcell(label)); + } + } else { // If the list of attributes is not defined + // Render the object as string + item.setLabel(Objects.toString(data)); + } + + item.setValue(data); + } + + /** + * A {@link Map} that stores the information about the attributes for a + * class. + * + * The information about attributes is stored with another Map where + * keys are the properties name and the values the + * {@link PropertyDescriptor}. + */ + private Map, Map> propertiesMapsCached = new HashMap, Map>(); + + /** + * Creates a {@link Map} that relates the properties and their + * {@link PropertyDescriptor} from the {@link BeanInfo}. + * + * @param info + * Information about the bean + * @return A {@link Map} that relates properties name and + * {@link PropertyDescriptor} + */ + private Map buildPropertyDescriptorsMap( + BeanInfo info) { + PropertyDescriptor[] propertyDescriptors = info + .getPropertyDescriptors(); + Map propertiesByName = new HashMap(); + for (PropertyDescriptor propertyDescriptor : propertyDescriptors) { + propertiesByName.put(propertyDescriptor.getName(), + propertyDescriptor); + } + return propertiesByName; + } + + /** + * Gets the attributes of a {@link Class} together with the + * {@link PropertyDescriptor} of each property. + * + * @param klass + * The {@link Class} to get the properties + * @return A {@link Map} that relates properties name and + * {@link PropertyDescriptor} + * @throws IntrospectionException + */ + private Map getProperties( + Class klass) throws IntrospectionException { + // If it's already cached + if (propertiesMapsCached.containsKey(klass)) { + return propertiesMapsCached.get(klass); + } + + BeanInfo beanInfo = Introspector.getBeanInfo(klass); + Map result = buildPropertyDescriptorsMap(beanInfo); + + // Store in cache + propertiesMapsCached.put(klass, result); + + return result; + } + }; + + public void setAssignedTitle(String assignedTitle) { + if (assignedTitle != null) { + this.assignedTitle = assignedTitle; + } + } + + public String getAssignedTitle() { + return assignedTitle; + } + + public void setUnassignedTitle(String unassignedTitle) { + if (unassignedTitle != null) { + this.unassignedTitle = unassignedTitle; + } + } + + public String getUnassignedTitle() { + return unassignedTitle; + } + + public void setAssignedObjects(Set assignedObjects) { + if (assignedObjects != null) { + this.assignedObjects = assignedObjects; + } + } + + public Set getAssignedObjects() { + return assignedObjects; + } + + public void setUnassignedObjects(Set unassignedObjects) { + if (assignedObjects != null) { + this.unassignedObjects = unassignedObjects; + } + } + + public Set getUnassignedObjects() { + return unassignedObjects; + } + + /** + * Sets the list of attributes to be shown when an object is renderer. + * + * @param columns + * A comma-separated string + */ + public void setColumns(String columns) { + if (columns != null) { + // Remove white spaces + columns = columns.replaceAll("\\s", ""); + + if (!columns.isEmpty()) { + // Split the string + this.columns = Arrays.asList(columns.split(",")); + } + } + } + + public List getColumns() { + return columns; + } + + public ListitemRenderer getRenderer() { + return renderer; + } + + /** + * Assign (move to the left {@link Listbox}) the selected items from the + * right {@link Listbox}. And reload both {@link Listbox} in order to + * relfect the changes. + * + * @param unassignedObjectsListbox + * The right {@link Listbox} + */ + public void assign(Listbox unassignedObjectsListbox) { + Set selectedItems = unassignedObjectsListbox + .getSelectedItems(); + for (Listitem listitem : selectedItems) { + Object value = listitem.getValue(); + unassignedObjects.remove(value); + assignedObjects.add(value); + } + Util.reloadBindings(unassignedObjectsListbox.getParent()); + Util.saveBindings(this); + } + + /** + * Unassign (move to the rigth {@link Listbox}) the selected items from the + * left {@link Listbox}. And reload both {@link Listbox} in order to relfect + * the changes. + * + * @param assignedObjectsListbox + * The left {@link Listbox} + */ + public void unassign(Listbox assignedObjectsListbox) { + Set selectedItems = assignedObjectsListbox.getSelectedItems(); + for (Listitem listitem : selectedItems) { + Object value = listitem.getValue(); + assignedObjects.remove(value); + unassignedObjects.add(value); + } + Util.reloadBindings(assignedObjectsListbox.getParent()); + Util.saveBindings(this); + } + +} \ No newline at end of file diff --git a/ganttzk-demo-webapp/src/main/java/org/navalplanner/web/common/typeconverters/DateConverter.java b/ganttzk-demo-webapp/src/main/java/org/navalplanner/web/common/typeconverters/DateConverter.java new file mode 100644 index 000000000..208e28c54 --- /dev/null +++ b/ganttzk-demo-webapp/src/main/java/org/navalplanner/web/common/typeconverters/DateConverter.java @@ -0,0 +1,26 @@ +package org.navalplanner.web.common.typeconverters; + +import java.text.SimpleDateFormat; +import java.util.Date; + +import org.zkoss.zk.ui.Component; +import org.zkoss.zkplus.databind.TypeConverter; + +/** + * Converter for the type java.util.Date + * + * @author Diego Pino Garcia + * + */ +public class DateConverter implements TypeConverter { + + @Override + public Object coerceToBean(Object arg0, Component arg1) { + return null; + } + + @Override + public Object coerceToUi(Object object, Component component) { + return (new SimpleDateFormat("dd/MM/yyyy")).format((Date) object); + } +} diff --git a/ganttzk-demo-webapp/src/main/java/org/navalplanner/web/error/PageForErrorOnEvent.java b/ganttzk-demo-webapp/src/main/java/org/navalplanner/web/error/PageForErrorOnEvent.java new file mode 100644 index 000000000..91c042e33 --- /dev/null +++ b/ganttzk-demo-webapp/src/main/java/org/navalplanner/web/error/PageForErrorOnEvent.java @@ -0,0 +1,48 @@ +package org.navalplanner.web.error; + +import javax.servlet.http.HttpServletRequest; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.zkoss.zk.ui.Component; +import org.zkoss.zk.ui.Executions; +import org.zkoss.zk.ui.util.GenericForwardComposer; + +public class PageForErrorOnEvent extends GenericForwardComposer { + + private static final Log LOG = LogFactory.getLog(PageForErrorOnEvent.class); + + private Component modalWindow; + + @Override + public void doAfterCompose(Component comp) throws Exception { + super.doAfterCompose(comp); + logError(); + modalWindow = comp; + + } + + private void logError() { + Throwable exception = (Throwable) Executions.getCurrent().getAttribute( + "javax.servlet.error.exception"); + String errorMessage = (String) Executions.getCurrent().getAttribute( + "javax.servlet.error.message"); + LOG.error(errorMessage, exception); + } + + public void onClick$continueWorking() { + modalWindow.detach(); + } + + public void onClick$reload() { + Executions.sendRedirect(null); + } + + public void onClick$quitSession() { + HttpServletRequest nativeRequest = (HttpServletRequest) Executions + .getCurrent().getNativeRequest(); + nativeRequest.getSession().invalidate(); + Executions.sendRedirect("/"); + } + +} diff --git a/ganttzk-demo-webapp/src/main/java/org/navalplanner/web/planner/DataForPlanner.java b/ganttzk-demo-webapp/src/main/java/org/navalplanner/web/planner/DataForPlanner.java new file mode 100644 index 000000000..642b269ca --- /dev/null +++ b/ganttzk-demo-webapp/src/main/java/org/navalplanner/web/planner/DataForPlanner.java @@ -0,0 +1,206 @@ +package org.navalplanner.web.planner; + +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.List; + +import org.zkoss.ganttz.TaskEditFormComposer; +import org.zkoss.ganttz.adapters.AutoAdapter; +import org.zkoss.ganttz.adapters.DomainDependency; +import org.zkoss.ganttz.adapters.IStructureNavigator; +import org.zkoss.ganttz.adapters.PlannerConfiguration; +import org.zkoss.ganttz.data.DefaultFundamentalProperties; +import org.zkoss.ganttz.data.DependencyType; +import org.zkoss.ganttz.data.GanttDiagramGraph; +import org.zkoss.ganttz.data.ITaskFundamentalProperties; +import org.zkoss.ganttz.data.Task; +import org.zkoss.ganttz.data.TaskContainer; +import org.zkoss.ganttz.data.TaskLeaf; +import org.zkoss.ganttz.extensions.ICommand; +import org.zkoss.ganttz.extensions.ICommandOnTask; +import org.zkoss.ganttz.extensions.IContext; +import org.zkoss.ganttz.extensions.IContextWithPlannerTask; + +/** + * Some test data for planner
+ * @author Óscar González Fernández + */ +public class DataForPlanner { + + private TaskEditFormComposer taskEditForm = new TaskEditFormComposer(); + + public DataForPlanner() { + + } + + public GanttDiagramGraph getEmpty() { + return new GanttDiagramGraph(); + } + + private PlannerConfiguration addCommands( + PlannerConfiguration configuration) { + configuration + .addGlobalCommand(new ICommand() { + + @Override + public String getName() { + return "Add Task"; + } + + @Override + public void doAction( + IContext context) { + addNewTask(context); + } + }); + configuration + .setGoingDownInLastArrowCommand(new ICommand() { + + @Override + public void doAction( + IContext context) { + addNewTask(context); + } + + @Override + public String getName() { + return ""; + } + }); + configuration + .addCommandOnTask(new ICommandOnTask() { + @Override + public void doAction( + IContextWithPlannerTask context, + ITaskFundamentalProperties task) { + context.remove(task); + } + + @Override + public String getName() { + return "Remove"; + } + + }); + configuration.setEditTaskCommand(new ICommandOnTask() { + + @Override + public void doAction( + IContextWithPlannerTask context, + ITaskFundamentalProperties task) { + taskEditForm.showEditFormFor(context.getRelativeTo(), + context.getTask()); + } + + @Override + public String getName() { + return ""; + } + }); + return configuration; + } + + public PlannerConfiguration getLightLoad() { + return addCommands(getModelWith(20)); + } + + public PlannerConfiguration getMediumLoad() { + return addCommands(getModelWith(300)); + } + + public PlannerConfiguration getHighLoad() { + return addCommands(getModelWith(500)); + } + + private PlannerConfiguration getModelWith( + int tasksToCreate) { + List list = new ArrayList(); + Date now = new Date(); + Date end = twoMonthsLater(now); + final ITaskFundamentalProperties container = createTask("container", + now, end); + final List containerChildren = new ArrayList(); + final ITaskFundamentalProperties child1 = createTask("child 1", now, + end); + containerChildren.add(child1); + final DefaultFundamentalProperties child2 = createTask("another", now, + end); + containerChildren.add(child2); + list.add(container); + final ITaskFundamentalProperties first = createTask("tarefa1", now, end); + final ITaskFundamentalProperties second = createTask("tarefa2", now, + end); + list.add(first); + list.add(second); + for (int i = 2; i < tasksToCreate - 3; i++) { + String name = "tarefa " + (i + 1); + ITaskFundamentalProperties task = createTask(name, now, end); + list.add(task); + } + IStructureNavigator navigator = new IStructureNavigator() { + + @Override + public List getChildren( + ITaskFundamentalProperties object) { + if (object == container) + return containerChildren; + return new ArrayList(); + } + + @Override + public boolean isLeaf(ITaskFundamentalProperties object) { + return object != container; + } + }; + return new PlannerConfiguration( + new AutoAdapter() { + @Override + public List> getOutcomingDependencies( + ITaskFundamentalProperties object) { + List> result = new ArrayList>(); + if (child1 == object) { + result.add(DomainDependency.createDependency( + child1, child2, DependencyType.END_START)); + } else if (first == object) { + result.add(DomainDependency.createDependency(first, + second, DependencyType.END_START)); + } + return result; + } + }, navigator, list); + } + + private TaskContainer createContainer(String name, Date start, Date end) { + TaskContainer container = new TaskContainer(); + container.setBeginDate(start); + container.setEndDate(end); + container.setName(name); + return container; + } + + private DefaultFundamentalProperties createTask(String name, Date now, + Date end) { + return new DefaultFundamentalProperties(name, end, end.getTime() + - now.getTime(), "bla"); + } + + private void addNewTask(IContext context) { + Task newTask = new TaskLeaf(); + newTask.setName("Nova Tarefa"); + newTask.setBeginDate(new Date()); + newTask.setEndDate(twoMonthsLater(newTask.getBeginDate())); + context.add(newTask); + } + + private static Date twoMonthsLater(Date now) { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(now); + calendar.add(Calendar.MONTH, 2); + return calendar.getTime(); + } + + public TaskEditFormComposer getTaskEditForm() { + return taskEditForm; + } +} diff --git a/ganttzk-demo-webapp/src/main/java/org/navalplanner/web/planner/ShareBean.java b/ganttzk-demo-webapp/src/main/java/org/navalplanner/web/planner/ShareBean.java new file mode 100644 index 000000000..c650fad52 --- /dev/null +++ b/ganttzk-demo-webapp/src/main/java/org/navalplanner/web/planner/ShareBean.java @@ -0,0 +1,68 @@ +package org.navalplanner.web.planner; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang.Validate; + +public class ShareBean { + + public static int[] toHours(ShareBean... shares) { + Validate.noNullElements(shares); + int[] result = new int[shares.length]; + for (int i = 0; i < result.length; i++) { + result[i] = shares[i].getHours(); + } + return result; + } + + public static int sum(Collection shareBeans) { + Validate.noNullElements(shareBeans); + int result = 0; + for (ShareBean shareBean : shareBeans) { + result += shareBean.getHours(); + } + return result; + } + + public static List toShareBeans(String name, int[] hours) { + ArrayList result = new ArrayList(); + for (int i = 0; i < hours.length; i++) { + ShareBean s = new ShareBean(); + s.setName(name + "." + (i + 1)); + s.setHours(hours[i]); + result.add(s); + } + return result; + } + + private String name; + + private Integer hours; + + public ShareBean() { + } + + public String getName() { + return name; + } + + public void setName(String name) { + if (StringUtils.isEmpty(name)) + return; + this.name = name; + } + + public Integer getHours() { + return hours; + } + + public void setHours(Integer share) { + if (share == null || share <= 0) + return; + this.hours = share; + } + +} diff --git a/ganttzk-demo-webapp/src/main/java/org/navalplanner/web/planner/SplittingController.java b/ganttzk-demo-webapp/src/main/java/org/navalplanner/web/planner/SplittingController.java new file mode 100644 index 000000000..bc0810446 --- /dev/null +++ b/ganttzk-demo-webapp/src/main/java/org/navalplanner/web/planner/SplittingController.java @@ -0,0 +1,81 @@ +package org.navalplanner.web.planner; + +import java.util.List; + +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; +import org.zkoss.zk.ui.WrongValueException; +import org.zkoss.zk.ui.util.Clients; +import org.zkoss.zk.ui.util.GenericForwardComposer; +import org.zkoss.zul.Label; +import org.zkoss.zul.SimpleListModel; +import org.zkoss.zul.Window; +import org.zkoss.zul.api.Grid; + +@Component +@Scope(BeanDefinition.SCOPE_PROTOTYPE) +public class SplittingController extends GenericForwardComposer { + + private IActionOnOk curentAction; + private Window window; + + private Grid sharesListing; + + private Label totalHoursLabel; + private List sharesList; + private Integer totalHours; + + public interface IActionOnOk { + public void doOkAction(ShareBean[] shares); + } + + public void show(List initialSharesList, Integer totalHours, + IActionOnOk ok) { + this.sharesList = initialSharesList; + this.totalHours = totalHours; + this.curentAction = ok; + this.totalHoursLabel.setValue(totalHours + ""); + this.sharesListing.setModel(new SimpleListModel(initialSharesList)); + showWindow(); + } + + public void onClick$splitOk() { + checkSumIsEqualToTotal(); + Clients.closeErrorBox(totalHoursLabel); + hideWindow(); + curentAction.doOkAction(this.sharesList.toArray(new ShareBean[0])); + } + + private void checkSumIsEqualToTotal() { + int sum = ShareBean.sum(sharesList); + if (sum != totalHours) { + throw new WrongValueException(totalHoursLabel, + "the sum is not equal: " + sum); + } + } + + public void onClick$splitCancel() { + hideWindow(); + } + + private void showWindow() { + try { + window.setMode("modal"); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + } + + private void hideWindow() { + window.setVisible(false); + } + + @Override + public void doAfterCompose(org.zkoss.zk.ui.Component comp) throws Exception { + super.doAfterCompose(comp); + window = (Window) comp; + + } + +} diff --git a/ganttzk-demo-webapp/src/main/resources/metainfo/zk/lang-addon.xml b/ganttzk-demo-webapp/src/main/resources/metainfo/zk/lang-addon.xml new file mode 100755 index 000000000..ad28e0255 --- /dev/null +++ b/ganttzk-demo-webapp/src/main/resources/metainfo/zk/lang-addon.xml @@ -0,0 +1,14 @@ + + + + + navalplanner-webapp + xul/html + + + twowayselector + org.navalplanner.web.common.components.TwoWaySelector + /common/components/twowayselector.zul + + + \ No newline at end of file diff --git a/ganttzk-demo-webapp/src/main/resources/navalplanner-webapp-spring-config.xml b/ganttzk-demo-webapp/src/main/resources/navalplanner-webapp-spring-config.xml new file mode 100644 index 000000000..acf049dd7 --- /dev/null +++ b/ganttzk-demo-webapp/src/main/resources/navalplanner-webapp-spring-config.xml @@ -0,0 +1,28 @@ + + + + + + + + + + + + diff --git a/ganttzk-demo-webapp/src/main/webapp/META-INF/context.xml b/ganttzk-demo-webapp/src/main/webapp/META-INF/context.xml new file mode 100644 index 000000000..2811d9186 --- /dev/null +++ b/ganttzk-demo-webapp/src/main/webapp/META-INF/context.xml @@ -0,0 +1,8 @@ + + + + + + diff --git a/ganttzk-demo-webapp/src/main/webapp/WEB-INF/i3-label.properties b/ganttzk-demo-webapp/src/main/webapp/WEB-INF/i3-label.properties new file mode 100644 index 000000000..e86778d96 --- /dev/null +++ b/ganttzk-demo-webapp/src/main/webapp/WEB-INF/i3-label.properties @@ -0,0 +1,46 @@ +task.name=Nome +task.start=Comezo +task.end=Final +task.notes=Notas +task.ok=Aceptar +listdetails.add_task=Engadir +task.new_task_name=Nova Tarefa +DETAIL_ONE=Detalle 1 +DETAIL_TWO=Detalle 2 +DETAIL_THREE=Detalle 3 +DETAIL_FOUR=Detalle 4 +mainmenu.new=Novo +mainmenu.open=Abrir +mainmenu.save=Gardar +mainmenu.project=Proxecto +mainmenu.exit=Saír +mainmenu.resources=Recursos +mainmenu.list_workers=Lista traballadores +mainmenu.add_resources=Engadir recurso +mainmenu.manage_resources=Administrar recursos +mainmenu.check_plannification=Revisar conflitos de planificación +mainmenu.plannification=Planificación +mainmenu.add_task=Engadir tarefa +mainmenu.manage_tasks=Administrar tarefas +mainmenu.set_complection_data=Establecer nivel de complección +mainmenu.add_dependency=Engadir dependencia +mainmenu.manage_dependencies=Administrar dependencias +mainmenu.help=Axuda +mainmenu.about=Acerca de +mainmenu.aclunaga=Aclunaga +mainmenu.manage_criterions=Administrar criterios +mainmenu.orders=Pedidos +mainmenu.list_orders=Lista de pedidos +mainmenu.company_overview=Vista de empresa +mainmenu.plannifications_list=Listado de planificacións +mainmenu.manage_machines=Xestionar máquinas +mainmenu.activity_work_types=Tipos de actividad de traballo +mainmenu.models=Modelos +mainmenu.work_reports=Partes de traballo +mainmenu.work_report_list=Listado de partes de traballo +mainmenu.work_report_types=Tipos de partes de traballo +mainmenu.work_report_import=Importación de partes de traballo +mainmenu.administration=Administración +mainmenu.manage_users=Xestionar usuarios e permisos +mainmenu.quality_management=Xestión da calidade +mainmenu.manageAdvancesTypes=Xestionar tipos de avance \ No newline at end of file diff --git a/ganttzk-demo-webapp/src/main/webapp/WEB-INF/i3-label_en_US.properties b/ganttzk-demo-webapp/src/main/webapp/WEB-INF/i3-label_en_US.properties new file mode 100644 index 000000000..be5fc1657 --- /dev/null +++ b/ganttzk-demo-webapp/src/main/webapp/WEB-INF/i3-label_en_US.properties @@ -0,0 +1,46 @@ +task.name=Name +task.start=Start +task.end=End +task.notes=Notes +task.ok=Ok +listdetails.add_task=Add +task.new_task_name=New Task +DETAIL_ONE=Detail 1 +DETAIL_TWO=Detail 2 +DETAIL_THREE=Detail 3 +DETAIL_FOUR=Detail 4 +mainmenu.new=New +mainmenu.open=Open +mainmenu.save=Save +mainmenu.project=Project +mainmenu.exit=Exit +mainmenu.resources=Resources +mainmenu.list_workers=Workers list +mainmenu.add_resources=Add resource +mainmenu.manage_resources=Manage resources +mainmenu.check_plannification=Check for plannification conflicts +mainmenu.plannification=Plannification +mainmenu.add_task=Add task +mainmenu.manage_tasks=Manage tasks +mainmenu.set_complection_data=Set complection data +mainmenu.add_dependency=Add dependency +mainmenu.manage_dependencies=Manage dependences +mainmenu.help=Help +mainmenu.about=About +mainmenu.aclunaga=Aclunaga +mainmenu.manage_criterions=Manage criterions +mainmenu.orders=Orders +mainmenu.list_orders=Orders list +mainmenu.company_overview=Company overview +mainmenu.plannifications_list=Plannifications list +mainmenu.manage_machines=Manage machines +mainmenu.activity_work_types=Activity work types +mainmenu.models=Models +mainmenu.work_reports=Work reports +mainmenu.work_report_list=Work report list +mainmenu.work_report_types=Work report types +mainmenu.work_report_import=Work report importation +mainmenu.administration=Administration +mainmenu.manage_users=Manage users and permissions +mainmenu.quality_management=Quality management +mainmenu.manageAdvancesTypes=Manage Advance types \ No newline at end of file diff --git a/ganttzk-demo-webapp/src/main/webapp/WEB-INF/web.xml b/ganttzk-demo-webapp/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 000000000..2e3200426 --- /dev/null +++ b/ganttzk-demo-webapp/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,105 @@ + + + ganttzk-demo-webapp + + + + contextConfigLocation + classpath*:/navalplanner-override-spring-config.xml + + + + + + + + dspLoader + org.zkoss.web.servlet.dsp.InterpreterServlet + + + dspLoader + *.dsp + + + + + + + Used to cleanup when a session is destroyed + ZK Session Cleaner + org.zkoss.zk.ui.http.HttpSessionListener + + + + + + org.springframework.web.context.ContextLoaderListener + + + + org.springframework.web.context.request.RequestContextListener + + + + + + + + + ZK loader for ZUML pages + zkLoader + org.zkoss.zk.ui.http.DHtmlLayoutServlet + + + update-uri + /zkau + + 1 + + + zkLoader + *.zul + + + zkLoader + *.zhtml + + + The asynchronous update engine for ZK + auEngine + org.zkoss.zk.au.http.DHtmlUpdateServlet + + + auEngine + /zkau/* + + + + + /planner/main.zul + + + + java.lang.Throwable + /common/error.zul + + + + 404 + /common/page_not_found.zul + + diff --git a/ganttzk-demo-webapp/src/main/webapp/WEB-INF/zk.xml b/ganttzk-demo-webapp/src/main/webapp/WEB-INF/zk.xml new file mode 100644 index 000000000..d0ed26c16 --- /dev/null +++ b/ganttzk-demo-webapp/src/main/webapp/WEB-INF/zk.xml @@ -0,0 +1,11 @@ + + + + + + java.lang.Throwable + + /common/event_error.zul + + + diff --git a/ganttzk-demo-webapp/src/main/webapp/common/components/twowayselector.zul b/ganttzk-demo-webapp/src/main/webapp/common/components/twowayselector.zul new file mode 100644 index 000000000..f79bb275e --- /dev/null +++ b/ganttzk-demo-webapp/src/main/webapp/common/components/twowayselector.zul @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ganttzk-demo-webapp/src/main/webapp/common/event_error.zul b/ganttzk-demo-webapp/src/main/webapp/common/event_error.zul new file mode 100644 index 000000000..2e9b46a5f --- /dev/null +++ b/ganttzk-demo-webapp/src/main/webapp/common/event_error.zul @@ -0,0 +1,14 @@ + + + Prodúxose un erro na execución: + "${requestScope['javax.servlet.error.message']}". O erro + gardouse e procurarase arreglalo no menor tempo posible. + + + + + diff --git a/ganttzk-demo-webapp/src/main/webapp/common/img/axuda.gif b/ganttzk-demo-webapp/src/main/webapp/common/img/axuda.gif new file mode 100644 index 0000000000000000000000000000000000000000..f9e71a75261ce4b4d8860b63f7cb68cde37440c1 GIT binary patch literal 1360 zcmV-W1+V%?Nk%w1VHW@x0QUd@|NsC0{`&p>{_^thT7cCPR5 z?Vq8d`}_Ly^YUC_V)pj+`uFeg@$dit_vPyGYLLVK|NV`r&h_>4b$EFvRh2Yenm$8C z%hclh{QNjRKs;of?(Xeulg1}ss?yrzk*(1$WUTr5_eDxf_xJXGo5WXwxqX$mLv^?R z{`h{L$Sh>9{{H=+uEyHn=eEPy^YZRXdb*0C#Q*>P@$vEP?dz1W)Kywr^z-x@Q=+I`kk;YkFUiiQ5r>p<>usTZ*cMQ@hxAZ zS9z)V`S|1F-d=>bXpX`E{qsa-mi_tjoUqMMR95}^@`{d*CtIXti@n$0>G%2j$kX5) zO_Hm+(O@$>fA*w>V+%!#JU;^*uA{P{m)mg?&2Nph`|sK(>y@BI4phnu;+ z!N33c@Vvdf{`v1RQiEH9xLt?8v9z^Le!aK3xl(tn^!4?)#o6uc?UtCCi=MgTysI|-f{`_5mwf_0@q^75Xq|QKbvLHly z*xK2owa)wa^e|P|#nRzNcC?nQ%V37OX@{}3 z$lY(0#w{{5Gh?Ux`SJh${_yecV~xY!nM{ug~@$4{Usx)S*J!`1^{Q6Q>SiQ;IScSk*bf^CO^;dwl zf}zPNP>8I)*Xru#U45(a@$tRM+TY&YPk6C`qs{d5@3O<$I&HDx;9)C6c6w5WS>O5u%n3RV3=ISwlt7wsQzTa+u;q2N?qa4g@GdY+n#T2{M#% z7P60-#pgNGA*PAJ(DPnRzwow|gfR#289Mp|P1aA4=v4F_K#wG&bG)!Q_jKr*G z18@nuQ0@Sn6Im(&ph3t23r%6NiRpI82M7=Y&|HAQ!~q|3i7G_!F{glv3^o*rx9fFSC*i3S)vc)$?-LIVkRb`kgh?^_8l5L~qx z0Du;-WxXf>zylBPAi*gmc!y0HTv&q%5N$Ld03ADI;RyhFnDB>z?!2+i82qfl1v{4H zpuhkqJfcr2pa{S~6n~(gP6{vdu>>!OBw$NE5acib3=23Q#3cxH5QQ`Wuu=dEzqAt# z0$B85K@~JO0YDOf05S@OC=3z6B6Uo$#1R4jP(%VE%t1so0AS#UA9Mgs6q5kLh8oKeCaP@ob6L^sUvL>(@$5x_ubkl}&|d!%yhZ` S3Z%dy!>q(cD=h#40RTHuXyMQR literal 0 HcmV?d00001 diff --git a/ganttzk-demo-webapp/src/main/webapp/common/img/degradado_azul.gif b/ganttzk-demo-webapp/src/main/webapp/common/img/degradado_azul.gif new file mode 100644 index 0000000000000000000000000000000000000000..d18778ee265440bd4a27c0239eeab1c4dbaea827 GIT binary patch literal 2336 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 Ti~2Ny00000NkvXXu0mjf^eVSo literal 0 HcmV?d00001 diff --git a/ganttzk-demo-webapp/src/main/webapp/common/img/linea_down.gif b/ganttzk-demo-webapp/src/main/webapp/common/img/linea_down.gif new file mode 100644 index 0000000000000000000000000000000000000000..05c12041bdb6705b611e9821c09b6339958414e4 GIT binary patch literal 49 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ðxG5=+*V8XJ} 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 AcK`qY literal 0 HcmV?d00001 diff --git a/ganttzk-demo-webapp/src/main/webapp/common/img/migas_separacion.gif b/ganttzk-demo-webapp/src/main/webapp/common/img/migas_separacion.gif new file mode 100644 index 0000000000000000000000000000000000000000..78808e4eecf87af982533587d83a8cf88cb3380d GIT binary patch literal 106 zcmZ?wbhEHb=G{|qpo_>+Z^fq{oX2P6P8gMmeS!b#87do8kSHhJDyBoHpBFr6Xc@Uwk_4AuZ} CSR%Oq literal 0 HcmV?d00001 diff --git a/ganttzk-demo-webapp/src/main/webapp/common/img/pestana1.gif b/ganttzk-demo-webapp/src/main/webapp/common/img/pestana1.gif new file mode 100644 index 0000000000000000000000000000000000000000..6209c5f504ac732cc9c96c73ac2f9eabd03f902f GIT binary patch literal 2523 zcmb`E`6CmG1HgyTGFNU);hqyBkv`y^>e41-p0wLJMQWQQ;ugqM`hM%!+VtA? zDwR38LZh<|H+EQkbDN}X){hAyW_*1JPZ?jKjV@8ww)QA=cGvVq@9gFrac7%(FuT4p zxIkIlq_0qz1Tq7^K_}Ao#+J9pyKEX`zh!jo?0~i%6b-yyYcZYQ@KB8 z^V{cRP(RaKr{9$gHjS}Y3UhhKy5>PeO_dKL1EFi;*!#`^6zDNhEbWdsH_}bgPTTr zdH@XeM_YSGXIFPmZ(m2Nk+}hHb=??BTi?Lwwu!SPXaT>tv`ko8U0WxTRxM5WZyOot zYXg5Wz5opk^h`kaEQ|$yaR5C0auzknjtG#LD25AYDWhr%kX8ry<(Zx54F$G{eha&s z05yz}yLDZ~GU<|SxhoE3GLUxlj~6m^J%eIEYna_<53MY$BB3v9B`F86vW1?)Xp=9YAx*g&w5Q04b`+)|GPB%C+lq-i5|{VNtL@1u2C zP)W#4MF`c(#wtVFy*-*|zo(TTAR_A(h>9b!qeWDp;+{(tfADOKB5#E_UW3+?Ckk$d zXbzuek;ZdPLLMX5UadEz+?1G20$T9MTn^_+=W=bPuk=R9JB4C&nH&A-h4A~iEll!6 zlJ{u*h2S^hl5jktBF*DvF!~(c)6T>^a-X&`7`+o3dU|-kT$s7aG5qJWdu2oZpY18B zrJ$zFz&r(DQJ*o7${p$3A5^S$6(c2jk?xV=kAoDW<$@3LKPX3)u0%;&Wfa7y$AFY# zAyq+71)i-V+}?qO#uWe{{bmyZS)jT~q7nbCq9ha8BNa}vwWj5IvV|dTJ;hkm@_EXG zOYch;Q?9nzv@la=czu3pon>vURt7p{jYcz@-YiPomO(>@d(*+s4ye zXmReShY%o0t>RiIL}P2WOXTheyh~KgT8q;q<|IJxk+605?U1}u9s$;@s4>M|{%Xy@ zX?*uV4XCGJ7=u?!tZxim&vr$P+}QAWGYHuc@E^K1p`kshH>%&0UdMLu2HM@d&;Yh~ z@?}ju@~C_}?clx0nskX43;_O#cI)l?Wd1w#tXk2S&VqXLFdP4>%VvK8KKN(g!Yg!T z)1u#?pzhL}Gb8)Up-h{mb_Tff$^vk3F zRb6V@EKb;Np%#_oK{smpE*@`Y-3x0Buba&30LTE10J~jMet*;3ggGIM0r@rzb4=b= zpD`&rirF2yXY`&m@6Ex`?Hq(&b6n=wv&L+kM;n&09Jpi1qI?&|>`qLK{yJIw%eL(V z-)3YWj{e={@S=FQ$TK7Yq(R^k3~DFHh=d9K?Zz!XYYftahw)?FcqRHf_#eZ=<+t3p zwWRe0UMGeLeny@J_eTQQFA;)>Faa|KZkdt9DBTK00sqpj3#6JTgQ9%F_nx=qB$Gax zS}TeCvw2%ph#sZ)SxGp_^Nz9=J?0kPUCh-YlZ!&&auX;7bz1aZ&q|7Vp|U1D*xak# zN{{pMS>qW4-PM_<$GyfYb&MCw`rb6=RR9(7^T}97^39myzKQTa!~OU7u^5IUI1FMy1x) zt3v$B?)@&|TrpCCGnO_&%_&*Kc;y|?1ITMsN)FN0!>}iF1WpnAN*E&P_05fj zq)qUzt|>=gHt!2%5b}lJdfZWkg-1dC3q-J&??8edLKB zG8$lLoXZop0R=mcMx@=yXH{(KOF56l8}1=52zuU;cmDZ4^v$`UZ~$PBAR#o~@l|oy z6RLK8{M}3ca#>%p(Rb&m!G`JHQKQW?HkHh-<$8v!| M(x$@PTmZfQ0`D>(O8@`> literal 0 HcmV?d00001 diff --git a/ganttzk-demo-webapp/src/main/webapp/common/img/pestana_activa.gif b/ganttzk-demo-webapp/src/main/webapp/common/img/pestana_activa.gif new file mode 100644 index 0000000000000000000000000000000000000000..6817b7bedd49a8979b4146f786cbfe34d0afddfa GIT binary patch literal 2452 zcmchX`9IT*1HeDCVdO}zQcsRYBBg}Mk?(S!Q4tYIC3kpSMQr3g=01ysv00cg$Hi!73;mDp^Y)@GJL zhNrfw$CJ*-H5#V18KksoCpP<(eK;4}cs;r041y>T)1ZJPUVPQ0lhkq{uIX}olSTr` zHmifpIojSk++gid>5P?)oy4Yz$FKX6NRwHlN#C-5=I%izY4U*0**#z%vN;QDOjOeZ zYwzGUb8l;Bf1S0r#@Jom+}YVbOlh86`o+v?rlb+aL#sd2*0(pe_kaFoEv_+>31b~| ztG^h#NrbVq7D_T{a``tasC*!!h2mZM;ZDwb&)0nj{BUCZXnNzs^XkuBE*JR!BEJs- z0e~}b@n7w~O#pr_!Z|k18Jv)ql$?^9mY#vi%*uY1o0nfum=9Lb*3yEY-lr?>Az|HpwIvMwA3sc#%7s%XJ<^{-nS2+q!Z zpZ`H!SX}zKOj|V2Q`OgnX{mrG7`b3=n8tNMQ^RW_M_d3bc*dN7?umnnpLmQkg67KV zodx89XQllTkPw#B?Vs^xCV0o0Lj?#=bXa387kZ-SvVqRl)~e*~t+7`*Iw&iH!_Z`S43cEDO%FnbW=)`>Wy zMrfQLbsYybL_z|A0DcKCIpor*YwpNJ^%Xg!5DY8#if$5t21Gp~sPV@{k`@wW)S%@_ zXBSPuLI>Vof5>sKqu~faDLZ%2)w6aLv9QH!kJ5DL(-o*|^H4<;pPNzmte z)y09I15Z*OajwBtRq6UvY5uHMjxld1 zdVa)yhRm1;H8Q(*wyu?#KXjQupVtcjeINa-3{umTi{q0ve!b4SWO{Ln+b;3cPyNFg z--}xV5`PJ)56X9?ZVf6ty&p6nl`|JSq*{;`+%ICI!ZO>e?x ze7kCQW&-fSEpq`wFT>~jcR9>C#G!u+^(BR~J0HmJ7C!Iq7+BuYG&+feRc-bZE>Wq}T++KmlGwn)@Q z@12_+8v~~=vp2gQL`Q9o^Z(G_q=<6$8RM#5?42RAXV*8R=Y-n0`su;$NBgv#ZsY;I z0u_C@I)idz!qXddwh9$r`=@^~5=EWHQk zv)qh5Iqc4>F?d5bI1sF^>|UgBrx|zyfX`oB5V%!nC`7P}zx3*%pyOb#OwD-w<>3V( z*XdsA(al7-@!R9b);@*a@kE1MdC}y-USaAeLeZ~K=)M=vnZe)SIF|}42qq+ zotXeplox+K2tN=@M;R~4%YGU(xj@W9`YFntE3z=XeU+PCRQXup&$dsdmT;8dka2}& zx8>aobl$lLjOrr+E2G}*eBv+; zZn(@8Qpkx}Jl)|bKxiBBd%-N3`lY1Zvu_iW&3wJ0SgkX%Y7-PDUK|-EtaTl3E1HBZ z-Rn4Su!4 z5PS3=+sfuzmXle*A(gV*D;72~les?jm9o4l)(!n^X~ z9q|YDxT{(qRB+`-43x=%C{65it^$EYrw*h({7}c)qiaQlMX^L*bj^Mp-`OZ+PrbvXB{!kCS*>Chv zQmcc%k8h;&*TpbW=l5El$P$;CNmxto6Mv|(`^21NdEN1(0BE_@ce-Ubc^b1GQaj|j z=GoFd`@1fLwC1{5?AWn#=~-x>mD}2F1Y*li0!*`d03F}$+<9Lgy*u>dXkELD+g~5^ z&oL@Ue7YOD^9*?^^8wBDj&iyWV(Zm;>jgoVLXgxbA>lM)LD;sn@9gN6B%`PW(VV>x zGF5P|zoxLft$Y1fG8)pJS})1Wwt`@z4H@CXOJ~Ol!P+juE~QpBkdym^<~NDi1;am; z^!7j5We~HZ<(4nF6oH)(Ad%=mh}@U%1dHHBJa$I_Cuhbz44TR%T~|!>WF|5_S>>lWUdGY~lewiK zm`j&d&7bK4MLU{U9nR`4rViA68Yu$ZEISod4aQ`U-aWNhbDlkzYK_+952iwRH@o?e H0HF6@wMxKU literal 0 HcmV?d00001 diff --git a/ganttzk-demo-webapp/src/main/webapp/common/img/pestana_sobre.gif b/ganttzk-demo-webapp/src/main/webapp/common/img/pestana_sobre.gif new file mode 100644 index 0000000000000000000000000000000000000000..9ee16e79449297d9bd304c5320d6b13424844fcd GIT binary patch literal 3006 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 literal 0 HcmV?d00001 diff --git a/ganttzk-demo-webapp/src/main/webapp/common/img/sub_separacion.gif b/ganttzk-demo-webapp/src/main/webapp/common/img/sub_separacion.gif new file mode 100644 index 0000000000000000000000000000000000000000..35ea0345537f2df14e01a232b345c20515c2fb18 GIT binary patch literal 59 zcmZ?wbhEHb + + + + + + + + + + + + + + + + + + about + ganttZK + + + + + + + + + + + + + + + + + + +
+ + + + + + + diff --git a/ganttzk-demo-webapp/src/main/webapp/common/page_not_found.zul b/ganttzk-demo-webapp/src/main/webapp/common/page_not_found.zul new file mode 100644 index 000000000..99a392ea4 --- /dev/null +++ b/ganttzk-demo-webapp/src/main/webapp/common/page_not_found.zul @@ -0,0 +1,19 @@ + + + + + + + + A páxina que está solicitando non existe. + Se introduciu a dirección directamente na barra de navegación + do navegador revísea ou pulse na seguinte ligazón para ir á páxina + inicial: Ir a inicio + Se chegou a esta páxina dende outra páxina do portal + rogámoslle nolo notifique para que sexa subsanado no menor + intervalo de tempo posible. + Desculpe as molestias. + + + diff --git a/ganttzk-demo-webapp/src/main/webapp/planner/css/ganttzk.css b/ganttzk-demo-webapp/src/main/webapp/planner/css/ganttzk.css new file mode 100644 index 000000000..d649bfd7b --- /dev/null +++ b/ganttzk-demo-webapp/src/main/webapp/planner/css/ganttzk.css @@ -0,0 +1,335 @@ +/* +* ganttz.css Ganttz specific styles +* / + +The next constants are used within the planner styling: + +Ganntz.ListdetailsWidth = 280 + + +zkTasklist.HEIGHT_PER_ROW = 15 +zkTasklist.HEIGHT_TIME_TRACKER = 120 + +zkTasklist.SCROLLBAR_WIDTH = 15 + +zkTasklist.SCROLL_CONTAINER_INITIAL_HEIGHT = 500 +zkTasklist.SCROLL_CONTAINER_INITIAL_WIDTH = 600 + +zkTasklist.GANTT_PANEL_LEFT = 300 + +*/ + +/* -------------- Listdetails -------------- */ + +/* External listdetails box */ +.listdetails { + width:280px; /* Ganntz.ListdetailsWidth */ + float:left; + margin-top: 0px; +/* border-bottom: 1px solid #86A4BE; */ + font-size:10px !important; + margin-top:0px; +} + +#listdetails_container { + float:left; + height:500px; /* zkTasklist.SCROLL_CONTAINER_INITIAL_HEIGHT */ + position:relative; + top:27px; + overflow-y: hidden; + border-bottom: 1px solid #86A4BE; + border-right: 1px solid #86A4BE; +} + +.listdetails img { + display:none; +} + +#listdetails_container td { + border-bottom:1px solid #86A4BE; + border-left:1px solid #86A4BE; + border:0px; +} + +#listdetails_container td { + padding:0px; +} + +.listdetails input { + width: 65px; + font-size:10px !important; + border-bottom:0px; + border-right:0px; + height:17px; +} + +#listdetails_container .z-datebox-inp, +#listdetails_container div.z-tree-col-cnt { + font-family:"Verdana,Tahoma,Arial,Helvetica,sans-serif"; + font-size:10px !important; + border-bottom:0px; + border-right:0px; +} + +.depth_1 .task_title { + width: 121px !important; +} +.depth_2 .task_title { + width: 104px !important; +} +.depth_3 .task_title { + width: 85px; +} +.depth_4 .task_title { + width: 64px; +} + + +.taskdetail_grid table { + height:30px; + width:285px; /* Ganntz.ListdetailsWidth */ +} + + + +#listtasks { + position:relative; + width:600px; + top:0px; +} + +/* Task box properties */ +.box { + border: 1px solid; + text-align:center; + vertical-align: middle; + z-index:10; + cursor: pointer; + cursor: hand; +} + +/* Task lane properties */ +.row { + height: 9px; /* 19 */ + border-bottom: dotted 1px #CCCCCC; + margin-bottom: 10px; + margin-top: 10px; + width: 10000px; /* Defined to be larger than the maximum scroll_inner_x */ +} + + +/* -------------- Dependencies -------------- */ +#listdependencies { + position:relative; + width:400px; + float:left; + top:0px; +} + +.dependence { + z-index:1; + position: absolute; +} + +.end, .start, .mid, .arrow { + position:absolute; + padding:4px; + cursor: crosshair; +} + +.end, .start { + height:1px; +} + +.mid { + width:1px; +} + +.completion { + display: none; + width: 30%; + margin-top:0px; + height: 10px; + background-color: #FFCC99; + z-index:5; + border:0px; +} + +.row span { + display:none; + position:relative; + z-index:5; + color:#BBBBBB; + white-space:nowrap; +} + +/* -------------- TaskGroup -------------- */ +.taskgroup_start { + background-image: url("/ganttzk-demo-webapp/zkau/web/ganttz/img/group_left.png"); + height: 10px; + width: 10px; + float:left; +} + +.taskgroup_end { + background-image: url("/ganttzk-demo-webapp/zkau/web/ganttz/img/group_right.png"); + height: 10px; + width: 10px; + float:right; +} + +.taskgroup, .row .expanded { + border-top: solid black 2px; + border-bottom: 0px; + border-left: 0px; + border-right: 0px; + background-color: transparent !important; +} + +.row .closed { + border-top: solid black 2px; +} + + + + +.zk #ganttpanel .z-button-cm { + border: 0px; +} + +#ganttpanel { + height:400px; /* 800 */ + width: 900px; +} + +#ganttpanel table { + float:left; + padding:0; + margin:0; + overflow:hidden; +} + +#ganttpanel table td { + padding:0; +} + +/* -------------- Timetracker -------------- */ +.timetracker_fake_row { + height: 80px; +} + +/* Forces every zoom level the same table width */ +#timetracker table { + border-collapse: collapse; +} + +#timetracker .second_level_ tr { + height:14px; +} + +/* Watermark alternate row color */ +#watermark .timetracker_column_even { + background-color: #EEEEEE; +} + +/* Background image for current day vertical line */ +#watermark .timetracker_column_today { + background-image: url("/ganttzk-demo-webapp/zkau/web/ganttz/img/watermark_today.png"); + background-repeat: repeat-y; +} + +#watermark .bankHoliday { + background-color: #FFEEEE; !important; +} + + +/* Reduce spacing and font-size for watermark legend */ +.z-columns, .z-column { + font-size: 8px !important; + text-align: center; + padding:0 0 0 0 !important; +} + +table { + margin:0px; + padding:0px; + border:0px; +} + +#scroll_container { + margin-top:70px; + height:300px; /* Recalculated based on window */ + width:500px; /* Recalculated based on window */ + overflow:hidden; + float:left; + position:absolute; + left:285px; /* Ganntz.ListdetailsWidth + borders = 280 + 5 */ + /* border:solid green 1px; */ +} + +#timetracker { + /* border: solid 1px red; */ + position:absolute; + left:285px; /* Ganntz.ListdetailsWidth + borders = 280 + 5 */ + height:500px; /* zkTasklist.SCROLL_CONTAINER_INITIAL_HEIGHT (dynamic) */ + width:600px; /* zkTasklist.SCROLL_CONTAINER_INITIAL_WIDTH (dynamic) */ + position:absolute; + overflow-x:hidden; + float:left; +} + +#zoom_buttons { + position:relative; +} + +tr.z-vbox-sep { + height: 0px; + padding: 0px; + margin: 0px; +} + + +#ganttpanel_scroller_x, #ganttpanel_scroller_y { + position:absolute; + float:left; + overflow:auto; +} + +#ganttpanel_scroller_x { + + top: 600px; /* (dynamic) */ + left: 285px; /* Ganntz.ListdetailsWidth + borders = 280 + 5 */ + width:635px; + height:15px; +} + +#ganttpanel_inner_scroller_x { + /* must be resized on ganttpanel javascript adjust size */ + width:9000px; /* Real canvas dimensions */ + height:15px; /* Scroll constant */ +} + +#ganttpanel_scroller_y { + top: 160px; /* Fixed top position */ + left: 920px; + width:15px; + height:330px; +} +#ganttpanel_inner_scroller_y { + width:15px; /* Scroll constant */ + height:1350px; /* Modified when added or removed tasks, or zoom adjustments */ +} + + +.footer { + /* Pending to calculate general position */ + display:none; +} + +/* Hide at the beginning */ +#ganttpanel_scroller_x { + display:none; +} +#ganttpanel_scroller_y { + display:none; +} diff --git a/ganttzk-demo-webapp/src/main/webapp/planner/main.zul b/ganttzk-demo-webapp/src/main/webapp/planner/main.zul new file mode 100644 index 000000000..8ac3f1ddf --- /dev/null +++ b/ganttzk-demo-webapp/src/main/webapp/planner/main.zul @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + +
+
+ + + + + + ${c:l('task.name')} + + + + ${c:l('task.start')} + + + + ${c:l('task.end')} + + + + ${c:l('task.notes')} + + + + +