Skip to content

Commit 55def71

Browse files
committed
add InteractionGroup
1 parent 7622f05 commit 55def71

10 files changed

Lines changed: 68 additions & 12 deletions

File tree

Signum.Entities.Extensions/Dashboard/PanelPart.cs

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ public class PanelPartEmbedded : EmbeddedEntity, IGridEntity
3434
[NumberBetweenValidator(1, 12)]
3535
public int Columns { get; set; }
3636

37+
public InteractionGroup? InteractionGroup { get; set; }
38+
3739
public BootstrapStyle Style { get; set; }
3840

3941
[ImplementedBy(
@@ -91,6 +93,7 @@ internal XElement ToXml(IToXmlContext ctx)
9193
Title == null ? null! : new XAttribute("Title", Title),
9294
IconName == null ? null! : new XAttribute("IconName", IconName),
9395
IconColor == null ? null! : new XAttribute("IconColor", IconColor),
96+
InteractionGroup == null ? null! : new XAttribute("InteractionGroup", InteractionGroup),
9497
new XAttribute("Style", Style),
9598
Content.ToXml(ctx));
9699
}
@@ -103,7 +106,8 @@ internal void FromXml(XElement x, IFromXmlContext ctx)
103106
Title = x.Attribute("Title")?.Value;
104107
IconName = x.Attribute("IconName")?.Value;
105108
IconColor = x.Attribute("IconColor")?.Value;
106-
Style = (BootstrapStyle)(x.Attribute("Style")?.Let(a => Enum.Parse(typeof(BootstrapStyle), a.Value)) ?? BootstrapStyle.Light);
109+
Style = x.Attribute("Style")?.Value.TryToEnum<BootstrapStyle>() ?? BootstrapStyle.Light;
110+
InteractionGroup = x.Attribute("InteractionGroup")?.Value.ToEnum<InteractionGroup>();
107111
Content = ctx.GetPart(Content, x.Elements().Single());
108112
}
109113

@@ -113,8 +117,6 @@ internal Interval<int> ColumnInterval()
113117
}
114118
}
115119

116-
117-
118120
public interface IGridEntity
119121
{
120122
int Row { get; set; }
@@ -185,6 +187,17 @@ public void FromXml(XElement element, IFromXmlContext ctx)
185187
}
186188
}
187189

