private void ProcessEntityField(WidgetContext context, BaseField field, IWidget widget, TField LayoutField)
 {
     if (field.IsComputed)
     {
         WidgetFeatureBuilder.PrepareComputedField(context, widget, field);
     }
 }
        /// <summary>
        /// Finds a synchronous method to execute.
        /// </summary>
        /// <param name="context">The widget context.</param>
        /// <param name="widgetType">The widget type.</param>
        /// <returns>The synchronous method.</returns>
        public static MethodInfo FindSyncMethod(WidgetContext context, TypeInfo widgetType)
        {
            string     httpMethod = ResolveHttpMethod(context);
            string     state      = string.Empty; // Resolve a widget state?
            MethodInfo method     = null;

            for (int i = 0; i < SyncMethodNames.Length; i++)
            {
                string name = string.Format(SyncMethodNames[i], state, httpMethod);
                method = GetMethod(name, widgetType);
                if (method != null)
                {
                    break;
                }
            }

            if (method == null)
            {
                return(null);
            }

            if (method.ReturnType == typeof(void))
            {
                throw new InvalidOperationException($"Sync method '{method.Name}' should return a value.");
            }

            if (method.ReturnType.IsAssignableFrom(typeof(Task)))
            {
                throw new InvalidOperationException($"Sync method '{method.Name}' cannot return a task.");
            }

            return(method);
        }
        public IWidget BuildWidget(BaseField field, TField LayoutField)
        {
            var widgetContext = new WidgetContext(this.FormContext);

            widgetContext.Build(field, LayoutField);

            IWidget widget;

            if (CustomWidgetFactory.HasKey(LayoutField.WidgetType))
            {
                widget = CustomWidgetFactory.Get(LayoutField.WidgetType).Invoke(widgetContext, LayoutField);
            }
            else
            {
                if (field != null && field.IsComputed)
                {
                    widgetContext.WidgetType = FormControlType.Label;
                }

                widget = WidgetFactory.Create(widgetContext);
            }
            widget.OnCompile();

            if (field != null)
            {
                ProcessEntityField(widgetContext, field, widget, LayoutField);
            }

            WidgetFeatureBuilder.Build(widgetContext, widget, field, LayoutField);

            return(widget);
        }
        /// <summary>
        /// Resolves the HTTP method used to discover which action to execute.
        /// </summary>
        /// <param name="context">The widget context.</param>
        /// <returns>The HTTP method.</returns>
        private static string ResolveHttpMethod(WidgetContext context)
        {
            string httpMethod = context.ViewContext?.HttpContext?.Request?.Method;

            if (string.Equals(httpMethod, "get", StringComparison.OrdinalIgnoreCase))
            {
                httpMethod = "Get";
            }
            else
            {
                httpMethod = "Post";
            }

            if (httpMethod == "Post" && !string.IsNullOrEmpty(context.WidgetId))
            {
                // MA - We only want to use Post if we are the active widget.
                // TODO - This needs to come from the value provider.
                var form = context.ViewContext?.HttpContext?.Request?.Form;
                if (!string.Equals(context.WidgetId, form[WidgetConventions.WidgetTarget], StringComparison.CurrentCultureIgnoreCase))
                {
                    httpMethod = "Get";
                }
            }

            return(httpMethod);
        }
        /// <summary>
        /// Finds an asynchronous method to execute.
        /// </summary>
        /// <param name="context">The widget context.</param>
        /// <param name="widgetType">The widget type.</param>
        /// <returns>The asynchronous method.</returns>
        public static MethodInfo FindAsyncMethod(WidgetContext context, TypeInfo widgetType)
        {
            string     httpMethod = ResolveHttpMethod(context);
            string     state      = string.Empty; // Resolve a widget state?
            MethodInfo method     = null;

            for (int i = 0; i < AsyncMethodNames.Length; i++)
            {
                string name = string.Format(AsyncMethodNames[i], state, httpMethod);
                method = GetMethod(name, widgetType);
                if (method != null)
                {
                    break;
                }
            }

            if (method == null)
            {
                return(null);
            }

            if (!method.ReturnType.GetTypeInfo().IsGenericType ||
                method.ReturnType.GetGenericTypeDefinition() != typeof(Task <>))
            {
                throw new InvalidOperationException($"Async method '{method.Name}' must return a task.");
            }

            return(method);
        }
        private void CreateWidgets(FormContext formContext, BaseField fieldInfo, FilterExpField filterField = null)
        {
            formContext.AddEntityModelInfo("FieldName", fieldInfo.Name);

            formContext.AddControl(AddFieldName(formContext, fieldInfo));

            var widgetContext = new WidgetContext(formContext);

            widgetContext.Build(fieldInfo, new TField()
            {
                FieldId = "Field"
            });
            widgetContext.IsRequired = false;
            widgetContext.Validation = null;

            var widget = WidgetFactory.Create(widgetContext);

            widget.OnCompile();
            if (filterField != null)
            {
                widget.SetValue(filterField.Value);
            }
            formContext.AddControl(widget);

            AddOperationField(formContext, fieldInfo, filterField);
        }
