Tuesday, October 15, 2013

StateMachine - Allow hiding and disabling transition actions based on security and current object criteria

I will provide a short discussion on how to extend XAF StateMachine module as per subject.

By design when creating a new State the it is possible to restrict the transition to that State using Criteria. For example in the below image we see that the transition to the Completed state is allowed only to Administrators.

image

When you try to make the transition to the Completed state a handled exception will be raised however our goal is to hide all transitions that criteria do not fit.

So given the above requirement we need to write a controller that will go though all data hosted in the ChangeStateAction expose an event that will provide the state from external sources.

You can explore the controller that describes this requirement at

https://github.com/expand/eXpand/blob/master/Xpand/Xpand.ExpressApp.Modules/StateMachine/Controllers/ChangeStateActionController.cs

The next step is to subscribe to RequestActiveState event of the above ChangeStateActionController and provide the Active state logic. Below is illustrated a possible implementation.

public class CriteriaActionStateController:ViewController<ObjectView> {

    private const string HideIfCriteriaDoNotFit = "HideIfCriteriaDoNotFit";

    ChangeStateActionController _changeStateActionController;

 

    protected override void OnActivated() {

        base.OnActivated();

        _changeStateActionController = Frame.GetController<ChangeStateActionController>();

        _changeStateActionController.RequestActiveState+=ChangeStateActionControllerOnRequestActiveStateAction;

    }

 

    public override void CustomizeTypesInfo(DevExpress.ExpressApp.DC.ITypesInfo typesInfo) {

        base.CustomizeTypesInfo(typesInfo);

        var typeInfo = typesInfo.FindTypeInfo(typeof (XpoState));

        typeInfo.CreateMember(HideIfCriteriaDoNotFit, typeof (bool));

    }

 

    protected override void OnDeactivated() {

        base.OnDeactivated();

        _changeStateActionController.RequestActiveState-=ChangeStateActionControllerOnRequestActiveStateAction;

    }

 

    void ChangeStateActionControllerOnRequestActiveStateAction(object sender, ChoiceActionItemArgs choiceActionItemArgs) {

        var key = typeof(CriteriaActionStateController).Name;

        choiceActionItemArgs.Active[key] = IsActive(choiceActionItemArgs.Transition);

    }

 

    bool IsActive(XpoTransition xpoTransition) {

        var hideIfCriteriaDoNotFit = xpoTransition.TargetState.GetMemberValue(HideIfCriteriaDoNotFit) as bool?;

        if (hideIfCriteriaDoNotFit.HasValue&&hideIfCriteriaDoNotFit.Value) {

            var stateMachineLogic = new StateMachineLogic(ObjectSpace);

            var ruleSetValidationResult = RuleSetValidationResult(xpoTransition, stateMachineLogic);

            return ruleSetValidationResult.State != ValidationState.Invalid;

        }

        return true;

    }

 

    [Obsolete("in 13.2 the ValidateTransition will be public")]

    RuleSetValidationResult RuleSetValidationResult(XpoTransition xpoTransition, StateMachineLogic stateMachineLogic) {

        var methodInfo = stateMachineLogic.GetType().GetMethod("ValidateTransition",BindingFlags.NonPublic | BindingFlags.Instance);

        return (RuleSetValidationResult) methodInfo.Invoke(stateMachineLogic, new[]{xpoTransition.TargetState, View.CurrentObject});

    }

}

In the above controller (also available in eXpandFramework online repo) we also see that override the CustomisedTypesInfo to create a new member that will allow the end user to decide if he wants to hide the transition or use the by design behavior.

image

As always let us know your feedback using eXpand forums or for this functionality only you can post your feedback at this issue at DevExpress Support Center.

P.S. This implementation is available with the StateMachine module of eXpandFramework 13.1.7.10 and is also possible to do the same with permissions (see http://goo.gl/T0ZinL)! Also note that is totally possible to just grab the discussed controllers and add them in your projects without the eXpandFramework.

Subscribe to XAF feed
Subscribe to community feed

DiggIt!

0 comments:

Post a Comment