190+
public enum InteractionGroup
191+
{
192+
Group1,
193+
Group2,
194+
Group3,
195+
Group4,
196+
Group5,
197+
Group6,
198+
Group7,
199+
Group8,
200+
}
188201
public enum UserQueryPartRenderMode
189202
{
190203
SearchControl,

Signum.React.Extensions/Basics/Templates/ColorTypeahead.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ export function ColorTypeaheadLine(p : { ctx: TypeContext<string | null | undefi
2828
<FormGroup ctx={ctx} labelText={ctx.niceName()} >
2929
<ColorTypeahead color={ctx.value}
3030
formControlClass={ctx.formControlClass}
31-
onChange={handleOnChange} />
31+
onChange={handleOnChange}
32+
placeholder={p.ctx.placeholderLabels ? p.ctx.niceName() : undefined} />
3233
</FormGroup>
3334
);
3435
}
@@ -37,6 +38,7 @@ interface ColorTypeaheadProps {
3738
color: string | null | undefined;
3839
onChange: (newColor: string | null | undefined) => void;
3940
formControlClass: string | undefined;
41+
placeholder?: string;
4042
}
4143

4244
export function ColorTypeahead(p : ColorTypeaheadProps){
@@ -79,7 +81,7 @@ export function ColorTypeahead(p : ColorTypeaheadProps){
7981
return (
8082
<Typeahead
8183
value={p.color ?? ""}
82-
inputAttrs={{ className: classes(p.formControlClass, "sf-entity-autocomplete") }}
84+
inputAttrs={{ className: classes(p.formControlClass, "sf-entity-autocomplete"), placeholder: p.placeholder }}
8385
getItems={handleGetItems}
8486
onSelect={handleSelect}
8587
onChange={handleSelect}

Signum.React.Extensions/Basics/Templates/IconTypeahead.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ export function IconTypeaheadLine(p : IconTypeaheadLineProps){
3030
return (
3131
<FormGroup ctx={ctx} labelText={ctx.niceName()} >
3232
<IconTypeahead icon={ctx.value}
33+
placeholder={p.ctx.placeholderLabels ? p.ctx.niceName() : undefined}
3334
extraIcons={p.extraIcons}
3435
formControlClass={ctx.formControlClass}
3536
onChange={handleChange} />
@@ -42,6 +43,7 @@ export interface IconTypeaheadProps {
4243
onChange: (newIcon: string | null | undefined) => void;
4344
extraIcons?: string[];
4445
formControlClass: string | undefined;
46+
placeholder?: string;
4547
}
4648

4749
export function IconTypeahead(p: IconTypeaheadProps) {
@@ -90,7 +92,7 @@ export function IconTypeahead(p: IconTypeaheadProps) {
9092
return (
9193
<Typeahead
9294
value={(p.icon ?? "")}
93-
inputAttrs={{ className: classes(p.formControlClass, "sf-entity-autocomplete") }}
95+
inputAttrs={{ className: classes(p.formControlClass, "sf-entity-autocomplete"), placeholder: p.placeholder }}
9496
getItems={handleGetItems}
9597
onSelect={handleSelect}
9698
onChange={handleSelect}

Signum.React.Extensions/Dashboard/Admin/Dashboard.tsx

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11

22
import * as React from 'react'
33
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
4-
import { ValueLine, EntityLine, RenderEntity } from '@framework/Lines'
4+
import { ValueLine, EntityLine, RenderEntity, OptionItem } from '@framework/Lines'
55
import { tryGetTypeInfos, New, getTypeInfos } from '@framework/Reflection'
66
import SelectorModal from '@framework/SelectorModal'
77
import { TypeContext } from '@framework/TypeContext'
@@ -13,6 +13,7 @@ import { ColorTypeaheadLine } from "../../Basics/Templates/ColorTypeahead";
1313
import "../Dashboard.css"
1414
import { getToString } from '@framework/Signum.Entities';
1515
import { useForceUpdate } from '@framework/Hooks'
16+
import { softCast } from '../../../Signum.React/Scripts/Globals';
1617

1718
export default function Dashboard(p : { ctx: TypeContext<DashboardEntity> }){
1819
const forceUpdate = useForceUpdate();
@@ -45,6 +46,7 @@ export default function Dashboard(p : { ctx: TypeContext<DashboardEntity> }){
4546
});
4647
}
4748

49+
var colors = ["#DFFF00", "#FFBF00", "#FF7F50", "#DE3163", "#9FE2BF", "#40E0D0", "#6495ED", "#CCCCFF"]
4850

4951
function renderPart(tc: TypeContext<PanelPartEmbedded>) {
5052
const tcs = tc.subCtx({ formGroupStyle: "SrOnly", formSize: "ExtraSmall", placeholderLabels: true });
@@ -56,7 +58,17 @@ export default function Dashboard(p : { ctx: TypeContext<DashboardEntity> }){
5658
<div className="d-flex">
5759
{icon && <div className="mx-2"><FontAwesomeIcon icon={icon} style={{ color: tc.value.iconColor ?? undefined, fontSize: "25px", marginTop: "17px" }} /> </div>}
5860
<div style={{ flexGrow: 1 }} className="mr-2">
59-
<ValueLine ctx={tcs.subCtx(pp => pp.title)} labelText={getToString(tcs.value.content) ?? tcs.niceName(pp => pp.title)} />
61+
62+
<div className="row">
63+
<div className="col-sm-8">
64+
<ValueLine ctx={tcs.subCtx(pp => pp.title)} labelText={getToString(tcs.value.content) ?? tcs.niceName(pp => pp.title)} />
65+
</div>
66+
<div className="col-sm-4">
67+
<ValueLine ctx={tcs.subCtx(pp => pp.interactionGroup)}
68+
optionItems={colors.map((c, i) => ({ label: "Group " + (i + 1), value: "Group" + (i + 1), color: c }))} onRenderDropDownListItem={(io) => <span><span className="sf-dot" style={{ backgroundColor: (io as any).color }} />{io.label}</span>} />
69+
</div>
70+
</div>
71+
6072
<div className="row">
6173
<div className="col-sm-4">
6274
<ValueLine ctx={tcs.subCtx(pp => pp.style)} onChange={() => forceUpdate()} />

Signum.React.Extensions/Dashboard/Dashboard.css

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,3 +99,11 @@ div.row-control-panel {
9999
font-size: 1rem;
100100
margin-left: 2px;
101101
}
102+
103+
.sf-dot {
104+
height: 15px;
105+
width: 15px;
106+
border-radius: 50%;
107+
display: inline-block;
108+
margin-right: 5px;
109+
}

Signum.React.Extensions/Dashboard/Signum.Entities.Dashboard.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,17 @@ export module DashboardPermission {
6565
export const ViewDashboard : Authorization.PermissionSymbol = registerSymbol("Permission", "DashboardPermission.ViewDashboard");
6666
}
6767

68+
export const InteractionGroup = new EnumType<InteractionGroup>("InteractionGroup");
69+
export type InteractionGroup =
70+
"Group1" |
71+
"Group2" |
72+
"Group3" |
73+
"Group4" |
74+
"Group5" |
75+
"Group6" |
76+
"Group7" |
77+
"Group8";
78+
6879
export interface IPartEntity extends Entities.Entity {
6980
requiresTitle: boolean;
7081
}
@@ -92,6 +103,7 @@ export interface PanelPartEmbedded extends Entities.EmbeddedEntity {
92103
row: number;
93104
startColumn: number;
94105
columns: number;
106+
interactionGroup: InteractionGroup | null;
95107
style: Signum.BootstrapStyle;
96108
content: IPartEntity;
97109
}

Signum.React.Extensions/Dashboard/View/DashboardFilterController.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,11 @@ export class DashboardFilterController {
3535
}
3636

3737
getFilterOptions(partEmbedded: PanelPartEmbedded, queryKey: string): FilterOptionParsed[] {
38-
var otherFilters = Array.from(this.filters.values()).filter(f => f.partEmbedded != partEmbedded && f.rows?.length);
38+
39+
if (partEmbedded.interactionGroup == null)
40+
return [];
41+
42+
var otherFilters = Array.from(this.filters.values()).filter(f => f.partEmbedded != partEmbedded && f.partEmbedded.interactionGroup == partEmbedded.interactionGroup && f.rows?.length);
3943

4044
var result = otherFilters.filter(a => a.queryKey == queryKey).map(
4145
df => groupFilter("Or", df.rows.map(

Signum.React.Extensions/Dashboard/View/UserChartPart.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ export default function UserChartPart(p: PanelPartContentProps<UserChartPartEnti
119119
dashboardFilter={p.filterController.filters.get(p.partEmbedded)}
120120
onDrillDown={(row, e) => {
121121
e.stopPropagation();
122-
if (e.altKey)
122+
if (e.altKey || p.partEmbedded.interactionGroup == null)
123123
handleDrillDown(row, e, chartRequest, handleReload);
124124
else {
125125
const dashboardFilter = p.filterController.filters.get(p.partEmbedded);

Signum.React/Scripts/Lines/Lines.css

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,10 +326,12 @@ input[type=checkbox].form-control-xs {
326326
margin-bottom: 0px;
327327
}
328328

329+
.form-control-xs .rw-widget-input,
329330
.rw-widget-xs .rw-widget-input {
330331
min-height: 24px;
331332
}
332333

334+
.form-control-xs .rw-dropdown-list-input,
333335
.rw-widget-xs .rw-dropdown-list-input,
334336
.rw-widget-xs .rw-combobox-input {
335337
padding: 0 0.4em;
@@ -339,6 +341,7 @@ input[type=checkbox].form-control-xs {
339341
padding: 0px;
340342
}
341343

344+
.form-control-xs .rw-widget-picker,
342345
.rw-widget-xs .rw-widget-picker {
343346
min-height: 24px;
344347
}

Signum.React/Scripts/Lines/ValueLine.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,7 @@ function internalDropDownList(vl: ValueLineController) {
314314
}
315315

316316
return (
317-
<FormGroup ctx={s.ctx} labelText={s.labelText} helpText={s.helpText} htmlAttributes={{ ...vl.baseHtmlAttributes(), ...s.formGroupHtmlAttributes }} labelHtmlAttributes={s.labelHtmlAttributes}>
317+
<FormGroup ctx={s.ctx} labelText={s.labelText} helpText={s.helpText} htmlAttributes={{ ...vl.baseHtmlAttributes(), ...s.formGroupHtmlAttributes}} labelHtmlAttributes={s.labelHtmlAttributes}>
318318
{vl.withItemGroup(
319319
<FormControlReadonly htmlAttributes={{
320320
...vl.props.valueHtmlAttributes,
@@ -343,7 +343,7 @@ function internalDropDownList(vl: ValueLineController) {
343343
return (
344344
<FormGroup ctx={s.ctx} labelText={s.labelText} helpText={s.helpText} htmlAttributes={{ ...vl.baseHtmlAttributes(), ...s.formGroupHtmlAttributes }} labelHtmlAttributes={s.labelHtmlAttributes}>
345345
{vl.withItemGroup(
346-
<DropdownList className={addClass(vl.props.valueHtmlAttributes, classes(s.ctx.formControlClass, vl.mandatoryClass))} data={optionItems} onChange={handleOptionItem} value={oi}
346+
<DropdownList className={addClass(vl.props.valueHtmlAttributes, classes(s.ctx.formControlClass, vl.mandatoryClass, "p-0"))} data={optionItems} onChange={handleOptionItem} value={oi}
347347
filter={false}
348348
autoComplete="off"
349349
dataKey="value"

0 commit comments

Comments
 (0)