Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CAUSEWAY-3655: Layout Inconsitencies #2080

Draft
wants to merge 5 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@

import javax.xml.bind.annotation.XmlType;

import org.springframework.lang.Nullable;

import org.apache.causeway.applib.layout.component.CssClassFaPosition;

/**
Expand Down Expand Up @@ -211,7 +213,14 @@ enum Position {
RIGHT,
PANEL,
PANEL_DROPDOWN,
NOT_SPECIFIED
NOT_SPECIFIED;
public static boolean isBelow(@Nullable final Position position) { return position==BELOW; }
public static boolean isRight(@Nullable final Position position) { return position==RIGHT; }
public static boolean isPanel(@Nullable final Position position) { return position==PANEL; }
public static boolean isPanelDropdown(@Nullable final Position position) { return position==PANEL_DROPDOWN; }
public static boolean isNullOrNotSpecified(@Nullable final Position position) {
return position==null || position==NOT_SPECIFIED;
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -261,5 +261,4 @@ public void setLink(final Link link) {
'}';
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,82 @@
package org.apache.causeway.applib.layout.component;

import java.util.List;
import java.util.Optional;

import org.springframework.lang.Nullable;

import org.apache.causeway.applib.annotation.ActionLayout;
import org.apache.causeway.commons.internal.collections._Lists;

/**
* @since 1.x {@index}
*/
public interface ActionLayoutDataOwner extends Owner {

List<ActionLayoutData> getActions();
void setActions(List<ActionLayoutData> actions);

default void addAction(final ActionLayoutData actionLayoutData) {
if(getActions() == null) {
setActions(_Lists.newArrayList());
}
actionLayoutData.setOwner(this);
getActions().add(actionLayoutData);
}

public enum PositioningContext {
/**
* Positioning has NO meaning in this context, eg. <i>DomainObject</i> or <i>Collection</i>.
*/
HAS_NONE,
/**
* This context provides a panel, eg. field-sets. But orientation has NO meaning.
*/
HAS_PANEL,
/**
* In this context orientation has meaning, eg. detailed <i>Property</i> rendering.
* But panel related positioning also has meaning.
*/
HAS_ORIENTATION;

//TODO[CAUSEWAY-3655] update java-doc
/**
* In a HAS_PANEL context, action's position is normalized to either
* {@link org.apache.causeway.applib.annotation.ActionLayout.Position#PANEL_DROPDOWN} (default) or
* {@link org.apache.causeway.applib.annotation.ActionLayout.Position#PANEL}.
* <p>
* In a HAS_ORIENTATION context, action's position is normalized to either
* {@link org.apache.causeway.applib.annotation.ActionLayout.Position#BELOW} (default) or
* {@link org.apache.causeway.applib.annotation.ActionLayout.Position#RIGHT}.
* <p>
* In a HAS_NONE context, action's position is without meaning, hence returning {@link Optional#empty()}.
*/
public Optional<ActionLayout.Position> normalizePosition(final @Nullable ActionLayout.Position position) {
switch (this) {
case HAS_PANEL:
if(ActionLayout.Position.isNullOrNotSpecified(position)
|| ActionLayout.Position.isBelow(position)
|| ActionLayout.Position.isRight(position)) {
return Optional.of(ActionLayout.Position.PANEL_DROPDOWN);
}
return Optional.of(position); // keep as is
case HAS_ORIENTATION:
if(ActionLayout.Position.isNullOrNotSpecified(position)
// || ActionLayout.Position.isPanelDropdown(position)
// || ActionLayout.Position.isPanel(position)
) {
return Optional.of(ActionLayout.Position.BELOW);
}
return Optional.of(position); // keep as is
case HAS_NONE:
default:
// positioning has no meaning in this context
return Optional.empty();
}
}

}

PositioningContext positioningContext();

}
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@ public CollectionLayoutData(final String id) {
setId(id);
}

@Override
public PositioningContext positioningContext() {
return PositioningContext.HAS_NONE;
}

private String id;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,11 @@ public FieldSet(final String name) {
setName(name);
}



@Override
public PositioningContext positioningContext() {
return PositioningContext.HAS_PANEL;
}

