/* * Copyright (c) 2010-2015 Evolveum * * Licensed 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 com.evolveum.midpoint.web.component.search; import com.evolveum.midpoint.gui.api.component.BasePanel; import com.evolveum.midpoint.gui.api.model.LoadableModel; import com.evolveum.midpoint.gui.api.page.PageBase; import com.evolveum.midpoint.gui.api.util.WebModelServiceUtils; import com.evolveum.midpoint.prism.ItemDefinition; import com.evolveum.midpoint.prism.PrismObject; import com.evolveum.midpoint.prism.PrismReferenceValue; import com.evolveum.midpoint.schema.GetOperationOptions; import com.evolveum.midpoint.schema.SelectorOptions; import com.evolveum.midpoint.schema.result.OperationResult; import com.evolveum.midpoint.task.api.Task; import com.evolveum.midpoint.util.DisplayableValue; import com.evolveum.midpoint.util.logging.Trace; import com.evolveum.midpoint.util.logging.TraceManager; import com.evolveum.midpoint.web.component.AjaxButton; import com.evolveum.midpoint.web.component.AjaxSubmitButton; import com.evolveum.midpoint.web.component.util.VisibleEnableBehaviour; import com.evolveum.midpoint.xml.ns._public.common.common_3.LookupTableType; import org.apache.commons.lang.StringUtils; 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.basic.Label; import org.apache.wicket.markup.html.form.Form; import org.apache.wicket.markup.html.list.ListItem; import org.apache.wicket.markup.html.list.ListView; import org.apache.wicket.model.AbstractReadOnlyModel; import org.apache.wicket.model.IModel; import org.apache.wicket.model.Model; import org.apache.wicket.model.PropertyModel; import java.io.Serializable; import java.util.ArrayList; import java.util.Collection; import java.util.List; /** * @author Viliam Repan (lazyman) */ public class SearchItemPanel extends BasePanel<SearchItem> { private static final Trace LOG = TraceManager.getTrace(SearchItemPanel.class); private static final String ID_MAIN_BUTTON = "mainButton"; private static final String ID_LABEL = "label"; private static final String ID_DELETE_BUTTON = "deleteButton"; private static final String ID_POPOVER = "popover"; private static final String ID_POPOVER_BODY = "popoverBody"; private static final String ID_UPDATE = "update"; private static final String ID_CLOSE = "close"; private static final String ID_VALUES = "values"; private static final String ID_VALUE = "value"; private LoadableModel<SearchItemPopoverDto> popoverModel; public SearchItemPanel(String id, IModel<SearchItem> model) { super(id, model); initLayout(); } @Override protected void onConfigure() { super.onConfigure(); SearchItem item = getModelObject(); if (!item.isEditWhenVisible()) { return; } item.setEditWhenVisible(false); //todo show popover for this item somehow [lazyman] } private void initLayout() { popoverModel = new LoadableModel<SearchItemPopoverDto>(false) { @Override protected SearchItemPopoverDto load() { return loadPopoverItems(); } }; AjaxLink mainButton = new AjaxLink(ID_MAIN_BUTTON) { @Override public void onClick(AjaxRequestTarget target) { editPerformed(target); } }; add(mainButton); Label label = new Label(ID_LABEL, createLabelModel()); label.setRenderBodyOnly(true); mainButton.add(label); AjaxLink deleteButton = new AjaxLink(ID_DELETE_BUTTON) { @Override public void onClick(AjaxRequestTarget target) { deletePerformed(target); } }; mainButton.add(deleteButton); deleteButton.add(new VisibleEnableBehaviour() { @Override public boolean isVisible() { return !getModelObject().isFixed(); } }); initPopover(); } private SearchItemPopoverDto loadPopoverItems() { SearchItemPopoverDto dto = new SearchItemPopoverDto(); SearchItem item = getModelObject(); for (DisplayableValue<? extends Serializable> value : (List<DisplayableValue>) item.getValues()) { DisplayableValue itemValue = new SearchValue(value.getValue(), value.getLabel()); dto.getValues().add(itemValue); } if (dto.getValues().isEmpty()) { dto.getValues().add(new SearchValue()); } return dto; } private void initPopover() { WebMarkupContainer popover = new WebMarkupContainer(ID_POPOVER); popover.setOutputMarkupId(true); add(popover); WebMarkupContainer popoverBody = new WebMarkupContainer(ID_POPOVER_BODY); popoverBody.setOutputMarkupId(true); popover.add(popoverBody); ListView values = new ListView<DisplayableValue>(ID_VALUES, new PropertyModel<List<DisplayableValue>>(popoverModel, SearchItem.F_VALUES)) { @Override protected void populateItem(final ListItem<DisplayableValue> item) { item.add(AttributeModifier.replace("style", new AbstractReadOnlyModel<String>() { @Override public String getObject() { return item.getIndex() != 0 ? "margin-top: 5px;" : null; } })); SearchPopupPanel fragment = createPopoverFragment(item.getModel()); fragment.setRenderBodyOnly(true); item.add(fragment); } }; popoverBody.add(values); AjaxSubmitButton update = new AjaxSubmitButton(ID_UPDATE, createStringResource("SearchItemPanel.update")) { @Override protected void onSubmit(AjaxRequestTarget target, Form<?> form) { updateItemPerformed(target); } }; popoverBody.add(update); AjaxButton close = new AjaxButton(ID_CLOSE, createStringResource("SearchItemPanel.close")) { @Override public void onClick(AjaxRequestTarget target) { closeEditPopoverPerformed(target); } }; popoverBody.add(close); } private SearchPopupPanel createPopoverFragment(IModel<DisplayableValue> data) { SearchPopupPanel popup; SearchItem item = getModelObject(); IModel<? extends List> choices = null; switch (item.getType()) { case BROWSER: popup = new BrowserPopupPanel(ID_VALUE, data); break; case BOOLEAN: choices = createBooleanChoices(); case ENUM: if (choices == null) { choices = new Model((Serializable) item.getAllowedValues()); } popup = new ComboPopupPanel(ID_VALUE, data, choices); break; case TEXT: default: PrismObject<LookupTableType> lookupTable = findLookupTable(item.getDefinition()); popup = new TextPopupPanel(ID_VALUE, data, lookupTable); } return popup; } private PrismObject<LookupTableType> findLookupTable(ItemDefinition definition) { PrismReferenceValue valueEnumerationRef = definition.getValueEnumerationRef(); if (valueEnumerationRef == null) { return null; } PageBase page = getPageBase(); String lookupTableUid = valueEnumerationRef.getOid(); Task task = page.createSimpleTask("loadLookupTable"); OperationResult result = task.getResult(); Collection<SelectorOptions<GetOperationOptions>> options = WebModelServiceUtils.createLookupTableRetrieveOptions(); return WebModelServiceUtils.loadObject(LookupTableType.class, lookupTableUid, options, page, task, result); } private IModel<List<DisplayableValue>> createBooleanChoices() { return new AbstractReadOnlyModel<List<DisplayableValue>>() { @Override public List<DisplayableValue> getObject() { List<DisplayableValue> list = new ArrayList<>(); list.add(new SearchValue(Boolean.TRUE, getString("Boolean.TRUE"))); list.add(new SearchValue(Boolean.FALSE, getString("Boolean.FALSE"))); return list; } }; } private IModel<String> createLabelModel() { return new AbstractReadOnlyModel<String>() { @Override public String getObject() { SearchItem item = getModelObject(); StringBuilder sb = new StringBuilder(); sb.append(item.getName()); sb.append(": "); List<String> values = new ArrayList<>(); for (DisplayableValue value : (List<DisplayableValue>) item.getValues()) { if (StringUtils.isNotEmpty(value.getLabel())) { values.add(value.getLabel()); } } if (!values.isEmpty()) { String or = createStringResource("SearchItemPanel.or").getString(); sb.append('"'); sb.append(StringUtils.join(values, "\" " + or + " \"")); sb.append('"'); } else { String all = createStringResource("SearchItemPanel.all").getString(); sb.append(all); } return sb.toString(); } }; } private void updateItemPerformed(AjaxRequestTarget target) { SearchItem item = getModelObject(); item.getValues().clear(); SearchItemPopoverDto dto = popoverModel.getObject(); for (DisplayableValue value : dto.getValues()) { item.getValues().add(value); } LOG.debug("Update item performed, item {} value is {}", item.getName(), item.getValues()); SearchPanel panel = findParent(SearchPanel.class); panel.refreshSearchForm(target); panel.searchPerformed(target); } public LoadableModel<SearchItemPopoverDto> getPopoverModel() { return popoverModel; } private void closeEditPopoverPerformed(AjaxRequestTarget target) { togglePopover(target); } private void editPerformed(AjaxRequestTarget target) { LOG.debug("Edit performed"); popoverModel.reset(); target.add(get(createComponentPath(ID_POPOVER, ID_POPOVER_BODY))); togglePopover(target); } public void togglePopover(AjaxRequestTarget target) { SearchPanel panel = findParent(SearchPanel.class); panel.togglePopover(target, get(ID_MAIN_BUTTON), get(ID_POPOVER), 0); } private void deletePerformed(AjaxRequestTarget target) { SearchItem item = getModelObject(); LOG.debug("Delete of item {} performed", item.getName()); Search search = item.getSearch(); search.delete(item); SearchPanel panel = findParent(SearchPanel.class); panel.refreshSearchForm(target); panel.searchPerformed(target); } void updatePopupBody(AjaxRequestTarget target) { target.add(get(createComponentPath(ID_POPOVER, ID_POPOVER_BODY))); } }