Example #1
0
        public SomeChoicesForm()
        {
            _view = new SomeChoicesFormView();

            LocalActionBuilder.Build(_view.First, () => Ended?.Invoke(this, Outcome.FirstChoice));
            LocalActionBuilder.Build(_view.Second, () => Ended?.Invoke(this, Outcome.SecondChoice));
        }
Example #2
0
        public PhotoTakerForm(PhotoTakerFormView view)
        {
            _view = view;
            LocalActionBuilder.Build(_view.TakePhoto, () => _view.InputFile.Click());
            LocalActionBuilder.Build(_view.AcceptPhoto, () => {
                _view.ResetPreviewStyle(true);
                Ended?.Invoke(this, CompletedOrCanceled.Completed);
            });
            LocalActionBuilder.Build(_view.RetryPhoto, () => {
                _view.ClearImage();
                _view.InputFile.Click();
            });

            _view.InputFile.OnChange += _ => {
                var files = _view.InputFile.Files;
                if (files == null || files.Length <= 0)
                {
                    Logger.Debug(GetType(), "got no files");
                    return;
                }
                Logger.Debug(GetType(), "got files {0}", files.Length);

                var fr = new FileReader();
                fr.OnLoad += ev => {
                    _view.SetImageFromDataUrl((string)fr.Result);
                };
                fr.ReadAsDataURL(files[0]);
            };
        }
Example #3
0
        public UploaderDemoForm(IHttpRequester httpRequester)
        {
            _view = new UploaderDemoFormView();
            _view.Attachments.SetImplementation(new ISomeService_OrderAttachment(httpRequester, () => 124, () => true));
            _attachments = LocalValueFieldBuilder.Build(new List <RemoteFileDescr>(), _view.Attachments,
                                                        (newValue, errors) => {
                errors.IfTrueAdd(newValue.Count > 10, "Maximum 10 files allowed");
            });

            //TODO this is experimental feature. It should be added by the above statement (if BeforeChange is supported in IView)
            _view.Attachments.BeforeChange += (newValue, isUser, preventProp) => {
                if (newValue.Count > 10)
                {
                    preventProp(new HashSet <string> {
                        "Maximum 10 files allowed"
                    });
                }
            };

            var mayConfirm = new AggregatedErrorsValue <bool>(
                false, self => !self.Errors.Any(), x => x.Observes(_attachments));

            var confirm = LocalActionBuilder.Build(_view.Confirm, () => Ended?.Invoke(this, Unit.Instance));

            confirm.BindEnableAndInitialize(mayConfirm);
        }
