http://git-wip-us.apache.org/repos/asf/syncope/blob/2d194636/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/DateTimeFieldPanel.java ---------------------------------------------------------------------- diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/DateTimeFieldPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/DateTimeFieldPanel.java new file mode 100644 index 0000000..d8014f6 --- /dev/null +++ b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/DateTimeFieldPanel.java @@ -0,0 +1,195 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.client.console.wicket.markup.html.form; + +import java.util.Calendar; +import java.util.Date; +import org.apache.syncope.client.console.commons.Constants; +import org.apache.wicket.AttributeModifier; +import org.apache.wicket.ajax.AjaxRequestTarget; +import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior; +import org.apache.wicket.extensions.yui.calendar.DateTimeField; +import org.apache.wicket.markup.html.form.Form; +import org.apache.wicket.markup.html.form.FormComponent; +import org.apache.wicket.markup.html.form.validation.AbstractFormValidator; +import org.apache.wicket.model.IModel; +import org.apache.wicket.model.Model; +import org.apache.wicket.validation.IValidationError; +import org.apache.wicket.validation.ValidationError; + +public class DateTimeFieldPanel extends DateFieldPanel { + + private static final long serialVersionUID = -428975732068281726L; + + private Form form = null; + + public DateTimeFieldPanel(final String id, final String name, final IModel<Date> model, final String datePattern) { + super(id, name, model, datePattern); + + field = new DateTimeField("field", model); + + final Calendar cal = Calendar.getInstance(); + + field.get("hours").add(new AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) { + + private static final long serialVersionUID = -1107858522700306810L; + + @Override + protected void onUpdate(final AjaxRequestTarget target) { + final Integer hours = ((DateTimeField) field).getHours(); + if (hours != null) { + cal.set(hours > 12 ? Calendar.HOUR_OF_DAY : Calendar.HOUR, hours); + field.setModelObject(cal.getTime()); + } + } + }); + + field.get("minutes").add(new AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) { + + private static final long serialVersionUID = -1107858522700306810L; + + @Override + protected void onUpdate(final AjaxRequestTarget target) { + final Integer minutes = ((DateTimeField) field).getMinutes(); + if (minutes != null) { + cal.set(Calendar.MINUTE, minutes); + field.setModelObject(cal.getTime()); + } + } + }); + + field.get("date").add(new AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) { + + private static final long serialVersionUID = -1107858522700306810L; + + @Override + protected void onUpdate(final AjaxRequestTarget target) { + final Date date = ((DateTimeField) field).getDate(); + if (date == null) { + field.setModelObject(null); + } else { + cal.setTime(date); + cal.set(Calendar.AM_PM, "PM".equals("" + ((DateTimeField) field).getAmOrPm()) ? Calendar.PM + : Calendar.AM); + field.setModelObject(cal.getTime()); + } + } + }); + + field.get("amOrPmChoice").add(new AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) { + + private static final long serialVersionUID = -1107858522700306810L; + + @Override + protected void onUpdate(final AjaxRequestTarget target) { + cal.set(Calendar.AM_PM, "PM".equals("" + ((DateTimeField) field).getAmOrPm()) ? Calendar.PM + : Calendar.AM); + field.setModelObject(cal.getTime()); + } + }); + + add(field.setLabel(new Model<String>(name)).setOutputMarkupId(true)); + } + + /** + * Custom form validator for registering and handling DateTimeField components that are in it. + */ + private class DateTimeFormValidator extends AbstractFormValidator { + + private static final long serialVersionUID = 6842264694946633582L; + + private FormComponent[] dateTimeComponents; + + public DateTimeFormValidator(final DateTimeField dateTimeComponent) { + if (dateTimeComponent == null) { + throw new IllegalArgumentException("argument dateTimeComponent cannot be null"); + } + + dateTimeComponents = new FormComponent[] { dateTimeComponent }; + } + + @Override + public FormComponent[] getDependentFormComponents() { + return dateTimeComponents; + } + + /** + * Validation rule : all 3 fields (date,hours,minutes) must be not-null. + * + * @param form + */ + @Override + public void validate(final Form form) { + final DateTimeField dateTimeField = (DateTimeField) dateTimeComponents[0]; + + if (!(dateTimeField.getDate() != null && dateTimeField.getHours() != null + && dateTimeField.getMinutes() != null)) { + + ValidationError ve = new ValidationError(); + ve.setVariables(DateTimeFormValidator.this.variablesMap()); + ve.addKey(resourceKey()); + dateTimeComponents[0].error((IValidationError) ve); + } + } + } + + @SuppressWarnings("rawtypes") + public FieldPanel<Date> setFormValidator(final Form form) { + if (field == null) { + LOG.error("Error setting form validator"); + } else { + form.add(new DateTimeFormValidator(((DateTimeField) field))); + this.form = form; + } + + return this; + } + + @Override + public FieldPanel<Date> setStyleSheet(final String classes) { + field.get("date").add(AttributeModifier.replace("class", (classes == null ? "" : classes) + " date_size")); + + field.get("hours").add(AttributeModifier.replace("class", classes == null ? "" : classes)); + + field.get("minutes").add(AttributeModifier.replace("class", classes == null ? "" : classes)); + + field.get("amOrPmChoice").add(AttributeModifier.replace("class", classes == null ? "" : classes)); + + return this; + } + + @Override + public FieldPanel<Date> clone() { + final FieldPanel<Date> panel = new DateTimeFieldPanel(getId(), name, new Model<Date>(null), datePattern); + + panel.setRequired(isRequired()); + panel.setReadOnly(isReadOnly()); + panel.setTitle(title); + + if (isRequiredLabelAdded) { + panel.addRequiredLabel(); + } + + if (form != null && isRequired()) { + ((DateTimeFieldPanel) panel).setFormValidator(form); + } + + return panel; + } +}
http://git-wip-us.apache.org/repos/asf/syncope/blob/2d194636/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/FieldPanel.java ---------------------------------------------------------------------- diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/FieldPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/FieldPanel.java new file mode 100644 index 0000000..8dbc434 --- /dev/null +++ b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/FieldPanel.java @@ -0,0 +1,199 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.client.console.wicket.markup.html.form; + +import java.io.Serializable; +import java.util.List; +import org.apache.commons.lang3.SerializationUtils; +import org.apache.wicket.AttributeModifier; +import org.apache.wicket.markup.html.basic.Label; +import org.apache.wicket.markup.html.form.FormComponent; +import org.apache.wicket.markup.html.list.ListItem; +import org.apache.wicket.markup.html.panel.Fragment; +import org.apache.wicket.model.IModel; +import org.apache.wicket.model.Model; + +public abstract class FieldPanel<T> extends AbstractFieldPanel<T> implements Cloneable { + + private static final long serialVersionUID = -198988924922541273L; + + protected FormComponent<T> field = null; + + protected String title = null; + + protected boolean isRequiredLabelAdded = false; + + public FieldPanel(final String id, final IModel<T> model) { + super(id, model); + + final Fragment fragment = new Fragment("required", "notRequiredFragment", this); + add(fragment); + + setOutputMarkupId(true); + } + + public FormComponent<T> getField() { + return field; + } + + public FieldPanel<T> setTitle(final String title) { + this.title = title; + field.add(AttributeModifier.replace("title", title != null + ? title + : "")); + + return this; + } + + public FieldPanel<T> setStyleSheet(final String classes) { + field.add(AttributeModifier.replace("class", classes != null + ? classes + : "")); + + return this; + } + + public FieldPanel<T> setRequired(boolean required) { + field.setRequired(required); + + return this; + } + + public FieldPanel<T> setReadOnly(boolean readOnly) { + field.setEnabled(!readOnly); + + return this; + } + + public boolean isRequired() { + return field.isRequired(); + } + + public boolean isReadOnly() { + return !field.isEnabled(); + } + + public FieldPanel<T> addRequiredLabel() { + if (!isRequired()) { + setRequired(true); + } + + final Fragment fragment = new Fragment("required", "requiredFragment", this); + + fragment.add(new Label("requiredLabel", "*")); + + replace(fragment); + + this.isRequiredLabelAdded = true; + + return this; + } + + public FieldPanel<T> removeRequiredLabel() { + if (isRequired()) { + setRequired(false); + } + + final Fragment fragment = new Fragment("required", "notRequiredFragment", this); + + replace(fragment); + + this.isRequiredLabelAdded = false; + + return this; + } + + @Override + public FieldPanel<T> setModelObject(final T object) { + field.setModelObject(object); + return this; + } + + public T getModelObject() { + return (T) field.getModelObject(); + } + + public FieldPanel<T> setNewModel(final IModel<T> model) { + field.setModel(model); + return this; + } + + /** + * Used by MultiValueSelectorPanel to attach items. + * + * @param item item to attach. + * @return updated FieldPanel object. + */ + public FieldPanel<T> setNewModel(final ListItem<T> item) { + setNewModel(new IModel<T>() { + + private static final long serialVersionUID = 6799404673615637845L; + + @Override + public T getObject() { + return item.getModelObject(); + } + + @Override + public void setObject(final T object) { + item.setModelObject(object); + } + + @Override + public void detach() { + // no detach + } + }); + return this; + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + public FieldPanel<T> setNewModel(final List<Serializable> list) { + setNewModel(new Model() { + + private static final long serialVersionUID = 1088212074765051906L; + + @Override + public Serializable getObject() { + return list == null || list.isEmpty() + ? null + : list.get(0); + } + + @Override + public void setObject(final Serializable object) { + list.clear(); + + if (object != null) { + list.add(object); + } + } + }); + + return this; + } + + @Override + @SuppressWarnings("unchecked") + public FieldPanel<T> clone() { + final FieldPanel<T> panel = SerializationUtils.clone(this); + panel.setModelObject(null); + return panel; + } +} http://git-wip-us.apache.org/repos/asf/syncope/blob/2d194636/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/LinkPanel.java ---------------------------------------------------------------------- diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/LinkPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/LinkPanel.java new file mode 100644 index 0000000..b31bbab --- /dev/null +++ b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/LinkPanel.java @@ -0,0 +1,39 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.client.console.wicket.markup.html.form; + +import org.apache.wicket.markup.html.panel.Panel; +import org.apache.wicket.model.IModel; + +/** + * This empty class must exist because there not seems to be alternative to + * provide specialized HTML for links. + */ +public class LinkPanel extends Panel { + + private static final long serialVersionUID = 4799005986804366330L; + + public LinkPanel(final String id) { + super(id); + } + + public LinkPanel(final String id, final IModel<?> model) { + super(id, model); + } +} http://git-wip-us.apache.org/repos/asf/syncope/blob/2d194636/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/MappingPurposePanel.java ---------------------------------------------------------------------- diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/MappingPurposePanel.java b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/MappingPurposePanel.java new file mode 100644 index 0000000..2c41f37 --- /dev/null +++ b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/MappingPurposePanel.java @@ -0,0 +1,133 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.client.console.wicket.markup.html.form; + +import org.apache.syncope.common.lib.types.MappingPurpose; +import org.apache.wicket.AttributeModifier; +import org.apache.wicket.ajax.AjaxRequestTarget; +import org.apache.wicket.ajax.markup.html.AjaxLink; +import org.apache.wicket.markup.html.WebMarkupContainer; +import org.apache.wicket.markup.html.panel.Panel; +import org.apache.wicket.model.IModel; +import org.apache.wicket.model.Model; + +public class MappingPurposePanel extends Panel { + + private static final long serialVersionUID = 322966537010107771L; + + private final AjaxLink<Void> propagation; + + private final AjaxLink<Void> synchronization; + + private final AjaxLink<Void> both; + + private final AjaxLink<Void> none; + + public MappingPurposePanel(final String componentId, final IModel<MappingPurpose> model, + final WebMarkupContainer container) { + + super(componentId, model); + + propagation = new AjaxLink<Void>("propagationPurposeLink") { + + private static final long serialVersionUID = -6957616042924610305L; + + @Override + public void onClick(final AjaxRequestTarget target) { + model.setObject(MappingPurpose.PROPAGATION); + setOpacity(MappingPurpose.PROPAGATION); + target.add(container); + } + }; + + synchronization = new AjaxLink<Void>("synchronizationPurposeLink") { + + private static final long serialVersionUID = -6957616042924610305L; + + @Override + public void onClick(final AjaxRequestTarget target) { + model.setObject(MappingPurpose.SYNCHRONIZATION); + setOpacity(MappingPurpose.SYNCHRONIZATION); + target.add(container); + } + }; + + both = new AjaxLink<Void>("bothPurposeLink") { + + private static final long serialVersionUID = -6957616042924610305L; + + @Override + public void onClick(final AjaxRequestTarget target) { + model.setObject(MappingPurpose.BOTH); + setOpacity(MappingPurpose.BOTH); + target.add(container); + } + }; + + none = new AjaxLink<Void>("nonePurposeLink") { + + private static final long serialVersionUID = -6957616042924610305L; + + @Override + public void onClick(final AjaxRequestTarget target) { + model.setObject(MappingPurpose.NONE); + setOpacity(MappingPurpose.NONE); + target.add(container); + } + }; + + add(propagation); + add(synchronization); + add(both); + add(none); + + setOpacity(model.getObject()); + } + + private void setOpacity(final MappingPurpose mappingPurpose) { + switch (mappingPurpose) { + case PROPAGATION: + propagation.add(new AttributeModifier("style", new Model<String>("opacity: 1;"))); + synchronization.add(new AttributeModifier("style", new Model<String>("opacity: 0.3;"))); + both.add(new AttributeModifier("style", new Model<String>("opacity: 0.3;"))); + none.add(new AttributeModifier("style", new Model<String>("opacity: 0.3;"))); + break; + case SYNCHRONIZATION: + synchronization.add(new AttributeModifier("style", new Model<String>("opacity: 1;"))); + propagation.add(new AttributeModifier("style", new Model<String>("opacity: 0.3;"))); + both.add(new AttributeModifier("style", new Model<String>("opacity: 0.3;"))); + none.add(new AttributeModifier("style", new Model<String>("opacity: 0.3;"))); + break; + case BOTH: + both.add(new AttributeModifier("style", new Model<String>("opacity: 1;"))); + propagation.add(new AttributeModifier("style", new Model<String>("opacity: 0.3;"))); + synchronization.add(new AttributeModifier("style", new Model<String>("opacity: 0.3;"))); + none.add(new AttributeModifier("style", new Model<String>("opacity: 0.3;"))); + break; + case NONE: + none.add(new AttributeModifier("style", new Model<String>("opacity: 1;"))); + synchronization.add(new AttributeModifier("style", new Model<String>("opacity: 0.3;"))); + propagation.add(new AttributeModifier("style", new Model<String>("opacity: 0.3;"))); + both.add(new AttributeModifier("style", new Model<String>("opacity: 0.3;"))); + break; + default: + // do nothing + } + } +} http://git-wip-us.apache.org/repos/asf/syncope/blob/2d194636/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/MultiFieldPanel.java ---------------------------------------------------------------------- diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/MultiFieldPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/MultiFieldPanel.java new file mode 100644 index 0000000..cd4ab2a --- /dev/null +++ b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/MultiFieldPanel.java @@ -0,0 +1,172 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.client.console.wicket.markup.html.form; + +import java.util.List; +import org.apache.syncope.client.console.commons.Constants; +import org.apache.wicket.ajax.AjaxRequestTarget; +import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior; +import org.apache.wicket.ajax.markup.html.AjaxLink; +import org.apache.wicket.event.Broadcast; +import org.apache.wicket.extensions.ajax.markup.html.IndicatingAjaxLink; +import org.apache.wicket.markup.html.WebMarkupContainer; +import org.apache.wicket.markup.html.list.ListItem; +import org.apache.wicket.markup.html.list.ListView; +import org.apache.wicket.markup.html.panel.Fragment; +import org.apache.wicket.model.IModel; + +public class MultiFieldPanel<E> extends AbstractFieldPanel<List<E>> { + + private static final long serialVersionUID = -6322397761456513324L; + + private ListView<E> view; + + private WebMarkupContainer container; + + public MultiFieldPanel(final String id, final IModel<List<E>> model, final FieldPanel<E> panelTemplate) { + this(id, model, panelTemplate, false); + } + + public MultiFieldPanel(final String id, final IModel<List<E>> model, final FieldPanel<E> panelTemplate, + final boolean eventTemplate) { + + super(id, model); + + // ----------------------- + // Object container definition + // ----------------------- + container = new WebMarkupContainer("multiValueContainer"); + container.setOutputMarkupId(true); + add(container); + // ----------------------- + + view = new ListView<E>("view", model) { + + private static final long serialVersionUID = -9180479401817023838L; + + @Override + protected void populateItem(final ListItem<E> item) { + final FieldPanel<E> fieldPanel = panelTemplate.clone(); + + if (eventTemplate) { + fieldPanel.getField().add(new AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) { + + private static final long serialVersionUID = -1107858522700306810L; + + @Override + protected void onUpdate(final AjaxRequestTarget target) { + send(getPage(), Broadcast.BREADTH, new MultiValueSelectorEvent(target)); + } + }); + } + + fieldPanel.getField().add(new AjaxFormComponentUpdatingBehavior(Constants.ON_BLUR) { + + private static final long serialVersionUID = -1107858522700306810L; + + @Override + protected void onUpdate(final AjaxRequestTarget target) { + } + }); + + fieldPanel.setNewModel(item); + item.add(fieldPanel); + + AjaxLink<Void> minus = new IndicatingAjaxLink<Void>("drop") { + + private static final long serialVersionUID = -7978723352517770644L; + + @Override + public void onClick(final AjaxRequestTarget target) { + //Drop current component + model.getObject().remove(item.getModelObject()); + fieldPanel.getField().clearInput(); + target.add(container); + + if (eventTemplate) { + send(getPage(), Broadcast.BREADTH, new MultiValueSelectorEvent(target)); + } + } + }; + + item.add(minus); + + if (model.getObject().size() <= 1) { + minus.setVisible(false); + minus.setEnabled(false); + } else { + minus.setVisible(true); + minus.setEnabled(true); + } + + final Fragment fragment; + if (item.getIndex() == model.getObject().size() - 1) { + final AjaxLink<Void> plus = new IndicatingAjaxLink<Void>("add") { + + private static final long serialVersionUID = -7978723352517770644L; + + @Override + public void onClick(final AjaxRequestTarget target) { + //Add current component + model.getObject().add(null); + target.add(container); + } + }; + + fragment = new Fragment("panelPlus", "fragmentPlus", container); + + fragment.add(plus); + } else { + fragment = new Fragment("panelPlus", "emptyFragment", container); + } + item.add(fragment); + } + }; + + container.add(view.setOutputMarkupId(true)); + setOutputMarkupId(true); + } + + public ListView<E> getView() { + return view; + } + + public WebMarkupContainer getContainer() { + return container; + } + + @Override + public MultiFieldPanel<E> setModelObject(final List<E> object) { + view.setModelObject(object); + return this; + } + + public static class MultiValueSelectorEvent { + + final AjaxRequestTarget target; + + public MultiValueSelectorEvent(final AjaxRequestTarget target) { + this.target = target; + } + + public AjaxRequestTarget getTarget() { + return target; + } + } +} http://git-wip-us.apache.org/repos/asf/syncope/blob/2d194636/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/NonI18nPalette.java ---------------------------------------------------------------------- diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/NonI18nPalette.java b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/NonI18nPalette.java new file mode 100644 index 0000000..55038da --- /dev/null +++ b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/NonI18nPalette.java @@ -0,0 +1,44 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.client.console.wicket.markup.html.form; + +import java.util.Collection; +import java.util.List; +import org.apache.wicket.extensions.markup.html.form.palette.Palette; +import org.apache.wicket.markup.html.form.IChoiceRenderer; +import org.apache.wicket.model.IModel; + +public class NonI18nPalette<T> extends Palette<T> { + + private static final long serialVersionUID = 2659070187837941889L; + + public NonI18nPalette(final String id, + final IModel<? extends List<? extends T>> model, + final IModel<? extends Collection<? extends T>> choicesModel, + final IChoiceRenderer<T> choiceRenderer, final int rows, + final boolean allowOrder, final boolean allowMoveAll) { + + super(id, model, choicesModel, choiceRenderer, rows, allowOrder, allowMoveAll); + } + + @Override + protected boolean localizeDisplayValues() { + return false; + } +} http://git-wip-us.apache.org/repos/asf/syncope/blob/2d194636/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/SelectableRecorder.java ---------------------------------------------------------------------- diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/SelectableRecorder.java b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/SelectableRecorder.java new file mode 100644 index 0000000..2893533 --- /dev/null +++ b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/SelectableRecorder.java @@ -0,0 +1,204 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.client.console.wicket.markup.html.form; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; + +import org.apache.wicket.WicketRuntimeException; +import org.apache.wicket.extensions.markup.html.form.palette.Palette; +import org.apache.wicket.extensions.markup.html.form.palette.component.Recorder; +import org.apache.wicket.markup.html.form.IChoiceRenderer; +import org.apache.wicket.model.Model; +import org.apache.wicket.util.string.Strings; + +/** + * A variant of Recorder, supporting single element selection (for editing purpose, for example). <b>Note</b>: this + * class extends Recorder<T> but in fact it is a bare copy of most source code; this was done because the original class + * is keeping everything private. + * + * @param <T> Type of the palette + */ +public class SelectableRecorder<T> extends Recorder<T> { + + private static final long serialVersionUID = -3009044376132921879L; + + private boolean attached = false; + + private static final String[] EMPTY_IDS = new String[0]; + + /** + * Conveniently maintained array of selected ids. + */ + private String[] ids; + + private String selectedId; + + public SelectableRecorder(final String id, final Palette<T> palette) { + super(id, palette); + } + + @Override + protected void onBeforeRender() { + super.onBeforeRender(); + + if (!getForm().hasError()) { + initIds(); + } else if (ids == null) { + ids = EMPTY_IDS; + } + attached = true; + } + + /** + * Synchronize ids collection from the palette's model + */ + private void initIds() { + // construct the model string based on selection collection + IChoiceRenderer<T> renderer = getPalette().getChoiceRenderer(); + StringBuilder modelStringBuffer = new StringBuilder(); + Collection<T> modelCollection = getPalette().getModelCollection(); + if (modelCollection == null) { + throw new WicketRuntimeException("Expected getPalette().getModelCollection() to return a non-null value." + + " Please make sure you have model object assigned to the palette"); + } + Iterator<T> selection = modelCollection.iterator(); + + int i = 0; + while (selection.hasNext()) { + modelStringBuffer.append(renderer.getIdValue(selection.next(), i++)); + if (selection.hasNext()) { + modelStringBuffer.append(","); + } + } + + // set model and update ids array + String modelString = modelStringBuffer.toString(); + setDefaultModel(new Model<String>(modelString)); + updateIds(modelString); + } + + public T getSelectedItem() { + if (selectedId == null) { + return null; + } + + IChoiceRenderer<T> renderer = getPalette().getChoiceRenderer(); + + T selected = null; + for (T choice : getPalette().getChoices()) { + if (renderer.getIdValue(choice, 0).equals(selectedId)) { + selected = choice; + break; + } + } + + return selected; + } + + /** + * @return iterator over selected choices + */ + @Override + public Iterator<T> getSelectedChoices() { + IChoiceRenderer<T> renderer = getPalette().getChoiceRenderer(); + if (ids.length == 0) { + return Collections.<T>emptyList().iterator(); + } + + List<T> selected = new ArrayList<T>(ids.length); + for (String id : ids) { + for (T choice : getPalette().getChoices()) { + if (renderer.getIdValue(choice, 0).equals(id)) { + selected.add(choice); + break; + } + } + } + return selected.iterator(); + } + + /** + * @return iterator over unselected choices + */ + @Override + public Iterator<T> getUnselectedChoices() { + IChoiceRenderer<T> renderer = getPalette().getChoiceRenderer(); + Collection<? extends T> choices = getPalette().getChoices(); + + if (choices.size() - ids.length == 0) { + return Collections.<T>emptyList().iterator(); + } + + List<T> unselected = new ArrayList<T>(Math.max(1, choices.size() - ids.length)); + for (T choice : choices) { + final String choiceId = renderer.getIdValue(choice, 0); + boolean selected = false; + for (String id : ids) { + if (id.equals(choiceId)) { + selected = true; + break; + } + } + if (!selected) { + unselected.add(choice); + } + } + return unselected.iterator(); + } + + @Override + protected void onValid() { + super.onValid(); + if (attached) { + updateIds(); + } + } + + @Override + protected void onInvalid() { + super.onInvalid(); + if (attached) { + updateIds(); + } + } + + private void updateIds() { + updateIds(getValue()); + } + + @Override + protected void updateIds(final String value) { + if (Strings.isEmpty(value)) { + ids = EMPTY_IDS; + } else { + if (value.indexOf('|') == -1) { + ids = value.split(","); + selectedId = null; + } else { + String[] splitted = value.split("\\|"); + selectedId = splitted[0]; + ids = splitted[1].split(","); + } + } + } +} http://git-wip-us.apache.org/repos/asf/syncope/blob/2d194636/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/SpinnerFieldPanel.java ---------------------------------------------------------------------- diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/SpinnerFieldPanel.java b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/SpinnerFieldPanel.java new file mode 100644 index 0000000..4f71f81 --- /dev/null +++ b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/SpinnerFieldPanel.java @@ -0,0 +1,197 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.client.console.wicket.markup.html.form; + +import java.io.Serializable; +import java.util.List; +import java.util.UUID; +import org.apache.commons.lang3.math.NumberUtils; +import org.apache.syncope.client.console.commons.Constants; +import org.apache.wicket.ajax.AjaxRequestTarget; +import org.apache.wicket.ajax.form.AjaxFormComponentUpdatingBehavior; +import org.apache.wicket.markup.html.basic.Label; +import org.apache.wicket.markup.html.form.TextField; +import org.apache.wicket.markup.html.list.ListItem; +import org.apache.wicket.model.IModel; +import org.apache.wicket.model.Model; +import org.springframework.util.StringUtils; + +public class SpinnerFieldPanel<T extends Number> extends FieldPanel<T> { + + private static final long serialVersionUID = 6413819574530703577L; + + private final String name; + + private final Class<T> reference; + + private final IModel<T> model; + + private final T min; + + private final T max; + + @SuppressWarnings("unchecked") + public SpinnerFieldPanel(final String id, final String name, final Class<T> reference, final IModel<T> model, + final T min, final T max) { + + super(id, model); + this.name = name; + this.reference = reference; + this.model = model; + this.min = min; + this.max = max; + + String uuid = UUID.randomUUID().toString(); + field = new TextField<T>("spinnerField", model, reference); + field.setMarkupId(uuid); + add(field.setLabel(new Model<String>(name))); + + if (!isReadOnly()) { + field.add(new AjaxFormComponentUpdatingBehavior(Constants.ON_CHANGE) { + + private static final long serialVersionUID = -1107858522700306810L; + + @Override + protected void onUpdate(final AjaxRequestTarget target) { + // nothing to do + } + }); + } + + final StringBuilder statements = new StringBuilder(); + statements.append("jQuery(function() {"). + append("var spinner = $('#").append(uuid).append("').spinner();"). + append("$('#").append(uuid).append("').spinner("). + append("'option', 'stop', function(event, ui) { $(this).change(); });"); + if (this.min != null) { + statements. + append("$('#").append(uuid).append("').spinner("). + append("'option', 'min', ").append(this.min).append(");"); + } + if (this.max != null) { + statements. + append("$('#").append(uuid).append("').spinner("). + append("'option', 'max', ").append(this.max).append(");"); + } + statements.append("});"); + Label spinnerFieldJS = new Label("spinnerFieldJS", statements.toString()); + spinnerFieldJS.setEscapeModelStrings(false); + add(spinnerFieldJS); + } + + @Override + public SpinnerFieldPanel<T> setNewModel(final List<Serializable> list) { + setNewModel(new Model<T>() { + + private static final long serialVersionUID = 527651414610325237L; + + @Override + public T getObject() { + T value = null; + + if (list != null && !list.isEmpty() && StringUtils.hasText(list.get(0).toString())) { + value = reference.equals(Integer.class) + ? reference.cast(NumberUtils.toInt(list.get(0).toString())) + : reference.equals(Long.class) + ? reference.cast(NumberUtils.toLong(list.get(0).toString())) + : reference.equals(Short.class) + ? reference.cast(NumberUtils.toShort(list.get(0).toString())) + : reference.equals(Float.class) + ? reference.cast(NumberUtils.toFloat(list.get(0).toString())) + : reference.equals(byte.class) + ? reference.cast(NumberUtils.toByte(list.get(0).toString())) + : reference.cast(NumberUtils.toDouble(list.get(0).toString())); + } + + return value; + } + + @Override + public void setObject(final T object) { + list.clear(); + if (object != null) { + list.add(object.toString()); + } + } + }); + + return this; + } + + @SuppressWarnings("rawtypes") + @Override + public SpinnerFieldPanel<T> setNewModel(final ListItem item) { + field.setModel(new Model<T>() { + + private static final long serialVersionUID = 6799404673615637845L; + + @Override + public T getObject() { + T number = null; + + final Object obj = item.getModelObject(); + + if (obj != null && !obj.toString().isEmpty()) { + if (obj instanceof String) { + number = reference.equals(Integer.class) + ? reference.cast(Integer.valueOf((String) obj)) + : reference.equals(Long.class) + ? reference.cast(Long.valueOf((String) obj)) + : reference.equals(Short.class) + ? reference.cast(Short.valueOf((String) obj)) + : reference.equals(Float.class) + ? reference.cast(Float.valueOf((String) obj)) + : reference.equals(byte.class) + ? reference.cast(Byte.valueOf((String) obj)) + : reference.cast(Double.valueOf((String) obj)); + } else if (obj instanceof Number) { + // Don't parse anything + number = reference.cast(obj); + } + } + + return number; + } + + @Override + @SuppressWarnings("unchecked") + public void setObject(final T object) { + item.setModelObject(object == null ? null : object.toString()); + } + }); + + return this; + } + + @Override + public SpinnerFieldPanel<T> clone() { + SpinnerFieldPanel<T> panel = new SpinnerFieldPanel<T>(getId(), name, reference, model, min, max); + + panel.setRequired(isRequired()); + panel.setReadOnly(isReadOnly()); + panel.setTitle(title); + + if (isRequiredLabelAdded) { + panel.addRequiredLabel(); + } + + return panel; + } + +} http://git-wip-us.apache.org/repos/asf/syncope/blob/2d194636/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/preview/AbstractBinaryPreviewer.java ---------------------------------------------------------------------- diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/preview/AbstractBinaryPreviewer.java b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/preview/AbstractBinaryPreviewer.java new file mode 100644 index 0000000..24bdb47 --- /dev/null +++ b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/preview/AbstractBinaryPreviewer.java @@ -0,0 +1,46 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.client.console.wicket.markup.html.form.preview; + +import org.apache.wicket.Component; +import org.apache.wicket.markup.html.panel.Panel; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public abstract class AbstractBinaryPreviewer extends Panel { + + /** + * Logger. + */ + protected static final Logger LOG = LoggerFactory.getLogger(AbstractBinaryPreviewer.class); + + private static final long serialVersionUID = -2482706463911903025L; + + protected final String mimeType; + + protected final byte[] uploadedBytes; + + public AbstractBinaryPreviewer(final String id, final String mimeType, final byte[] uploadedBytes) { + super(id); + this.mimeType = mimeType; + this.uploadedBytes = uploadedBytes; + } + + public abstract Component preview(); +} http://git-wip-us.apache.org/repos/asf/syncope/blob/2d194636/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/preview/BinaryCertPreviewer.java ---------------------------------------------------------------------- diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/preview/BinaryCertPreviewer.java b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/preview/BinaryCertPreviewer.java new file mode 100644 index 0000000..61589d7 --- /dev/null +++ b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/preview/BinaryCertPreviewer.java @@ -0,0 +1,70 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.client.console.wicket.markup.html.form.preview; + +import java.io.ByteArrayInputStream; +import java.security.cert.CertificateFactory; +import java.security.cert.X509Certificate; +import javax.naming.ldap.LdapName; +import javax.naming.ldap.Rdn; +import org.apache.commons.lang3.StringUtils; +import org.apache.syncope.client.console.BinaryPreview; +import org.apache.wicket.Component; +import org.apache.wicket.markup.html.basic.Label; +import org.apache.wicket.model.Model; +import org.apache.wicket.util.io.IOUtils; + +@BinaryPreview(mimeTypes = { "application/x-x509-ca-cert", "application/x-x509-user-cert", "application/pkix-cert" }) +public class BinaryCertPreviewer extends AbstractBinaryPreviewer { + + private static final long serialVersionUID = -5843835939538055110L; + + public BinaryCertPreviewer(final String id, final String mimeType, final byte[] uploadedBytes) { + super(id, mimeType, uploadedBytes); + } + + @Override + public Component preview() { + final Label commonNameLabel = new Label("certCommonName", new Model<String>()); + final ByteArrayInputStream certificateStream = new ByteArrayInputStream(uploadedBytes); + try { + final X509Certificate certificate = (X509Certificate) CertificateFactory.getInstance("X.509"). + generateCertificate(certificateStream); + + final StringBuilder commonNameBuilder = new StringBuilder("cn="); + + final LdapName ldapName = new LdapName(certificate.getIssuerDN().getName()); + + for (Rdn rdn : ldapName.getRdns()) { + if ("CN".equalsIgnoreCase(rdn.getType())) { + commonNameBuilder.append(rdn.getValue() == null + ? StringUtils.EMPTY + : rdn.getValue().toString()); + } + } + commonNameLabel.setDefaultModelObject(commonNameBuilder.toString()); + } catch (Exception e) { + LOG.error("Error evaluating certificate file", e); + throw new IllegalArgumentException("Error evaluating certificate file", e); + } finally { + IOUtils.closeQuietly(certificateStream); + } + return this.add(commonNameLabel); + } +} http://git-wip-us.apache.org/repos/asf/syncope/blob/2d194636/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/preview/BinaryImagePreviewer.java ---------------------------------------------------------------------- diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/preview/BinaryImagePreviewer.java b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/preview/BinaryImagePreviewer.java new file mode 100644 index 0000000..35e442e --- /dev/null +++ b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/form/preview/BinaryImagePreviewer.java @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.client.console.wicket.markup.html.form.preview; + +import org.apache.syncope.client.console.BinaryPreview; +import org.apache.wicket.Component; +import org.apache.wicket.extensions.markup.html.image.resource.ThumbnailImageResource; +import org.apache.wicket.markup.html.image.NonCachingImage; +import org.apache.wicket.request.resource.DynamicImageResource; +import org.apache.wicket.request.resource.IResource; + +@BinaryPreview(mimeTypes = { "image/jpeg", "image/png", "image/gif", "image/bmp", "image/x-png", "image/vnd.wap.wbmp" }) +public class BinaryImagePreviewer extends AbstractBinaryPreviewer { + + private static final long serialVersionUID = 3338812359368457349L; + + private static final int IMG_SIZE = 230; + + public BinaryImagePreviewer(final String id, final String mimeType, final byte[] uploadedBytes) { + super(id, mimeType, uploadedBytes); + } + + @Override + public Component preview() { + return this.add(new NonCachingImage("previewImage", new ThumbnailImageResource(new DynamicImageResource() { + + private static final long serialVersionUID = 923201517955737928L; + + @Override + protected byte[] getImageData(final IResource.Attributes attributes) { + return uploadedBytes; + } + }, IMG_SIZE))); + } +} http://git-wip-us.apache.org/repos/asf/syncope/blob/2d194636/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/link/VeilPopupSettings.java ---------------------------------------------------------------------- diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/link/VeilPopupSettings.java b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/link/VeilPopupSettings.java new file mode 100644 index 0000000..51c8ec5 --- /dev/null +++ b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/link/VeilPopupSettings.java @@ -0,0 +1,32 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.client.console.wicket.markup.html.link; + +import org.apache.wicket.markup.html.link.PopupSettings; + +public class VeilPopupSettings extends PopupSettings { + + private static final long serialVersionUID = -2727046117490858226L; + + @Override + public String getPopupJavaScript() { + return "document.getElementById('veil').style.display = 'block';" + super.getPopupJavaScript(); + } + +} http://git-wip-us.apache.org/repos/asf/syncope/blob/2d194636/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/list/AltListView.java ---------------------------------------------------------------------- diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/list/AltListView.java b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/list/AltListView.java new file mode 100644 index 0000000..5a491ae --- /dev/null +++ b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/list/AltListView.java @@ -0,0 +1,59 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.client.console.wicket.markup.html.list; + +import java.util.List; +import org.apache.wicket.markup.ComponentTag; +import org.apache.wicket.markup.html.list.ListItem; +import org.apache.wicket.markup.html.list.ListView; +import org.apache.wicket.model.IModel; + +public abstract class AltListView<T> extends ListView<T> { + + private static final long serialVersionUID = 251378224847354710L; + + public AltListView(final String id) { + super(id); + } + + public AltListView(final String id, final IModel<? extends List<? extends T>> model) { + super(id, model); + } + + public AltListView(final String id, final List<? extends T> list) { + super(id, list); + } + + @Override + protected ListItem<T> newItem(final int index, final IModel<T> itemModel) { + return new ListItem<T>(index, itemModel) { + + private static final long serialVersionUID = 5473483270932376694L; + + @Override + protected void onComponentTag(final ComponentTag tag) { + if (index % 2 == 0) { + tag.append("class", "alt", " "); + } + + super.onComponentTag(tag); + } + }; + } +} http://git-wip-us.apache.org/repos/asf/syncope/blob/2d194636/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/list/ConnConfPropertyListView.java ---------------------------------------------------------------------- diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/list/ConnConfPropertyListView.java b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/list/ConnConfPropertyListView.java new file mode 100644 index 0000000..30775f5 --- /dev/null +++ b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/list/ConnConfPropertyListView.java @@ -0,0 +1,152 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.client.console.wicket.markup.html.list; + +import java.io.Serializable; +import java.util.List; +import java.util.Set; +import org.apache.commons.lang3.StringUtils; +import org.apache.syncope.client.console.commons.Constants; +import org.apache.syncope.client.console.wicket.markup.html.form.AjaxCheckBoxPanel; +import org.apache.syncope.client.console.wicket.markup.html.form.AjaxPasswordFieldPanel; +import org.apache.syncope.client.console.wicket.markup.html.form.AjaxTextFieldPanel; +import org.apache.syncope.client.console.wicket.markup.html.form.FieldPanel; +import org.apache.syncope.client.console.wicket.markup.html.form.MultiFieldPanel; +import org.apache.syncope.client.console.wicket.markup.html.form.SpinnerFieldPanel; +import org.apache.syncope.common.lib.types.ConnConfProperty; +import org.apache.wicket.markup.html.basic.Label; +import org.apache.wicket.markup.html.form.PasswordTextField; +import org.apache.wicket.markup.html.list.ListItem; +import org.apache.wicket.model.IModel; +import org.apache.wicket.model.Model; +import org.apache.wicket.model.PropertyModel; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.util.ClassUtils; + +public class ConnConfPropertyListView extends AltListView<ConnConfProperty> { + + private static final long serialVersionUID = -5239334900329150316L; + + private static final Logger LOG = LoggerFactory.getLogger(ConnConfPropertyListView.class); + + private final boolean withOverridable; + + private final Set<ConnConfProperty> configuration; + + public ConnConfPropertyListView(final String id, final IModel<? extends List<? extends ConnConfProperty>> model, + final boolean withOverridable, final Set<ConnConfProperty> configuration) { + + super(id, model); + this.configuration = configuration; + this.withOverridable = withOverridable; + } + + @Override + @SuppressWarnings({ "unchecked", "rawtypes" }) + protected void populateItem(final ListItem<ConnConfProperty> item) { + final ConnConfProperty property = item.getModelObject(); + + final Label label = new Label("connPropAttrSchema", + StringUtils.isBlank(property.getSchema().getDisplayName()) + ? property.getSchema().getName() + : property.getSchema().getDisplayName()); + item.add(label); + + FieldPanel<? extends Serializable> field; + boolean required = false; + boolean isArray = false; + + if (property.getSchema().isConfidential() + || Constants.GUARDED_STRING.equalsIgnoreCase(property.getSchema().getType()) + || Constants.GUARDED_BYTE_ARRAY.equalsIgnoreCase(property.getSchema().getType())) { + + field = new AjaxPasswordFieldPanel("panel", + label.getDefaultModelObjectAsString(), new Model<String>()); + ((PasswordTextField) field.getField()).setResetPassword(false); + + required = property.getSchema().isRequired(); + } else { + Class<?> propertySchemaClass; + try { + propertySchemaClass = + ClassUtils.forName(property.getSchema().getType(), ClassUtils.getDefaultClassLoader()); + if (ClassUtils.isPrimitiveOrWrapper(propertySchemaClass)) { + propertySchemaClass = org.apache.commons.lang3.ClassUtils.primitiveToWrapper(propertySchemaClass); + } + } catch (Exception e) { + LOG.error("Error parsing attribute type", e); + propertySchemaClass = String.class; + } + + if (ClassUtils.isAssignable(Number.class, propertySchemaClass)) { + @SuppressWarnings("unchecked") + final Class<Number> numberClass = (Class<Number>) propertySchemaClass; + field = new SpinnerFieldPanel<Number>("panel", + label.getDefaultModelObjectAsString(), numberClass, new Model<Number>(), null, null); + + required = property.getSchema().isRequired(); + } else if (ClassUtils.isAssignable(Boolean.class, propertySchemaClass)) { + field = new AjaxCheckBoxPanel("panel", + label.getDefaultModelObjectAsString(), new Model<Boolean>()); + } else { + field = new AjaxTextFieldPanel("panel", + label.getDefaultModelObjectAsString(), new Model<String>()); + + required = property.getSchema().isRequired(); + } + + if (propertySchemaClass.isArray()) { + isArray = true; + } + } + + field.setTitle(property.getSchema().getHelpMessage()); + + if (required) { + field.addRequiredLabel(); + } + + if (isArray) { + if (property.getValues().isEmpty()) { + property.getValues().add(null); + } + + final MultiFieldPanel multiFieldPanel = new MultiFieldPanel("panel", + new PropertyModel<List<String>>(property, "values"), field); + item.add(multiFieldPanel); + } else { + setNewFieldModel(field, property.getValues()); + item.add(field); + } + + if (withOverridable) { + item.add(new AjaxCheckBoxPanel("connPropAttrOverridable", + "connPropAttrOverridable", new PropertyModel<Boolean>(property, "overridable"))); + } + + configuration.add(property); + } + + @SuppressWarnings({ "unchecked", "rawtypes" }) + private void setNewFieldModel(final FieldPanel field, final List<Object> values) { + field.setNewModel(values); + } + +} http://git-wip-us.apache.org/repos/asf/syncope/blob/2d194636/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/tree/DefaultMutableTreeNodeExpansion.java ---------------------------------------------------------------------- diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/tree/DefaultMutableTreeNodeExpansion.java b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/tree/DefaultMutableTreeNodeExpansion.java new file mode 100644 index 0000000..50db23c --- /dev/null +++ b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/tree/DefaultMutableTreeNodeExpansion.java @@ -0,0 +1,160 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.client.console.wicket.markup.html.tree; + +import java.io.Serializable; +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; +import javax.swing.tree.DefaultMutableTreeNode; +import org.apache.syncope.common.lib.to.RoleTO; +import org.apache.wicket.MetaDataKey; +import org.apache.wicket.Session; + +public class DefaultMutableTreeNodeExpansion implements Set<DefaultMutableTreeNode>, Serializable { + + private static final long serialVersionUID = -2864060875425661224L; + + private static MetaDataKey<DefaultMutableTreeNodeExpansion> KEY = + new MetaDataKey<DefaultMutableTreeNodeExpansion>() { + + private static final long serialVersionUID = 3109256773218160485L; + + }; + + private Set<Long> ids = new HashSet<Long>(); + + private boolean inverse; + + public void expandAll() { + ids.clear(); + + inverse = true; + } + + public void collapseAll() { + ids.clear(); + + inverse = false; + } + + @Override + public boolean add(final DefaultMutableTreeNode node) { + RoleTO roleTO = (RoleTO) node.getUserObject(); + boolean isAdded; + if (inverse) { + isAdded = ids.remove(roleTO.getKey()); + } else { + isAdded = ids.add(roleTO.getKey()); + } + return isAdded; + } + + @Override + public boolean remove(final Object object) { + DefaultMutableTreeNode node = (DefaultMutableTreeNode) object; + RoleTO roleTO = (RoleTO) node.getUserObject(); + boolean isRemoved; + if (inverse) { + isRemoved = ids.add(roleTO.getKey()); + } else { + isRemoved = ids.remove(roleTO.getKey()); + } + return isRemoved; + } + + @Override + public boolean contains(final Object object) { + DefaultMutableTreeNode node = (DefaultMutableTreeNode) object; + RoleTO roleTO = (RoleTO) node.getUserObject(); + boolean isContained; + if (inverse) { + isContained = !ids.contains(roleTO.getKey()); + } else { + isContained = ids.contains(roleTO.getKey()); + } + return isContained; + } + + @Override + public void clear() { + throw new UnsupportedOperationException(); + } + + @Override + public int size() { + throw new UnsupportedOperationException(); + } + + @Override + public boolean isEmpty() { + throw new UnsupportedOperationException(); + } + + @Override + public <A> A[] toArray(final A[] a) { + throw new UnsupportedOperationException(); + } + + @Override + public Iterator<DefaultMutableTreeNode> iterator() { + throw new UnsupportedOperationException(); + } + + @Override + public Object[] toArray() { + throw new UnsupportedOperationException(); + } + + @Override + public boolean containsAll(Collection<?> c) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean addAll(Collection<? extends DefaultMutableTreeNode> c) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean retainAll(Collection<?> c) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean removeAll(Collection<?> c) { + throw new UnsupportedOperationException(); + } + + /** + * Get the expansion for the session. + * + * @return expansion + */ + public static DefaultMutableTreeNodeExpansion get() { + DefaultMutableTreeNodeExpansion expansion = Session.get().getMetaData(KEY); + if (expansion == null) { + expansion = new DefaultMutableTreeNodeExpansion(); + + Session.get().setMetaData(KEY, expansion); + } + return expansion; + } +} http://git-wip-us.apache.org/repos/asf/syncope/blob/2d194636/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/tree/DefaultMutableTreeNodeExpansionModel.java ---------------------------------------------------------------------- diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/tree/DefaultMutableTreeNodeExpansionModel.java b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/tree/DefaultMutableTreeNodeExpansionModel.java new file mode 100644 index 0000000..1b342bd --- /dev/null +++ b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/tree/DefaultMutableTreeNodeExpansionModel.java @@ -0,0 +1,36 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.client.console.wicket.markup.html.tree; + +import java.util.Set; + +import javax.swing.tree.DefaultMutableTreeNode; + +import org.apache.wicket.model.AbstractReadOnlyModel; + +public class DefaultMutableTreeNodeExpansionModel + extends AbstractReadOnlyModel<Set<DefaultMutableTreeNode>> { + + private static final long serialVersionUID = -3407581132184748054L; + + @Override + public Set<DefaultMutableTreeNode> getObject() { + return DefaultMutableTreeNodeExpansion.get(); + } +} http://git-wip-us.apache.org/repos/asf/syncope/blob/2d194636/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/tree/TreeRolePanel.java ---------------------------------------------------------------------- diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/tree/TreeRolePanel.java b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/tree/TreeRolePanel.java new file mode 100644 index 0000000..b0be4e9 --- /dev/null +++ b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/tree/TreeRolePanel.java @@ -0,0 +1,121 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.client.console.wicket.markup.html.tree; + +import javax.swing.tree.DefaultMutableTreeNode; +import org.apache.syncope.client.console.commons.RoleTreeBuilder; +import org.apache.syncope.client.console.commons.XMLRolesReader; +import org.apache.syncope.client.console.pages.Roles.TreeNodeClickUpdate; +import org.apache.syncope.common.lib.to.RoleTO; +import org.apache.wicket.Component; +import org.apache.wicket.ajax.AjaxRequestTarget; +import org.apache.wicket.authroles.authorization.strategies.role.metadata.MetaDataRoleAuthorizationStrategy; +import org.apache.wicket.event.Broadcast; +import org.apache.wicket.event.IEvent; +import org.apache.wicket.extensions.markup.html.repeater.tree.DefaultNestedTree; +import org.apache.wicket.extensions.markup.html.repeater.tree.ITreeProvider; +import org.apache.wicket.extensions.markup.html.repeater.tree.NestedTree; +import org.apache.wicket.extensions.markup.html.repeater.tree.content.Folder; +import org.apache.wicket.extensions.markup.html.repeater.tree.theme.WindowsTheme; +import org.apache.wicket.markup.html.WebMarkupContainer; +import org.apache.wicket.markup.html.panel.Panel; +import org.apache.wicket.model.IModel; +import org.apache.wicket.model.Model; +import org.apache.wicket.spring.injection.annot.SpringBean; + +public class TreeRolePanel extends Panel { + + private static final long serialVersionUID = 1762003213871836869L; + + @SpringBean + private RoleTreeBuilder roleTreeBuilder; + + @SpringBean + private XMLRolesReader xmlRolesReader; + + private WebMarkupContainer treeContainer; + + private NestedTree<DefaultMutableTreeNode> tree; + + public TreeRolePanel(final String id) { + super(id); + + treeContainer = new WebMarkupContainer("treeContainer"); + treeContainer.setOutputMarkupId(true); + add(treeContainer); + updateTree(); + } + + private void updateTree() { + final ITreeProvider<DefaultMutableTreeNode> treeProvider = new TreeRoleProvider(roleTreeBuilder, true); + final DefaultMutableTreeNodeExpansionModel treeModel = new DefaultMutableTreeNodeExpansionModel(); + + tree = new DefaultNestedTree<DefaultMutableTreeNode>("treeTable", treeProvider, treeModel) { + + private static final long serialVersionUID = 7137658050662575546L; + + @Override + protected Component newContentComponent(final String id, final IModel<DefaultMutableTreeNode> node) { + final DefaultMutableTreeNode treeNode = node.getObject(); + final RoleTO roleTO = (RoleTO) treeNode.getUserObject(); + + return new Folder<DefaultMutableTreeNode>(id, TreeRolePanel.this.tree, node) { + + private static final long serialVersionUID = 9046323319920426493L; + + @Override + protected boolean isClickable() { + return true; + } + + @Override + protected IModel<?> newLabelModel(final IModel<DefaultMutableTreeNode> model) { + return new Model<>(roleTO.getDisplayName()); + } + + @Override + protected void onClick(final AjaxRequestTarget target) { + super.onClick(target); + + send(getPage(), Broadcast.BREADTH, new TreeNodeClickUpdate(target, roleTO.getKey())); + } + }; + } + }; + tree.add(new WindowsTheme()); + tree.setOutputMarkupId(true); + + DefaultMutableTreeNodeExpansion.get().expandAll(); + + MetaDataRoleAuthorizationStrategy.authorize(tree, ENABLE, xmlRolesReader.getEntitlement("Roles", "read")); + + treeContainer.addOrReplace(tree); + } + + @Override + public void onEvent(final IEvent<?> event) { + super.onEvent(event); + + if (event.getPayload() instanceof TreeNodeClickUpdate) { + final TreeNodeClickUpdate update = (TreeNodeClickUpdate) event.getPayload(); + updateTree(); + update.getTarget().add(treeContainer); + } + } +} http://git-wip-us.apache.org/repos/asf/syncope/blob/2d194636/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/tree/TreeRoleProvider.java ---------------------------------------------------------------------- diff --git a/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/tree/TreeRoleProvider.java b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/tree/TreeRoleProvider.java new file mode 100644 index 0000000..6fbe9a4 --- /dev/null +++ b/client/console/src/main/java/org/apache/syncope/client/console/wicket/markup/html/tree/TreeRoleProvider.java @@ -0,0 +1,43 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.syncope.client.console.wicket.markup.html.tree; + +import javax.swing.tree.DefaultMutableTreeNode; +import org.apache.syncope.client.console.commons.RoleTreeBuilder; +import org.apache.wicket.extensions.markup.html.repeater.util.TreeModelProvider; +import org.apache.wicket.model.IModel; +import org.apache.wicket.model.Model; + +public class TreeRoleProvider extends TreeModelProvider<DefaultMutableTreeNode> { + + private static final long serialVersionUID = -7741964777100892335L; + + public TreeRoleProvider(final RoleTreeBuilder roleTreeBuilder) { + this(roleTreeBuilder, false); + } + + public TreeRoleProvider(final RoleTreeBuilder roleTreeBuilder, final boolean rootVisible) { + super(roleTreeBuilder.build(), rootVisible); + } + + @Override + public IModel<DefaultMutableTreeNode> model(final DefaultMutableTreeNode treeNode) { + return new Model<DefaultMutableTreeNode>(treeNode); + } +} http://git-wip-us.apache.org/repos/asf/syncope/blob/2d194636/client/console/src/main/resources/META-INF/cxf/org.apache.cxf.Logger ---------------------------------------------------------------------- diff --git a/client/console/src/main/resources/META-INF/cxf/org.apache.cxf.Logger b/client/console/src/main/resources/META-INF/cxf/org.apache.cxf.Logger new file mode 100644 index 0000000..6e7bd36 --- /dev/null +++ b/client/console/src/main/resources/META-INF/cxf/org.apache.cxf.Logger @@ -0,0 +1 @@ +org.apache.cxf.common.logging.Slf4jLogger http://git-wip-us.apache.org/repos/asf/syncope/blob/2d194636/client/console/src/main/resources/META-INF/resources/css/bulk.css ---------------------------------------------------------------------- diff --git a/client/console/src/main/resources/META-INF/resources/css/bulk.css b/client/console/src/main/resources/META-INF/resources/css/bulk.css new file mode 100644 index 0000000..1f0e621 --- /dev/null +++ b/client/console/src/main/resources/META-INF/resources/css/bulk.css @@ -0,0 +1,97 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +th.checkGroupColumn{ + width: 20px; +} + +td.checkGroupColumn{ + text-align: center; +} + +div.bulkAction{ + display:inline-table; +} + +div.bulkActionCell{ + display: table-cell; + vertical-align: middle; + text-align: center; + width: 40px; + padding-left: 7px; +} + +.pageRowElement{ + display: inline-table; + width: 95%; +} + +div#selectedObjects{ + text-align: center; + margin-top: 10px; +} + +div#selectedObjects table { + margin: 1em 0; + border-collapse: collapse; +} + +div#selectedObjects table td, div#selectedObjects table th { + border: 1px solid #eee; + padding: .6em 10px; +} + +div#actionRow{ + height: 30px; + overflow: hidden; + text-align: left; + margin-top: 10px; +} + +div#actions{ + display: inline-table; + height: 30px; + overflow: hidden; +} + +div#actions div#actionPanel{ + display: table-cell; + height: 30px; + overflow: hidden; + cursor: auto; + background: none; + padding: 0px 10px; + vertical-align: middle; +} + +div#actions div#cancelBtmForm{ + display: table-cell; + height: 30px; + overflow: hidden; + vertical-align: middle; + padding-left: 3px; +} + +div#actions div#cancelBtmForm form{ + padding: 0px; + margin: 0px; +} + +div#actions div#cancelBtmForm form input#cancel{ + padding: 0.6em 1em; +}