示例#7
0
 public static void AddArticle(WidgetContext<SeccionData> context, int idArticulo)
 {
     if (context.Data == null) context.Data = new SeccionData();
     if (context.Data.Articulos == null) context.Data.Articulos = new List<int>();
     context.Data.Articulos.Insert(0, idArticulo);
     SeccionBLL.UpdateProperties(context);
 }
        /// <inheritdoc />
        public async Task ExecuteAsync(WidgetContext context)
        {
            var  viewEngine            = ViewEngine ?? ResolveViewEngine(context);
            var  viewData              = ViewData ?? context.ViewData;
            bool isNullOrEmptyViewName = string.IsNullOrEmpty(ViewName);

            string state = null; // TODO: Resolve from value provider?

            string qualifiedViewName;

            if (!isNullOrEmptyViewName && (ViewName[0] == '~' || ViewName[0] == '/'))
            {
                qualifiedViewName = ViewName;
            }
            else
            {
                qualifiedViewName = string.Format(ViewPath, context.WidgetDescriptor.ShortName, isNullOrEmptyViewName ? (state ?? DefaultViewName) : ViewName);
            }

            var view             = FindView(context.ViewContext, viewEngine, qualifiedViewName);
            var childViewContext = new ViewContext(
                context.ViewContext,
                view,
                viewData,
                context.Writer);

            using (view as IDisposable)
            {
                await view.RenderAsync(childViewContext);
            }
        }
        public void Put_Existing_Widget_NotFound()
        {
            var options = new DbContextOptionsBuilder <WidgetContext>()
                          .UseInMemoryDatabase(Guid.NewGuid().ToString())
                          .Options;

            using (var context = new WidgetContext(options))
            {
                context.Widgets.Add(new Widget {
                    Id = id1, Name = GetRandomString(), Shape = GetRandomString()
                });
                context.Widgets.Add(new Widget {
                    Id = id2, Name = GetRandomString(), Shape = GetRandomString()
                });
                context.Widgets.Add(new Widget {
                    Id = id3, Name = GetRandomString(), Shape = GetRandomString()
                });
                context.SaveChanges();

                var widgetDTO = new WidgetDTO {
                    Id = Guid.NewGuid(), Name = GetRandomString(), NumberOfGears = 42
                };

                var controller   = new WidgetController(context);
                var actionResult = controller.Put(widgetDTO).Result;
                var result       = actionResult as NotFoundResult;

                Assert.IsNotNull(result);
                Assert.AreEqual(404, result.StatusCode);
            }
        }
示例#10
0
        internal void OnInit(Connection connection, WidgetContext context, Widget widget)
        {
            ID = widget.ID;

            Connection = connection;
            Context    = context;

            object objConfig = widget.Config.ToObject(ConfigType) !;

            widget.Config = StdJson.ObjectToJObject(objConfig);
            SetConfig(objConfig);

            Type   type   = GetType();
            string prefix = RequestMethodNamePrefix;
            int    N      = prefix.Length;

            MethodInfo[] methods =
                type.GetMethods(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance)
                .Where(m => m.Name.StartsWith(prefix))
                .ToArray();

            foreach (MethodInfo m in methods)
            {
                ParameterInfo[] parameters = m.GetParameters();

                UIReqDelegate theDelegate = (object?[] args) => {
                    return((Task <ReqResult>)m.Invoke(this, args) !);
                };

                UiReqPara[] uiReqParameters = parameters.Select(MakeParameter).ToArray();

                string key = m.Name.Substring(N);
                mapUiReqMethods[key] = new UiReqMethod(theDelegate, uiReqParameters);
            }
        }