Example #4
0
        public QrScannerForm(
            QrScannerFormView view,
            string title, string label,
            Func <string, Task <T> > getItemByCode,
            int scannerPopupMmFromTop = 15,
            int scannerPopupHeightMm  = 40)
        {
            _view       = view;
            _view.Label = label;

            _view.PadMmFromTop     = scannerPopupMmFromTop;
            _scannerPopupMmFromTop = scannerPopupMmFromTop;

            _view.HeightMm        = scannerPopupHeightMm;
            _scannerPopupHeightMm = scannerPopupHeightMm;

            _title         = title;
            _getItemByCode = getItemByCode;

            LocalActionBuilder.Build(_view.Unpause, async() => {
                _view.Unpause.Widget.Style.Display = Display.None;
                await _errorLbl.DoChange("", false, this, false);
                _hndl?.ResumeScanning();
            });
            LocalActionBuilder.Build(_view.Cancel, () => _hndl?.CancelScanning());
            _errorLbl = LocalValueFieldBuilder.Build(_view.Error);
        }
        public AllFieldsFilledDataEntryForm()
        {
            var view  = new AllFieldsFilledDataEntryFormView();
            var ended = new Observable.Publisher <Unit>();

            Ended = ended;
            View  = view;

            var strEntry = LocalValueFieldBuilder.Build(
                view.StringEntry,
                (x, errors) => errors.IfTrueAdd(
                    string.IsNullOrWhiteSpace(x) || x.Length < 4,
                    "Text must be at least 4 chars long"),
                (x, errors) => errors.IfTrueAdd(
                    string.IsNullOrWhiteSpace(x) || x.Length > 10,
                    "Text must be no longer than 10 chars long")
                );

            var intEntry = LocalValueFieldBuilder.BuildNullableInt(
                view.IntEntry,
                (x, errors) => errors.IfTrueAdd(!x.HasValue || x < 1234, "Number must be bigger than 1234")
                );

            var decEntry = LocalValueFieldBuilder.BuildNullableDecimal(
                view.DecimalEntry,
                DecimalFormat.WithTwoDecPlaces,
                (x, errors) => errors.IfTrueAdd(!x.HasValue || x < 5.6m,
                                                "Number must be bigger than " + I18n.Localize(5.6m, DecimalFormat.WithOneDecPlace))
                );

            //this field is used to show that values on screen are not necessarily values within model.
            //In other words: when validator rejected value from user wrong value and error message stays on screen BUT model keeps its last-accepted-value
            var summaryLine = LocalValueFieldBuilder.Build("", view.SummaryLine);

            void UpdateSummaryLine()
            {
                var decVal = !decEntry.Value.HasValue ? "" : I18n.Localize(decEntry.Value.Value, DecimalFormat.WithOneDecPlace);

                summaryLine.DoProgrammaticChange(
                    $@"Accepted vals: Text={strEntry.Value} Int={intEntry.Value} Decimal={decVal}"
                    );
            }

            strEntry.Changed += (_, __, ___, ____, _____) => UpdateSummaryLine();
            intEntry.Changed += (_, __, ___, ____, _____) => UpdateSummaryLine();
            decEntry.Changed += (_, __, ___, ____, _____) => UpdateSummaryLine();

            UpdateSummaryLine();

            var confirm = LocalActionBuilder.Build(view.ConfirmAction, () => ended.Fire(Unit.Instance));

            confirm.BindEnableAndInitializeAsObserving(x => {
                x.Observes(strEntry);
                x.Observes(intEntry);
                x.Observes(decEntry);
            });
        }
        public DataboundDatagridForm()
        {
            _view = new DataboundDatagridFormView();
            Func <string, BaseUnboundColumnBuilder <SomeDto> > build = x => UnboundDataGridColumnBuilder.For <SomeDto>(x);

            Items = DataGridModel <SomeDto> .CreateAndBindReloadable(
                _view.Items,
                () => Ended?.Invoke(this, Outcome.ReloadData),
                (el, theaderHeight, _) => //most of the time you would use Toolkit.DefaultTableBodyHeightProvider()
                el.GetAvailableHeightForFormElement(0, 2) - theaderHeight - _view.Help.Widget.OffsetHeight,
                new List <IDataGridColumn <SomeDto> > {
                build("#")
                .WithValueLocalized(x => Items.Items.IndexOf(x) + 1)
                .NonTransformable()
                .Build(),
                build("SomeNumber")
                .WithValueLocalized(x => x.SomeNumber)
                .TransformableDefault()
                .Observes(x => nameof(x.SomeNumber))
                .Build(),
                build("SomeText")
                .WithValue(x => x.SomeText)
                .TransformableDefault()
                .Observes(x => nameof(x.SomeText))
                .Build(),
                build("SomeBool")
                .WithValueLocalized(x => x.SomeBool)
                .TransformableDefault()
                .Observes(x => nameof(x.SomeBool))
                .Build(),
                build("SomeTrait")
                .WithValueAsText(x => x.SomeTrait, x => x.ToString())
                .TransformableAsText()
                .Observes(x => nameof(x.SomeTrait))
                .Build(),
            }).model;

            Items.Activated.Changed += (sender, oldValue, newValue, errors, isUserChange) => {
                if (newValue == null)
                {
                    return;
                }
                ChoosenItem = Items.Activated.Value;
                Ended?.Invoke(this, Outcome.EditItemDemanded);
            };

            LocalActionBuilder.Build(_view.Creator, () => Ended?.Invoke(this, Outcome.CreateItemDemanded));

            //button that is activated only if exactly one record is selected in the datagarid
            var activateEditor = LocalActionBuilder.Build(_view.Editor, () => {
                ChoosenItem = Items.Selected[0];
                Ended?.Invoke(this, Outcome.EditItemDemanded);
            });

            activateEditor.BindSelectionIntoEnabled(Items, SelectionNeeded.ExactlyOneSelected);
        }
