コード例 #1
0
            public IView <HTMLElement> Create(RemoteFileDescr forFile, Action forceAddOrRemoveToView)
            {
                var widget = InputTypeButtonActionView.CreateFontAwesomeIconedAction(
                    IconFontType.FontAwesomeSolid, FontAwesomeSolid.IconExchangeAlt);

                widget.Widget.Title = I18n.Translate("Replace");
                widget.Triggered   += () => {
                    //HACK due to lack of: on input[file] activated but user declined to select anything
                    _parent._hackOnUploadStarted =
                        () => {
                        widget.State = ActionViewState.CreateOperationRunning();
                        _activatedFor.Add(forFile);
                    };

                    _parent.OnReplace(widget, forFile, forceAddOrRemoveToView);

                    _parent._hackOnUploadEnded = result => {
                        _activatedFor.Remove(forFile);
                        widget.Widget.TextContent = FontAwesomeSolid.IconExchangeAlt;
                        widget.State = result.Success ?
                                       ActionViewState.CreateIdleOrSuccess()
                            :
                                       ActionViewState.CreateOperationFailed(new Exception(result.ErrorMessage));

                        UpdateEnablement(forFile, widget, false); //make action enabled (needed due to hack above)
                    };
                };
                UpdateEnablement(forFile, widget, false);
                _known.Add(forFile, widget);
                return(widget);
            }
コード例 #2
0
ファイル: SyncView.cs プロジェクト: todo-it/philadelphia
        public SyncView(Action <HTMLElement> stylePopupHolder = null)
        {
            _toggleState = new InputTypeButtonActionView("");
            _showLogs    = new AnchorBasedActionView("");
            _showLogs.Widget.Style.Padding = "5px";
            _logsPopup = new FramelessPopupProvider(_showLogs.Widget)
            {
                PopupRawContent = _logItems
            };

            _container.Style.Display    = Display.Flex;
            _container.Style.AlignItems = AlignItems.Center;
            _container.AppendChild(_toggleState.Widget);
            _container.AppendChild(_logsPopup.Widget);

            _logItems.Style.Padding    = "20px";
            _logItems.Style.MinHeight  = "75px";
            _logItems.Style.MaxHeight  = "75px";
            _logItems.Style.OverflowX  = Overflow.Auto;
            _logItems.Style.OverflowY  = Overflow.Scroll;
            _logItems.Style.WhiteSpace = WhiteSpace.Pre;

            stylePopupHolder?.Invoke(_logsPopup.PopupHolderElement);

            _toggleState.StaysPressed = true;

            _showLogs.Triggered += () => _logsPopup.ShowPopup();
        }
コード例 #3
0
 public RemoteValueChangeByEntryFormView(
     IReadWriteValueView <HTMLElement, ViewT> input, TextType inputType = TextType.TreatAsText)
 {
     Input   = input;
     Message = new LabellessReadOnlyView("div", inputType);
     Confirm = new InputTypeButtonActionView(I18n.Translate("OK"))
               .With(x => x.MarkAsFormsDefaultButton());
 }
コード例 #4
0
        public static IActionView <HTMLElement> DefaultExitButtonBuilder()
        {
            var result = new InputTypeButtonActionView("");

            result.Widget.ClassList.Add(Magics.CssClassDatagridAction);
            var img = new HTMLImageElement {
                Src = Magics.IconUrlExit
            };

            result.Widget.AppendChild(img);
            return(result);
        }
コード例 #5
0
            private void UpdateEnablement(
                RemoteFileDescr forFile, InputTypeButtonActionView widget, bool isOperationStarted)
            {
                var val =
                    _parent.Mutable &&
                    _parent.Enabled &&
                    forFile.FileId != null &&
                    !isOperationStarted;

                widget.Enabled             = val;
                widget.Widget.Style.Cursor = val ? Cursor.Pointer : Cursor.Default;
            }
コード例 #6
0
            private void UpdateEnablement(
                RemoteFileDescr forFile, InputTypeButtonActionView widget, bool isOperationStarted)
            {
                var val =
                    _parent.Mutable &&
                    _parent.Enabled &&
                    forFile.FileId != null &&
                    !isOperationStarted &&
                    !_activatedFor.Contains(forFile);

                Logger.Debug(GetType(), "UpdateEnablement for {0} value {1}", forFile, val);
                widget.Enabled = val;
            }