示例#11
0
        public IActionResult EntityList()
        {
            this.RequestQuery.EntityId = EntityCode.EntityMaster;
            var context = new DeskPageContext(this.WebAppContext, EntityCode.EntityMaster, this.RequestQuery);

            context.Build();

            var widgetContext = WidgetContext.BuildContext(context, "LayoutList");

            widgetContext.WidgetType = FormControlType.EntityListView;

            var widget = new ViewModel.FormWidget.EntityListWidget(widgetContext);

            widget.OnCompile();
            widget.SetValue(null);
            context.AddControl(widget);

            var page = new ViewPage(context);

            page.Actions = new InvariantDictionary <Model.Form.ActionInfo>();
            var qs = new RequestQueryString()
            {
                EntityId = EntityCode.EntityMaster
            };

            page.Actions.Add("BTN_NEW", new Model.Form.ActionInfo(AppLinkProvider.NEW_ENTITY_URL, qs)
            {
                Title = "New Entity", LinkTarget = "POPUP"
            });

            return(CreatePageResult(page));
        }
        public void Get_One_Widget_Found()
        {
            var options = new DbContextOptionsBuilder <WidgetContext>()
                          .UseInMemoryDatabase(Guid.NewGuid().ToString())
                          .Options;

            using (var context = new WidgetContext(options))
            {
                context.Widgets.Add(new Widget {
                    Id = id1, Name = GetRandomString(), Shape = GetRandomString()
                });
                context.Widgets.Add(new Widget {
                    Id = id2, Name = GetRandomString(), Shape = GetRandomString()
                });
                context.Widgets.Add(new Widget {
                    Id = id3, Name = GetRandomString(), Shape = GetRandomString()
                });
                context.SaveChanges();

                var controller   = new WidgetController(context);
                var actionResult = controller.Get(id2).Result;
                var result       = actionResult as OkObjectResult;
                var widget       = result.Value as WidgetDTO;

                Assert.IsNotNull(result);
                Assert.AreEqual(200, result.StatusCode);
                Assert.IsNotNull(widget);
                Assert.AreEqual(id2, widget.Id);
            }
        }
示例#13
0
        public static List <SelectOption> GetCollectionData(WidgetContext context, List <int> values = null)
        {
            if (context.ControlDefinition != null && context.ControlDefinition.CollectionId > 0)
            {
                var collInfo = context.ControlDefinition.CollectionInfo;

                if (collInfo.SourceType == DataSourceType.Enum)
                {
                    return(CollectionService.GetCollectionDataEnum(collInfo, values));
                }

                var data = CollectionService.GetCollectionData(context.ControlDefinition.CollectionId, values);
                var list = new List <SelectOption>();
                foreach (var o in data)
                {
                    if (o != null)
                    {
                        var d = new SelectOption();
                        d.Add("Value", o.Get("Value", 0));
                        d.Add("Text", o.Get("Text", ""));
                        list.Add(d);
                    }
                }

                return(list);
            }

            return(null);
        }
示例#14
0
        public WidgetController(WidgetContext context)
        {
            _context = context ??
                       throw new ArgumentNullException(nameof(context));

            _context.ChangeTracker.QueryTrackingBehavior =
                QueryTrackingBehavior.NoTracking;
        }
示例#15
0
 public static void RemoveArticle(WidgetContext<SeccionData> context, int idArticulo)
 {
     if (context.Data != null && context.Data != null && context.Data.Articulos != null && context.Data.Articulos.Count > 0)
     {
         context.Data.Articulos.Remove(idArticulo);
     }
     SeccionBLL.UpdateProperties(context);
 }
示例#16
0
        public static BaseWidget Create(WidgetContext cntxt)
        {
            if (!_widgets.Keys.Contains((int)cntxt.WidgetType))
            {
                return(null);
            }

            return(_widgets[(int)cntxt.WidgetType].Invoke(cntxt));
        }
示例#17
0
        private IWidget AddFieldName(FormContext formContext, BaseField fieldInfo)
        {
            var widgetContext = WidgetContext.BuildContext(formContext, "Name");
            var label         = new LabelWidget(widgetContext);

            label.SetValue(fieldInfo.Text);

            return(label);
        }
        public object GetBurndownChartData([FromBody] IncomingBurndownChartSetting request)
        {
            var result = default(object);

            using (var context = new WidgetContext(Context, Configuration))
            {
                result = context.GetBurndownChartData(request);
            }
            return(result);
        }
示例#19
0
    public bool IsWidgetActive(string name)
    {
        WidgetContext widget = context.GetWidget(name);

        if (widget != null)
        {
            return(widget.active);
        }
        return(false);
    }
