From 55def717ccf8414e11396faa6b47b12747c56f01 Mon Sep 17 00:00:00 2001 From: Olmo del Corral Cano Date: Mon, 1 Nov 2021 22:25:31 +0100 Subject: [PATCH] add InteractionGroup --- .../Dashboard/PanelPart.cs | 19 ++++++++++++++++--- .../Basics/Templates/ColorTypeahead.tsx | 6 ++++-- .../Basics/Templates/IconTypeahead.tsx | 4 +++- .../Dashboard/Admin/Dashboard.tsx | 16 ++++++++++++++-- .../Dashboard/Dashboard.css | 8 ++++++++ .../Dashboard/Signum.Entities.Dashboard.ts | 12 ++++++++++++ .../View/DashboardFilterController.tsx | 6 +++++- .../Dashboard/View/UserChartPart.tsx | 2 +- Signum.React/Scripts/Lines/Lines.css | 3 +++ Signum.React/Scripts/Lines/ValueLine.tsx | 4 ++-- 10 files changed, 68 insertions(+), 12 deletions(-) diff --git a/Signum.Entities.Extensions/Dashboard/PanelPart.cs b/Signum.Entities.Extensions/Dashboard/PanelPart.cs index d50a61f81b..02a2bab717 100644 --- a/Signum.Entities.Extensions/Dashboard/PanelPart.cs +++ b/Signum.Entities.Extensions/Dashboard/PanelPart.cs @@ -34,6 +34,8 @@ public class PanelPartEmbedded : EmbeddedEntity, IGridEntity [NumberBetweenValidator(1, 12)] public int Columns { get; set; } + public InteractionGroup? InteractionGroup { get; set; } + public BootstrapStyle Style { get; set; } [ImplementedBy( @@ -91,6 +93,7 @@ internal XElement ToXml(IToXmlContext ctx) Title == null ? null! : new XAttribute("Title", Title), IconName == null ? null! : new XAttribute("IconName", IconName), IconColor == null ? null! : new XAttribute("IconColor", IconColor), + InteractionGroup == null ? null! : new XAttribute("InteractionGroup", InteractionGroup), new XAttribute("Style", Style), Content.ToXml(ctx)); } @@ -103,7 +106,8 @@ internal void FromXml(XElement x, IFromXmlContext ctx) Title = x.Attribute("Title")?.Value; IconName = x.Attribute("IconName")?.Value; IconColor = x.Attribute("IconColor")?.Value; - Style = (BootstrapStyle)(x.Attribute("Style")?.Let(a => Enum.Parse(typeof(BootstrapStyle), a.Value)) ?? BootstrapStyle.Light); + Style = x.Attribute("Style")?.Value.TryToEnum() ?? BootstrapStyle.Light; + InteractionGroup = x.Attribute("InteractionGroup")?.Value.ToEnum(); Content = ctx.GetPart(Content, x.Elements().Single()); } @@ -113,8 +117,6 @@ internal Interval ColumnInterval() } } - - public interface IGridEntity { int Row { get; set; } @@ -185,6 +187,17 @@ public void FromXml(XElement element, IFromXmlContext ctx) } } + public enum InteractionGroup + { + Group1, + Group2, + Group3, + Group4, + Group5, + Group6, + Group7, + Group8, + } public enum UserQueryPartRenderMode { SearchControl, diff --git a/Signum.React.Extensions/Basics/Templates/ColorTypeahead.tsx b/Signum.React.Extensions/Basics/Templates/ColorTypeahead.tsx index 913943a8c0..ba5a9d53bf 100644 --- a/Signum.React.Extensions/Basics/Templates/ColorTypeahead.tsx +++ b/Signum.React.Extensions/Basics/Templates/ColorTypeahead.tsx @@ -28,7 +28,8 @@ export function ColorTypeaheadLine(p : { ctx: TypeContext + onChange={handleOnChange} + placeholder={p.ctx.placeholderLabels ? p.ctx.niceName() : undefined} /> ); } @@ -37,6 +38,7 @@ interface ColorTypeaheadProps { color: string | null | undefined; onChange: (newColor: string | null | undefined) => void; formControlClass: string | undefined; + placeholder?: string; } export function ColorTypeahead(p : ColorTypeaheadProps){ @@ -79,7 +81,7 @@ export function ColorTypeahead(p : ColorTypeaheadProps){ return ( @@ -42,6 +43,7 @@ export interface IconTypeaheadProps { onChange: (newIcon: string | null | undefined) => void; extraIcons?: string[]; formControlClass: string | undefined; + placeholder?: string; } export function IconTypeahead(p: IconTypeaheadProps) { @@ -90,7 +92,7 @@ export function IconTypeahead(p: IconTypeaheadProps) { return ( }){ const forceUpdate = useForceUpdate(); @@ -45,6 +46,7 @@ export default function Dashboard(p : { ctx: TypeContext }){ }); } + var colors = ["#DFFF00", "#FFBF00", "#FF7F50", "#DE3163", "#9FE2BF", "#40E0D0", "#6495ED", "#CCCCFF"] function renderPart(tc: TypeContext) { const tcs = tc.subCtx({ formGroupStyle: "SrOnly", formSize: "ExtraSmall", placeholderLabels: true }); @@ -56,7 +58,17 @@ export default function Dashboard(p : { ctx: TypeContext }){
{icon &&
}
- pp.title)} labelText={getToString(tcs.value.content) ?? tcs.niceName(pp => pp.title)} /> + +
+
+ pp.title)} labelText={getToString(tcs.value.content) ?? tcs.niceName(pp => pp.title)} /> +
+
+ pp.interactionGroup)} + optionItems={colors.map((c, i) => ({ label: "Group " + (i + 1), value: "Group" + (i + 1), color: c }))} onRenderDropDownListItem={(io) => {io.label}} /> +
+
+
pp.style)} onChange={() => forceUpdate()} /> diff --git a/Signum.React.Extensions/Dashboard/Dashboard.css b/Signum.React.Extensions/Dashboard/Dashboard.css index 8657ecab91..6515d3d4df 100644 --- a/Signum.React.Extensions/Dashboard/Dashboard.css +++ b/Signum.React.Extensions/Dashboard/Dashboard.css @@ -99,3 +99,11 @@ div.row-control-panel { font-size: 1rem; margin-left: 2px; } + +.sf-dot { + height: 15px; + width: 15px; + border-radius: 50%; + display: inline-block; + margin-right: 5px; +} diff --git a/Signum.React.Extensions/Dashboard/Signum.Entities.Dashboard.ts b/Signum.React.Extensions/Dashboard/Signum.Entities.Dashboard.ts index c436919243..d6b413b08c 100644 --- a/Signum.React.Extensions/Dashboard/Signum.Entities.Dashboard.ts +++ b/Signum.React.Extensions/Dashboard/Signum.Entities.Dashboard.ts @@ -65,6 +65,17 @@ export module DashboardPermission { export const ViewDashboard : Authorization.PermissionSymbol = registerSymbol("Permission", "DashboardPermission.ViewDashboard"); } +export const InteractionGroup = new EnumType("InteractionGroup"); +export type InteractionGroup = + "Group1" | + "Group2" | + "Group3" | + "Group4" | + "Group5" | + "Group6" | + "Group7" | + "Group8"; + export interface IPartEntity extends Entities.Entity { requiresTitle: boolean; } @@ -92,6 +103,7 @@ export interface PanelPartEmbedded extends Entities.EmbeddedEntity { row: number; startColumn: number; columns: number; + interactionGroup: InteractionGroup | null; style: Signum.BootstrapStyle; content: IPartEntity; } diff --git a/Signum.React.Extensions/Dashboard/View/DashboardFilterController.tsx b/Signum.React.Extensions/Dashboard/View/DashboardFilterController.tsx index dabe5e7b0b..c9ca81585e 100644 --- a/Signum.React.Extensions/Dashboard/View/DashboardFilterController.tsx +++ b/Signum.React.Extensions/Dashboard/View/DashboardFilterController.tsx @@ -35,7 +35,11 @@ export class DashboardFilterController { } getFilterOptions(partEmbedded: PanelPartEmbedded, queryKey: string): FilterOptionParsed[] { - var otherFilters = Array.from(this.filters.values()).filter(f => f.partEmbedded != partEmbedded && f.rows?.length); + + if (partEmbedded.interactionGroup == null) + return []; + + var otherFilters = Array.from(this.filters.values()).filter(f => f.partEmbedded != partEmbedded && f.partEmbedded.interactionGroup == partEmbedded.interactionGroup && f.rows?.length); var result = otherFilters.filter(a => a.queryKey == queryKey).map( df => groupFilter("Or", df.rows.map( diff --git a/Signum.React.Extensions/Dashboard/View/UserChartPart.tsx b/Signum.React.Extensions/Dashboard/View/UserChartPart.tsx index 0aa27c0a4a..f3a0a4a4a8 100644 --- a/Signum.React.Extensions/Dashboard/View/UserChartPart.tsx +++ b/Signum.React.Extensions/Dashboard/View/UserChartPart.tsx @@ -119,7 +119,7 @@ export default function UserChartPart(p: PanelPartContentProps { e.stopPropagation(); - if (e.altKey) + if (e.altKey || p.partEmbedded.interactionGroup == null) handleDrillDown(row, e, chartRequest, handleReload); else { const dashboardFilter = p.filterController.filters.get(p.partEmbedded); diff --git a/Signum.React/Scripts/Lines/Lines.css b/Signum.React/Scripts/Lines/Lines.css index cdbc972534..17dd506d1a 100644 --- a/Signum.React/Scripts/Lines/Lines.css +++ b/Signum.React/Scripts/Lines/Lines.css @@ -326,10 +326,12 @@ input[type=checkbox].form-control-xs { margin-bottom: 0px; } +.form-control-xs .rw-widget-input, .rw-widget-xs .rw-widget-input { min-height: 24px; } +.form-control-xs .rw-dropdown-list-input, .rw-widget-xs .rw-dropdown-list-input, .rw-widget-xs .rw-combobox-input { padding: 0 0.4em; @@ -339,6 +341,7 @@ input[type=checkbox].form-control-xs { padding: 0px; } +.form-control-xs .rw-widget-picker, .rw-widget-xs .rw-widget-picker { min-height: 24px; } diff --git a/Signum.React/Scripts/Lines/ValueLine.tsx b/Signum.React/Scripts/Lines/ValueLine.tsx index 5a8bf5f573..662249d4f3 100644 --- a/Signum.React/Scripts/Lines/ValueLine.tsx +++ b/Signum.React/Scripts/Lines/ValueLine.tsx @@ -314,7 +314,7 @@ function internalDropDownList(vl: ValueLineController) { } return ( - + {vl.withItemGroup( {vl.withItemGroup( -