private String id;

/**
Expand Down Expand Up @@ -131,7 +134,7 @@ public String getName() {
return name;
}

public void setName(String name) {
public void setName(final String name) {
this.name = name;
}

Expand All @@ -147,7 +150,7 @@ public List<ActionLayoutData> getActions() {
}

@Override
public void setActions(List<ActionLayoutData> actionLayoutDatas) {
public void setActions(final List<ActionLayoutData> actionLayoutDatas) {
this.actions = actionLayoutDatas;
}

Expand All @@ -161,7 +164,7 @@ public List<PropertyLayoutData> getProperties() {
return properties;
}

public void setProperties(List<PropertyLayoutData> properties) {
public void setProperties(final List<PropertyLayoutData> properties) {
this.properties = properties;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,11 @@ public PropertyLayoutData(final String id) {
this.id = id;
}

@Override
public PositioningContext positioningContext() {
return PositioningContext.HAS_ORIENTATION;
}

private String id;

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,11 +109,11 @@ protected void traverseActions(
final ActionLayoutDataOwner actionLayoutDataOwner,
final GridAbstract.Visitor visitor) {

final List<ActionLayoutData> actionLayoutDatas = actionLayoutDataOwner.getActions();
if(actionLayoutDatas == null) {
final List<ActionLayoutData> actionLayoutDataList = actionLayoutDataOwner.getActions();
if(actionLayoutDataList == null) {
return;
}
for (final ActionLayoutData actionLayoutData : new ArrayList<>(actionLayoutDatas)) {
for (final ActionLayoutData actionLayoutData : new ArrayList<>(actionLayoutDataList)) {
actionLayoutData.setOwner(actionLayoutDataOwner);
visitor.visit(actionLayoutData);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,17 +39,14 @@
import org.apache.causeway.commons.internal.primitives._Ints.Bound;

/**
* A column within a row which, depending on its {@link #getSpan()}, could be as narrow as 1/12th of the page's width, all the way up to spanning the entire page.
*
* A column within a row which, depending on its {@link #getSpan()}, could be as narrow as 1/12th of the page's width,
* all the way up to spanning the entire page.
* <p>
* Pretty much other content can be contained within a column, though most commonly it will be {@link FieldSet fieldset}s
* (a group of properties) or {@link CollectionLayoutData collection}s. However, columns can also be used to
* contain further {@link BSRow row}s (creating a nested grid of rows/cols/rows/cols) and {@link BSTabGroup tabgroup}s.
* </p>
*
* Pretty much other content can be contained within a column, though most commonly it will be {@link FieldSet fieldset}s
* (a group of properties) or {@link CollectionLayoutData collection}s. However, columns can also be used to
* contain further {@link BSRow row}s (creating a nested grid of rows/cols/rows/cols) and {@link BSTabGroup tabgroup}s.
* <p>
* It is rendered as a (eg) &lt;div class=&quot;col-md-4 ...&quot;&gt;
* </p>
* It is rendered as a (eg) &lt;div class=&quot;col-md-4 ...&quot;&gt;
*
* @since 1.x {@index}
*/
Expand Down Expand Up @@ -79,6 +76,11 @@ public class BSCol extends BSRowContent

private String id;

@Override
public PositioningContext positioningContext() {
return PositioningContext.HAS_NONE;
}

/**
* As per &lt;div id=&quot;...&quot;&gt;...&lt;/div&gt; : must be unique across entire page.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,13 @@
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.causeway.core.metamodel.facets.actions.position;
package org.apache.causeway.core.metamodel.facets.actions.associate;

import org.apache.causeway.applib.annotation.ActionLayout;
import org.apache.causeway.core.metamodel.facetapi.FacetHolder;
import org.apache.causeway.core.metamodel.facetapi.Facet;

public class ActionPositionFacetFallback extends ActionPositionFacetAbstract {
public interface ActionAssociateWithFacet extends Facet {

public ActionPositionFacetFallback(final FacetHolder holder) {
super(ActionLayout.Position.BELOW, holder, Precedence.FALLBACK);
}
/** non-empty */
String getAssociateWith();

}
Original file line number Diff line number Diff line change
@@ -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.causeway.core.metamodel.facets.actions.associate;