コード例 #7
0
            public IView <HTMLElement> Create(RemoteFileDescr forFile, Action forceAddOrRemoveToView)
            {
                var widget = InputTypeButtonActionView.CreateFontAwesomeIconedAction(
                    IconFontType.FontAwesomeSolid, FontAwesomeSolid.IconTimes);

                widget.Widget.Title = I18n.Translate("Hide");
                widget.Triggered   += () => _parent.OnRemoveTransient(forFile);

                UpdateVisibility(forFile, widget);

                _known.Add(forFile, widget);

                return(widget);
            }
コード例 #8
0
        public FramelessPopupProvider(InputTypeButtonActionView act) : this(act.Widget)
        {
            act.Triggered     += ShowPopup;
            act.StaysPressed   = true;
            PopupStateChanged += x => {
                switch (x)
                {
                case VisibilityAction.Hiding:
                    act.IsPressed = false;
                    break;

                case VisibilityAction.Showing:
                    act.IsPressed = true;
                    break;
                }
            };
        }
コード例 #9
0
            public IView <HTMLElement> Create(RemoteFileDescr forFile, Action forceAddOrRemoveToView)
            {
                var widget = InputTypeButtonActionView.CreateFontAwesomeIconedAction(
                    IconFontType.FontAwesomeSolid, FontAwesomeSolid.IconTrashAlt);

                widget.Widget.Title = I18n.Translate("Remove");
                widget.Triggered   += async() => {
                    widget.State = ActionViewState.CreateOperationRunning();
                    var result = await _parent.OnRemove(widget, forFile, forceAddOrRemoveToView);

                    widget.Widget.TextContent = FontAwesomeSolid.IconTrashAlt;
                    widget.State = result.Success ?
                                   ActionViewState.CreateIdleOrSuccess()
                        :
                                   ActionViewState.CreateOperationFailed(new Exception(result.ErrorMessage));
                };

                UpdateEnablement(forFile, widget, false);

                _known.Add(forFile, widget);
                return(widget);
            }
コード例 #10
0
        public ActionButtonsMenuBarView(
            Func <MenuItemModel, InputTypeButtonActionView> customButtonBuilder = null)
        {
            _buttonBuilder = customButtonBuilder ?? (x => {
                var res = new InputTypeButtonActionView(x.Label.Value);
                x.Label.Changed += (_, __, newValue, ___, ____) =>
                                   res.ProperLabelElem.TextContent = newValue;

                res.Widget.SetAttribute(Magics.AttrDataMenuItemId, x.Id.ToString());

                if (x.DescriptonOrNull != null)
                {
                    res.Widget.Title = x.DescriptonOrNull;
                }

                return(res);
            });

            _nav    = DocumentUtil.CreateElementHavingClassName("nav", GetType().FullName);
            _nav.Id = UniqueIdGenerator.GenerateAsString();

            _actionsCntnr = new HTMLDivElement();
            _nav.AppendChild(_actionsCntnr);
        }
コード例 #11
0
        //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
            }));
        }
コード例 #12
0
 private void DeactivateAllExceptFor(InputTypeButtonActionView btn)
 {
     _items.ForEach(x => x.IsPressed = false);
     btn.IsPressed = true;
 }
コード例 #13
0
 private void UpdateVisibility(RemoteFileDescr forFile, InputTypeButtonActionView widget)
 {
     widget.Widget.Style.SetProperty("display",
                                     forFile.Status == UploadStatus.Failed && forFile.FileId == null ? "" : "none");
 }
コード例 #14
0
 public ConfirmOperationFormView(TextType inputType = TextType.TreatAsText)
 {
     Message = new LabellessReadOnlyView("div", inputType);
     Confirm = new InputTypeButtonActionView(I18n.Translate("Confirm"))
               .With(x => x.MarkAsFormsDefaultButton());
 }
コード例 #15
0
 public TextInputFormView(TextType inputType = TextType.TreatAsText)
 {
     Label   = new LabellessReadOnlyView("div", inputType);
     Confirm = new InputTypeButtonActionView(I18n.Translate("OK"))
               .With(x => x.MarkAsFormsDefaultButton());
 }