Example #7
0
        public InformationalMessageForm(InformationalMessageFormView view, string messageOrNull = null, string titleOrNull = null, bool cancellable = true)
        {
            _cancellable = cancellable;
            Title        = titleOrNull ?? I18n.Translate("Confirmation");
            View         = view;

            _message = new LocalValue <string>(messageOrNull ?? I18n.Translate("Without message"));
            view.Message.BindReadOnlyAndInitialize(_message);

            LocalActionBuilder.Build(view.Confirm, () => Ended?.Invoke(this, Unit.Instance));
        }
        public ConfirmMessageForm(ConfirmMessageFormView view, string messageOrNull = null, string titleOrNull = null)
        {
            Title = titleOrNull ?? I18n.Translate("Confirmation");
            View  = view;

            _message = new LocalValue <string>(messageOrNull ?? I18n.Translate("Without message"));
            view.Message.BindReadOnlyAndInitialize(_message);

            LocalActionBuilder.Build(view.Confirm, () => Ended?.Invoke(this, CompletedOrCanceled.Completed));
            LocalActionBuilder.Build(view.Cancel, () => Ended?.Invoke(this, CompletedOrCanceled.Canceled));
        }
Example #9
0
        //comment out above declaration and uncomment next line to make form noncloseable
//        public ExternalEventsHandlers ExternalEventsHandlers => ExternalEventsHandlers.Ignore;

        public SomeForm()
        {
            var inp = LocalValueFieldBuilder.Build(_view.Inp,
                                                   (v, errors) => errors.IfTrueAdd(string.IsNullOrWhiteSpace(v),
                                                                                   "Must contain at least one non whitespace character"));

            var conf = LocalActionBuilder.Build(_view.Confirm,
                                                () => Ended?.Invoke(this, CompletedOrCanceled.Completed));

            conf.BindEnableAndInitializeAsObserving(x => x.Observes(inp));
        }
Example #10
0
        public EnumChoiceForm(
            string title, bool isCancelable, T defaultValue, Func <T, string> getLabel,
            Action <EnumChoiceFormView <T> > postInitialization = null)
        {
            Title         = title;
            _isCancelable = isCancelable;

            _view   = new EnumChoiceFormView <T>(defaultValue, getLabel, postInitialization);
            _chosen = LocalValueFieldBuilder.BuildEnumBasedChoice(defaultValue, _view.Choice);

            LocalActionBuilder.Build(_view.Confirm, () => Ended?.Invoke(this, CompletedOrCanceled.Completed));
        }
        public SingleRadioBasedChoiceForm(
            string title, bool isCancelable, T defaultValue,
            Func <T, string> getLabel, Func <int, T> intToItem, Func <T, int> itemToInt,
            Action <SingleRadioBasedChoiceFormView <T> > postInitialization = null)
        {
            Title         = title;
            _isCancelable = isCancelable;
            _getLabel     = getLabel;
            _itemToInt    = itemToInt;

            _view = new SingleRadioBasedChoiceFormView <T>(
                defaultValue, getLabel, intToItem, itemToInt, postInitialization);
            _chosen = LocalValueFieldBuilder.BuildGeneralChoice(
                defaultValue, intToItem, itemToInt, _view.Choice);

            LocalActionBuilder.Build(_view.Confirm, () => Ended?.Invoke(this, CompletedOrCanceled.Completed));
        }
Example #12
0
        public TextInputForm(
            TextInputFormView view, string label, string titleOrNull = null, string defaultValue = null,
            params Validate <string>[] validators)
        {
            Title = titleOrNull ?? I18n.Translate("Input");
            _view = view;

            _msg = new LocalValue <string>(label ?? "");
            view.Label.BindReadOnlyAndInitialize(_msg);

            _input = LocalValueFieldBuilder.Build(defaultValue, view.Input, validators);

            var isFormValid  = new AggregatedErrorsValue <bool>(false, x => !x.Errors.Any(), x => x.Observes(_input));
            var confirmInput = LocalActionBuilder.Build(view.Confirm, () => Ended?.Invoke(this, CompletedOrCanceled.Completed));

            confirmInput.BindEnableAndInitialize(isFormValid);
        }