示例#20
0
    public override void CopyFrom(WindowContextBase context)
    {
        base.CopyFrom(context);
        WidgetContext widget = context as WidgetContext;

        if (widget != null)
        {
            defaultParam.CopyFrom(widget.defaultParam);
        }
    }
示例#21
0
        public void XOnDeleteCascade()
        {
            using (WidgetContext ctx = new WidgetContext(st.ConnectionString))
            {
                var context = ((IObjectContextAdapter)ctx).ObjectContext;
                var sql     = context.CreateDatabaseScript();
                st.CheckSqlContains(sql,
                                    @"ALTER TABLE `WidgetDetails` ADD CONSTRAINT WidgetDetail_Widget
	          FOREIGN KEY (Id)	REFERENCES `Widgets` (Id) ON DELETE Cascade ON UPDATE NO ACTION;"        );
            }
        }
示例#22
0
 static IWidget WidgetsHelper_GetWidget(WidgetContext ctx)
 {
     if (ctx.Entity is Entity)
     {
         return new HelpButton {
                    Prefix = ctx.Prefix, RootType = ctx.TypeContext.PropertyRoute.RootType
         }
     }
     ;
     return(null);
 }
示例#23
0
        private void AddField(EditFormContext formContext)
        {
            var widgetContext = WidgetContext.BuildContext(formContext, "NameX");

            widgetContext.WidgetType = FormControlType.TextBox;

            var widget = ViewModel.FormWidget.WidgetFactory.Create(widgetContext);

            widget.OnCompile();

            AddFieldsInRow(new ViewModel.FormWidget.IWidget[] { widget });
        }
示例#24
0
        private BaseWidget BuildWidget(FormContext formContext, BaseField field, TField tField)
        {
            var widgetContext = new WidgetContext(formContext);

            widgetContext.Build(field, tField);

            var widget = WidgetFactory.Create(widgetContext);

            widget.OnCompile();

            return(widget);
        }
示例#25
0
 protected override void OnLoad(EventArgs e)
 {
     base.OnLoad(e);
      widgetContext = new WidgetContext<SlideShowData>();
      widgetContext.Widget = this.Keys;
      if (!string.IsNullOrEmpty(this.DataXML))
      {
          SlideShowData data = GenericSerializer<SlideShowData>.Deserialize(this.DataXML);
          widgetContext.Data = data;
      }
      CreateControls();
 }
示例#26
0
        private void AddListListField(DetailFormContext formContext)
        {
            var widgetContext = WidgetContext.BuildContext(formContext, "EntityListList");

            widgetContext.WidgetType = FormControlType.EntityListView;

            var widget = new EntityListWidget(widgetContext, "entitylists");

            widget.OnCompile();
            widget.SetValue(null);

            AddFieldsInRow(new ViewModel.FormWidget.IWidget[] { widget });
        }
示例#27
0
        static IWidget WidgetsHelper_GetWidget(WidgetContext ctx)
        {
            Entity ie = ctx.Entity as Entity;
            if (ie == null || ie.IsNew)
                return null;

            if (!Types.Contains(ie.GetType()))
                return null;

            if (!Finder.IsFindable(typeof(NoteEntity)))
                return null;

            return NoteWidgetHelper.CreateWidget(ctx);
        }
        public IWidget Build(WidgetContext context, TField layoutField)
        {
            if (context.FieldSchema != null && context.FieldSchema is OneToManyField)
            {
                var field = (OneToManyField)context.FieldSchema;

                var widget = new ListFormWidget(context);
                widget.FormPage     = BuildRefForm(context.FormContext.Context, field.RefObject);
                widget.RelatedField = field.Name;

                return(widget);
            }
            return(null);
        }
        public static Widget CreateWidget(WidgetContext ctx)
        {
            var ident = (Entity)ctx.Entity;

            var findOptions = new FindOptions
            {
                QueryName = typeof(NoteEntity),
                Create = false,
                SearchOnLoad = true,
                ShowFilters = false,
                ShowFilterButton = false,
                FilterOptions = { new FilterOption("Target", ident.ToLite()) },
                ColumnOptions = { new ColumnOption("Target") },
                ColumnOptionsMode = ColumnOptionsMode.Remove,
            }.ToJS(ctx.Prefix, "New");


            var url = RouteHelper.New().Action((NoteController ac) => ac.NotesCount());

            List<IMenuItem> items = new List<IMenuItem>()
            {
                new MenuItem(ctx.Prefix, "sfNoteView")
                {
                     CssClass = "sf-note-view",
                     OnClick = NoteClient.Module["explore"](ctx.Prefix, findOptions, url),
                     Text = NoteMessage.ViewNotes.NiceToString(),
                },

                new MenuItem(ctx.Prefix, "sfNoteCreate")
                {
                    CssClass = "sf-note-create",
                    OnClick = NoteClient.Module["createNote"](JsFunction.Event, ctx.Prefix, NoteOperation.CreateNoteFromEntity.Symbol.Key, url),
                    Text = NoteMessage.CreateNote.NiceToString()
                },
            }; 

            int count = CountNotes(ident.ToLite());

            return new Widget
            {
                Id = TypeContextUtilities.Compose(ctx.Prefix, "notesWidget"),
                Title = NoteMessage.Notes.NiceToString(),
                IconClass = "glyphicon glyphicon-comment",
                Active = count > 0,
                Class = "sf-notes-toggler",
                Html = new HtmlTag("span").Class("sf-widget-count").SetInnerText(count.ToString()),
                Items = items
            };
        }
示例#30
0
    public void SetWidgetActive(WindowContext context, WidgetContext widget, bool active)
    {
        widget.parent = context;

        var go = GetObject(widget);

        if (go != null)
        {
            SetActive(widget, active);
        }
        else
        {
            Open(widget);
        }
    }
示例#31
0
 public void AddFixedWidget(WidgetContext widget)
 {
     if (fixedWidgets == null)
     {
         fixedWidgets = new Dictionary <string, WidgetContext>();
     }
     if (fixedWidgets.ContainsKey(widget.name) == false)
     {
         fixedWidgets.Add(widget.name, widget);
     }
     else
     {
         fixedWidgets[widget.name] = widget;
     }
 }
示例#32
0
        public static void PrepareComputedField(WidgetContext context, IWidget widget, BaseField field)
        {
            var exp = field.ComputeExpression;

            foreach (var f in exp.KeyWords)
            {
                context.FormContext.AddMissingField(f);
            }

            var feture = new WidgetFeature();

            feture.Depends = exp.KeyWords;
            feture.Add(ViewConstant.Expression, exp);

            AddFeature(widget, feture, "EVAL");
        }
        public void Get_All_Widgets_Not_Found()
        {
            var options = new DbContextOptionsBuilder <WidgetContext>()
                          .UseInMemoryDatabase(Guid.NewGuid().ToString())
                          .Options;

            using (var context = new WidgetContext(options))
            {
                var controller   = new WidgetController(context);
                var actionResult = controller.Get().Result;
                var result       = actionResult as NotFoundObjectResult;

                Assert.IsNotNull(result);
                Assert.AreEqual(404, result.StatusCode);
            }
        }
示例#34
0
    public void SetWidgetActive(string context, string widget, bool active)
    {
        WindowContext windowContext = GetWindowContext(context);

        if (windowContext == null || mWindowContextDic.ContainsKey(windowContext.id) == false)
        {
            return;
        }
        WidgetContext widgetContext = windowContext.GetWidget(widget);

        if (widgetContext == null)
        {
            return;
        }

        SetWidgetActive(windowContext, widgetContext, active);
    }
示例#35
0
        /// <inheritdoc />
        public void Execute(WidgetContext context)
        {
            var serializerSettings = _serializerSettings;

            if (serializerSettings == null)
            {
                serializerSettings = context.ViewContext.HttpContext.RequestServices.GetRequiredService <IOptions <MvcJsonOptions> >().Value.SerializerSettings;
            }

            using (var jsonWriter = new JsonTextWriter(context.Writer))
            {
                jsonWriter.CloseOutput = false;

                var jsonSerializer = JsonSerializer.Create(serializerSettings);
                jsonSerializer.Serialize(jsonWriter, Value);
            }
        }
        public static IWidget CreateWidget(WidgetContext ctx)
        {
            Entity entity = (Entity)ctx.Entity;

            var iso = entity.Isolation();

            if (iso == null)
            {
                if (IsolationLogic.GetStrategy(entity.GetType()) == IsolationStrategy.Isolated)
                    throw new InvalidOperationException("Isolation not set");
            }

            return new IsolationWidget
            {
                Isolation = iso,
                Prefix = ctx.Prefix
            };
        }
示例#37
0
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            widgetContext = new WidgetContext<SeccionData>();
            widgetContext.Widget = this.Keys;
            if (!string.IsNullOrEmpty(this.DataXML))
            {
                SeccionData data = GenericSerializer<SeccionData>.Deserialize(this.DataXML);
                widgetContext.Data = data;
            }

            if (this.EditMode)
            {
                if (this.Page.Request.QueryString["delete"] != null)
                {
                    int idArticulo = Convert.ToInt32(this.Page.Request.QueryString["delete"]);
                    SeccionBLL.RemoveArticle(this.widgetContext, idArticulo);
                }
            }

            CreateControls();
        }