import java.util.function.BiConsumer;

import org.apache.causeway.core.metamodel.facetapi.FacetAbstract;
import org.apache.causeway.core.metamodel.facetapi.FacetHolder;

import lombok.Getter;

public abstract class ActionAssociateWithFacetAbstract
extends FacetAbstract
implements ActionAssociateWithFacet {

public static final Class<ActionAssociateWithFacet> type() {
return ActionAssociateWithFacet.class;
}

@Getter(onMethod_={@Override})
private final String associateWith;

protected ActionAssociateWithFacetAbstract(
final String associateWith,
final FacetHolder holder) {
this(associateWith, holder, Precedence.DEFAULT);
}

protected ActionAssociateWithFacetAbstract(
final String associateWith,
final FacetHolder holder,
final Precedence precedence) {
super(type(), holder, precedence);
this.associateWith = associateWith;
}

@Override
public void visitAttributes(final BiConsumer<String, Object> visitor) {
super.visitAttributes(visitor);
visitor.accept("associateWith", getAssociateWith());
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* 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.causeway.core.metamodel.facets.actions.layout;

import java.util.Optional;

import org.apache.causeway.applib.annotation.ActionLayout;
import org.apache.causeway.commons.internal.base._Strings;
import org.apache.causeway.core.metamodel.facetapi.FacetHolder;
import org.apache.causeway.core.metamodel.facets.actions.associate.ActionAssociateWithFacet;
import org.apache.causeway.core.metamodel.facets.actions.associate.ActionAssociateWithFacetAbstract;

public class ActionAssociateWithFacetForActionLayoutAnnotation extends ActionAssociateWithFacetAbstract {

public static Optional<ActionAssociateWithFacet> create(
final Optional<ActionLayout> actionLayoutIfAny,
final FacetHolder holder) {

return actionLayoutIfAny
.map(ActionLayout::associateWith)
.filter(_Strings::isNotEmpty)
.map(associateWith -> new ActionAssociateWithFacetForActionLayoutAnnotation(associateWith, holder));
}

private ActionAssociateWithFacetForActionLayoutAnnotation(final String associateWith, final FacetHolder holder) {
super(associateWith, holder);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@
import org.apache.causeway.core.metamodel.context.MetaModelContext;
import org.apache.causeway.core.metamodel.facetapi.FeatureType;
import org.apache.causeway.core.metamodel.facets.FacetFactoryAbstract;
import org.apache.causeway.core.metamodel.facets.actions.position.ActionPositionFacetFallback;
import org.apache.causeway.core.metamodel.facets.actions.redirect.RedirectFacetFallback;
import org.apache.causeway.core.metamodel.facets.members.layout.group.LayoutGroupFacetFromActionLayoutAnnotation;
import org.apache.causeway.core.metamodel.facets.members.layout.order.LayoutOrderFacetFromActionLayoutAnnotation;
Expand Down Expand Up @@ -84,12 +83,13 @@ public void process(final ProcessMethodContext processMethodContext) {
addFacetIfPresent(PromptStyleFacetForActionLayoutAnnotation
.create(actionLayoutIfAny, getConfiguration(), facetHolder));

// position
val actionPositionFacet = ActionPositionFacetForActionLayoutAnnotation
.create(actionLayoutIfAny, facetHolder)
.orElseGet(()->new ActionPositionFacetFallback(facetHolder));
// associateWith
addFacetIfPresent(ActionAssociateWithFacetForActionLayoutAnnotation
.create(actionLayoutIfAny, facetHolder));

addFacet(actionPositionFacet);
// position
addFacetIfPresent(ActionPositionFacetForActionLayoutAnnotation
.create(actionLayoutIfAny, facetHolder));

// redirectPolicy
val redirectFacet = RedirectFacetFromActionLayoutAnnotation
Expand All @@ -101,8 +101,6 @@ public void process(final ProcessMethodContext processMethodContext) {
addFacetIfPresent(
LayoutOrderFacetFromActionLayoutAnnotation
.create(actionLayoutIfAny, facetHolder));

}


}
Loading