Example #13
0
        public IntroduceItemForm()
        {
            _view = new IntroduceItemFormView();

            _someText   = LocalValueFieldBuilder.Build(_view.SomeText, Validator.IsNotEmptyOrWhitespaceOnly);
            _someNumber = LocalValueFieldBuilder.BuildInt(_view.SomeNumber, Validator.MustBePositive);
            _someBool   = LocalValueFieldBuilder.Build(_view.SomeBool);

            _view.SomeTrait.PermittedValues = EnumExtensions.GetEnumValues <SomeTraitType>().Select(x => (SomeTraitType?)x);
            _someTrait = LocalValueFieldBuilder.Build(_view.SomeTrait, Validator.IsNotNull);

            var isFormValid = new AggregatedErrorsValue <bool>(false, self => !self.Errors.Any(), x => {
                x.Observes(_someText);
                x.Observes(_someNumber);
                x.Observes(_someBool);
                x.Observes(_someTrait);
            });

            LocalActionBuilder
            .Build(_view.Create, () => Ended?.Invoke(this, Outcome.Saved))
            .With(x => x.BindEnableAndInitialize(isFormValid));
        }
Example #14
0
        public SseListenerForm(
            Func <ContinentalSubscriptionRequest, IServerSentEventsSubscriber <ContinentalNotification> > listenerBld)
        {
            _listenerBld = listenerBld;
            _unsubscribe = LocalActionBuilder.Build(_view.Unsubscribe, () => SetupListener(null));

            _contToAction.Add(Continent.Africa,
                              LocalActionBuilder.Build(_view.SubscribeAfrica,
                                                       () => SetupListener(Continent.Africa)));

            _contToAction.Add(Continent.Antarctica,
                              LocalActionBuilder.Build(_view.SubscribeAntarctica,
                                                       () => SetupListener(Continent.Antarctica)));

            _contToAction.Add(Continent.Europe,
                              LocalActionBuilder.Build(_view.SubscribeEurope,
                                                       () => SetupListener(Continent.Europe)));

            _contToAction.Add(Continent.NorthAmerica,
                              LocalActionBuilder.Build(_view.SubscribeNorthAmerica,
                                                       () => SetupListener(Continent.NorthAmerica)));

            SetupEnablement();
        }
        //TODO refactor this monster
        private static Tuple <HTMLElement, DataGridColumnControllerResult <InternalT> > Create <InternalT, OperT, ViewT>(
            Func <InternalT, OperT> toOper,
            ITransformationMediator listener,
            FilterDef <OperT>[] availableFilters,
            IEnumerable <AggregatorDef <OperT> > rawAvailableAggregators,
            IEnumerable <GrouperDef <OperT> > rawAvailableGroupers,
            Func <IReadWriteValue <OperT>, IReadWriteValueView <HTMLElement, ViewT> > paramEditor,
            OperT initialFilterValue,
            OperT invalidFilterValue,
            IComparer <OperT> sortingImpl)
        {
            var availableAggregators = rawAvailableAggregators.ToList();
            var availableGroupers    = rawAvailableGroupers.ToList();

            AssureUnique(availableFilters, x => x.Label);
            AssureUnique(availableAggregators, x => x.Label);
            AssureUnique(availableGroupers, x => x.Label);

            LocalValue <AggregatorDef <OperT> > aggregateFunc          = null;
            LocalValue <GrouperDef <OperT> >    groupingFunc           = null;
            LocalValue <GroupOrAggregate?>      groupOrAggregateChoice = null;

            FilterDef <OperT> currentFilterImplOrNull = null;
            var filterLabelToImpl = new Dictionary <string, FilterDef <OperT> >();

            availableFilters.ForEach(x => filterLabelToImpl.Add(x.Label, x));

            AggregatorDef <OperT> currentAggrImplOrNull = null;
            var aggregLabelToImpl = new Dictionary <string, AggregatorDef <OperT> >();

            availableAggregators.ForEach(x => aggregLabelToImpl.Add(x.Label, x));

            GrouperDef <OperT> currentGrouperImplOrNull = null;
            var grouperLabelToImpl = new Dictionary <string, GrouperDef <OperT> >();

            availableGroupers.ForEach(x => grouperLabelToImpl.Add(x.Label, x));

            var filterParam = new LocalValue <OperT>(initialFilterValue, invalidFilterValue);

            HTMLElement controllerElem = new HTMLSpanElement {
                ClassName = Magics.CssClassFilterMainContainer
            };
            var actionContainer = new HTMLSpanElement {
                ClassName = Magics.CssClassFilterActionContainer
            };

            controllerElem.AppendChild(actionContainer);

            var groupOrAggregateChoiceView = new RadioBasedSingleChoice();

            Element GetLabelTh()
            {
                var filterTh = controllerElem.ParentElement;
                var filterTr = filterTh.ParentElement;
                var thead    = filterTr.ParentElement;

                var iCol = filterTr.IndexOfChild(filterTh);

                var labelTr = thead.GetChildAtOrNull(0);
                var labelTh = labelTr.GetChildAtOrNull(iCol);

                return(labelTh);
            }

            void MarkAsGrouped(bool activated)
            {
                Logger.Debug(typeof(DataGridColumnController), "markAsGrouped({0})", activated);
                controllerElem.ParentElement.AddOrRemoveClass(activated, Magics.CssClassActive);
                GetLabelTh().AddOrRemoveClass(activated, Magics.CssClassWithGrouping);
                controllerElem.ParentElement.AddOrRemoveClass(activated, Magics.CssClassWithGrouping);
            }

            void MarkAsAggregated(bool activated)
            {
                Logger.Debug(typeof(DataGridColumnController), "markAsAggregated({0})", activated);
                controllerElem.ParentElement.AddOrRemoveClass(activated, Magics.CssClassActive);
                GetLabelTh().AddOrRemoveClass(activated, Magics.CssClassWithAggregation);
                controllerElem.ParentElement.AddOrRemoveClass(activated, Magics.CssClassWithAggregation);
            }

            void MarkAsFiltered(bool activated)
            {
                Logger.Debug(typeof(DataGridColumnController), "markAsFiltered({0})", activated);
                controllerElem.ParentElement.AddOrRemoveClass(activated, Magics.CssClassActive);
                GetLabelTh().AddOrRemoveClass(activated, Magics.CssClassWithFilter);
                controllerElem.ParentElement.AddOrRemoveClass(activated, Magics.CssClassWithFilter);
            }

            var removeFilter = new HTMLAnchorElement {
                Target = "#",
                Title  = I18n.Translate("Remove filter"),
                Text   = FontAwesomeSolid.IconFilter
            };

            removeFilter.AddClasses(Magics.CssClassFilterRemove, IconFontType.FontAwesomeSolid.ToCssClassName());
            actionContainer.AppendChild(removeFilter);

            var removeFilterActionView = new InputTypeButtonActionView(removeFilter);

            LocalActionBuilder.Build(removeFilterActionView, () => {
                currentFilterImplOrNull = null;
                MarkAsFiltered(false);
                listener.UserFilterChangedHandler(ChangeOrRemove.Removed);
            });

            var removeGrouping = new HTMLAnchorElement {
                Target = "#",
                Title  = I18n.Translate("Remove grouping"),
                Text   = FontAwesomeSolid.IconListUl
            };

            removeGrouping.AddClasses(Magics.CssClassGroupingRemove, IconFontType.FontAwesomeSolid.ToCssClassName());
            actionContainer.AppendChild(removeGrouping);

            var removeGroupingActionView = new InputTypeButtonActionView(removeGrouping);

            LocalActionBuilder.Build(removeGroupingActionView, async() => {
                currentGrouperImplOrNull = null;
                MarkAsGrouped(false);
                await groupOrAggregateChoice.DoChange(null, false, null, false);
                listener.UserGroupingChangedHandler(ChangeOrRemove.Removed);
            });

            var removeAggregation = new HTMLAnchorElement {
                ClassName = Magics.CssClassAggregationRemove,
                Target    = "#",
                Title     = I18n.Translate("Remove aggregation"),
                Text      = "Σ"
            };

            actionContainer.AppendChild(removeAggregation);

            var removeAggregationActionView = new InputTypeButtonActionView(removeAggregation);

            LocalActionBuilder.Build(removeAggregationActionView, async() => {
                currentAggrImplOrNull = null;
                await groupOrAggregateChoice.DoChange(null, false, null, false);
                MarkAsAggregated(false);
                listener.UserAggregationChangedHandler(ChangeOrRemove.Removed);
            });



            Action <string> groupingChangedHandler = async labelOrNull => {
                Logger.Debug(typeof(DataGridColumnController), "Setting grouping programmatically to {0}", labelOrNull);

                if (labelOrNull == null)
                {
                    currentGrouperImplOrNull = null;
                    MarkAsGrouped(false);
                    await groupOrAggregateChoice.DoChange(null, false, null, false);

                    return;
                }

                GrouperDef <OperT> grouper;

                if (!grouperLabelToImpl.TryGetValue(labelOrNull, out grouper))
                {
                    Logger.Debug(typeof(DataGridColumnController), "No such grouping func when looking by label");
                    return;
                }

                await groupingFunc.DoChange(grouper, false, null, false);

                currentGrouperImplOrNull = grouper;
                MarkAsGrouped(true);
            };

            Action <string> aggregationChangedHandler = async labelOrNull => {
                Logger.Debug(typeof(DataGridColumnController), "Setting aggregation programmatically to {0}", labelOrNull);

                if (labelOrNull == null)
                {
                    currentAggrImplOrNull = null;
                    MarkAsAggregated(false);
                    await groupOrAggregateChoice.DoChange(null, false, null, false);

                    listener.UserAggregationChangedHandler(ChangeOrRemove.Removed);
                    return;
                }

                if (!aggregLabelToImpl.TryGetValue(labelOrNull, out var aggr))
                {
                    Logger.Debug(typeof(DataGridColumnController), "No such aggregation func when looking by label");
                    return;
                }

                await aggregateFunc.DoChange(aggr, false, null, false);

                currentAggrImplOrNull = aggr;
                MarkAsAggregated(true);
            };

            listener.InitUserSide(groupingChangedHandler, aggregationChangedHandler);



            var filterOper     = new LocalValue <FilterDef <OperT> >(availableFilters.FirstOrDefault());
            var filterOperView = new DropDownSelectBox("")
            {
                PermittedValues = filterLabelToImpl.Select(x => Tuple.Create(x.Key, x.Key))
            };

            filterOperView.BindReadWriteAndInitialize(filterOper,
                                                      x => x != null ? Tuple.Create(x.Label, x.Label) : Tuple.Create("", ""),
                                                      x => !string.IsNullOrEmpty(x.Item1) ? filterLabelToImpl[x.Item1] : null);

            controllerElem.AppendChild(filterOperView.Widget);

            var val = paramEditor(filterParam);

            controllerElem.AppendChild(val.Widget);

            filterParam.Changed += (_, __, newValue, ___, isUserChange) => {
                if (!isUserChange)
                {
                    return;
                }
                currentFilterImplOrNull = filterOper.Value;
                MarkAsFiltered(true);
                listener.UserFilterChangedHandler(ChangeOrRemove.Changed);
            };

            filterOper.Changed += (_, __, newValue, ___, isUserChange) => {
                if (!isUserChange)
                {
                    return;
                }

                currentFilterImplOrNull = newValue;
                MarkAsFiltered(true);
                listener.UserFilterChangedHandler(ChangeOrRemove.Changed);
            };

            {
                groupOrAggregateChoice = new LocalValue <GroupOrAggregate?>(null);
                groupOrAggregateChoiceView.Widget.ClassList.Add(Magics.CssClassGroupOrAggregate);
                groupOrAggregateChoiceView.PermittedValues =
                    EnumExtensions.GetEnumValues <GroupOrAggregate>().Select(x =>
                                                                             Tuple.Create(((int)x).ToString(), x.GetUserFriendlyName()));

                groupOrAggregateChoiceView.BindReadWriteAndInitialize(groupOrAggregateChoice,
                                                                      x => !x.HasValue ? null : Tuple.Create(((int)x).ToString(), x.Value.GetUserFriendlyName()),
                                                                      x => (x == null || string.IsNullOrEmpty(x.Item1)) ?
                                                                      null
                        :
                                                                      (GroupOrAggregate?)Convert.ToInt32(x.Item1));

                groupingFunc = new LocalValue <GrouperDef <OperT> >(availableGroupers.FirstOrDefault());
                var groupingFuncView = new DropDownSelectBox(I18n.Translate("group by:"));

                groupingFuncView.Widget.ClassList.Add(Magics.CssClassGroupingFunc);
                groupingFuncView.PermittedValues = grouperLabelToImpl.Select(x => Tuple.Create(x.Key, x.Key));
                groupingFuncView.BindReadWriteAndInitialize(groupingFunc,
                                                            x => x != null ? Tuple.Create(x.Label, x.Label) : Tuple.Create("", ""),
                                                            x => !string.IsNullOrEmpty(x.Item1) ? grouperLabelToImpl[x.Item1] : null);

                aggregateFunc = new LocalValue <AggregatorDef <OperT> >(availableAggregators.FirstOrDefault());
                var aggregateFuncView = new DropDownSelectBox(I18n.Translate("aggregate by:"));

                aggregateFuncView.Widget.ClassList.Add(Magics.CssClassAggregateFunc);
                aggregateFuncView.PermittedValues = aggregLabelToImpl.Select(x => Tuple.Create(x.Key, x.Key));
                aggregateFuncView.BindReadWriteAndInitialize(aggregateFunc,
                                                             x => x != null ? Tuple.Create(x.Label, x.Label) : Tuple.Create("", ""),
                                                             x => !string.IsNullOrEmpty(x.Item1) ? aggregLabelToImpl[x.Item1] : null);

                groupingFunc.Changed += (_, __, newValue, errors, isUserChange) => {
                    if (!isUserChange)
                    {
                        return;
                    }
                    currentGrouperImplOrNull = newValue;
                    MarkAsGrouped(newValue != null);
                    listener.UserGroupingChangedHandler(newValue != null ? ChangeOrRemove.Changed : ChangeOrRemove.Removed);
                };

                aggregateFunc.Changed += (_, __, newValue, errors, isUserChange) => {
                    if (!isUserChange)
                    {
                        return;
                    }
                    currentAggrImplOrNull = newValue;
                    MarkAsAggregated(newValue != null);
                    listener.UserAggregationChangedHandler(newValue != null ? ChangeOrRemove.Changed : ChangeOrRemove.Removed);
                };

                groupOrAggregateChoice.Changed += (_, __, newValue, ___, isUserChange) => {
                    Logger.Debug(typeof(DataGridColumnController), "groupOrAggregateChoice changed to {0} by {1}", newValue, isUserChange);

                    //if (!isUserChange) {
                    //    return;
                    //}

                    if (!newValue.HasValue)
                    {
                        return;
                    }

                    switch (newValue.Value)
                    {
                    case GroupOrAggregate.Aggregate:
                        currentAggrImplOrNull = aggregateFunc.Value;
                        MarkAsAggregated(true);
                        listener.UserAggregationChangedHandler(ChangeOrRemove.Changed);
                        break;

                    case GroupOrAggregate.Group:
                        currentGrouperImplOrNull = groupingFunc.Value;
                        MarkAsGrouped(true);
                        listener.UserGroupingChangedHandler(ChangeOrRemove.Changed);
                        break;

                    default: throw new Exception("unsupported GroupOrAggregate");
                    }
                };

                controllerElem.AppendChild(groupOrAggregateChoiceView.Widget);
                controllerElem.AppendChild(groupingFuncView.Widget);
                controllerElem.AppendChild(aggregateFuncView.Widget);
            }

            DocumentUtil.AddMouseClickListener(controllerElem, ev => {
                if (!ev.HasHtmlTarget())
                {
                    return;
                }

                //find out if clicked item is a descendant of th
                if (ev.HtmlTarget().IsDescendantOf(controllerElem.ParentElement))
                {
                    controllerElem.ParentElement.ClassList.Add(Magics.CssClassActive);
                    return;
                }

                controllerElem.ParentElement?.ClassList.Remove(Magics.CssClassActive);
            });

            return(Tuple.Create(controllerElem, new DataGridColumnControllerResult <InternalT> {
                FilterImpl = x =>
                             currentFilterImplOrNull == null || currentFilterImplOrNull.FilterFunc(filterParam.Value, toOper(x)),
                AggregationImpl = x => currentAggrImplOrNull?.AggregatorFunc(x.Select(toOper)),
                GroupingImpl = x => currentGrouperImplOrNull?.GroupingFunc(x.Select(toOper)),
                SortingImpl = new CompareImpl <InternalT>((x, y) => sortingImpl.Compare(toOper(x), toOper(y))),
                IsGroupingActive = () => currentGrouperImplOrNull != null
            }));
        }
Example #16
0
            () => Ended?.Invoke(this, Outcome.EndRequested));//makes form cancelable

        public MainForm()
        {
            LocalActionBuilder.Build(_view.ShowInfo, () => Ended?.Invoke(this, Outcome.InfoRequested));
            LocalActionBuilder.Build(_view.ReplaceMaster, () => Ended?.Invoke(this, Outcome.ReplaceMaster));
        }