示例#38
0
 public static void UpdateProperties(WidgetContext<SlideShowData> seccion)
 {
     WidgetBLL.InsertOrUpdate<SlideShowData>(seccion.Widget.ID, seccion.Widget.IdContainer, seccion.Widget.Type, seccion.Widget.Position, seccion.Data);
 }
 public SlideShowProperties(WidgetContext<SlideShowData> widgetInfo)
 {
     this.widgetInfo = widgetInfo;
 }
 public AnadirArticuloControl(WidgetContext<SeccionData> context)
 {
     this.widgetContext = context;
 }
 public PropiedadesContenidoLibre(WidgetContext<FreeEditorData> context)
 {
     this.widgetContext = context;
 }
        public static Widget CreateWidget(WidgetContext ctx)
        {
            var ident = (Entity)ctx.Entity;

            var url = RouteHelper.New().Action((AlertController ac) => ac.AlertsCount());

            var alertList = new[]
            {
                new { Count = CountAlerts(ident.ToLite(), "Attended"), Property = "Attended", AlertClass = "sf-alert-attended", Title = AlertMessage.Alerts_Attended.NiceToString() },
                new { Count = CountAlerts(ident.ToLite(), "Alerted"), Property = "Alerted", AlertClass = "sf-alert-alerted", Title = AlertMessage.Alerts_NotAttended.NiceToString() },
                new { Count = CountAlerts(ident.ToLite(), "Future"), Property = "Future", AlertClass = "sf-alert-future", Title = AlertMessage.Alerts_Future.NiceToString() },
            };

            var items = alertList.Select(a => new MenuItem(ctx.Prefix, "sfAlertExplore_" + a.Property)
            {
                OnClick = AlertClient.Module["exploreAlerts"](ctx.Prefix, GetFindOptions(ident, a.Property).ToJS(ctx.Prefix, "alerts"), url),
                CssClass = "sf-alert-view",
                Html = 
                new HtmlTag("span").Class("sf-alert-count-label").Class(a.AlertClass).Class(a.Count > 0 ? "sf-alert-active" : null).InnerHtml((a.Title + ": ").EncodeHtml()).ToHtml().Concat(
                new HtmlTag("span").Class(a.AlertClass).Class(a.Count > 0 ? "sf-alert-active" : null).SetInnerText(a.Count.ToString()))
            }).Cast<IMenuItem>().ToList();

            items.Add(new MenuItemSeparator());

            items.Add(new MenuItem(ctx.Prefix, "sfAlertCreate")
            {
                CssClass = "sf-alert-create",
                OnClick = AlertClient.Module["createAlert"](JsFunction.Event, ctx.Prefix, AlertOperation.CreateAlertFromEntity.Symbol.Key, url),
                Text = AlertMessage.CreateAlert.NiceToString(),
            }); 

            HtmlStringBuilder label = new HtmlStringBuilder();
            int count = alertList.Length;
            for(int i = 0; i < count; i++)
            {
                var a = alertList[i];
                    
                label.Add(new HtmlTag("span")
                    .Class("sf-widget-count")
                    .Class(a.AlertClass)
                    .Class(a.Count > 0 ? "sf-alert-active" : null)
                    .SetInnerText(a.Count.ToString())
                    .Attr("title", a.Title)
                    .ToHtml());

                if (i < count - 1)
                {
                    label.Add(new HtmlTag("span")
                        .Class("sf-alerts-count-separator")
                        .SetInnerText(" - ")
                        .ToHtml());
                }
            }

            return new Widget
            {
                Title = AlertMessage.Alerts.NiceToString(),
                IconClass = "glyphicon glyphicon-bell",
                Class = "sf-alerts-toggler",
                Id = TypeContextUtilities.Compose(ctx.Prefix, "alertsWidget"),
                Active = alertList.Any(a => a.Count > 0),
                Html = label.ToHtml(),
                Items = items,
            };
        }
 public PropiedadesArticuloControl(WidgetContext<SeccionData> widgetInfo)
 {
     this.widgetInfo = widgetInfo;
 }