Skip to content

Commit

Permalink
Merge branch 'master' into MultiProppertySetter
Browse files Browse the repository at this point in the history
  • Loading branch information
olmobrutall committed Sep 13, 2020
2 parents d3df370 + f56723a commit 70b9dde
Show file tree
Hide file tree
Showing 22 changed files with 118 additions and 67 deletions.
4 changes: 2 additions & 2 deletions Signum.Engine/Connection/PostgreSqlConnector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,9 @@ public class PostgreSqlConnector : Connector
{
public override ParameterBuilder ParameterBuilder { get; protected set; }

public Version PostgresVersion { get; set; }
public Version? PostgresVersion { get; set; }

public PostgreSqlConnector(string connectionString, Schema schema, Version postgresVersion) : base(schema.Do(s => s.Settings.IsPostgres = true))
public PostgreSqlConnector(string connectionString, Schema schema, Version? postgresVersion) : base(schema.Do(s => s.Settings.IsPostgres = true))
{
this.ConnectionString = connectionString;
this.ParameterBuilder = new PostgreSqlParameterBuilder();
Expand Down
4 changes: 2 additions & 2 deletions Signum.Engine/DynamicQuery/DynamicQueryFluentInclude.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,14 @@ public static FluentInclude<T> WithExpressionFrom<T, F>(this FluentInclude<T> fi
/// <summary>
/// Uses typeof(T) NiceName as niceName
/// </summary>
public static FluentInclude<T> WithExpressionFrom<T, F>(this FluentInclude<T> fi, Expression<Func<F, T>> lambdaToMethodOrProperty)
public static FluentInclude<T> WithExpressionFrom<T, F>(this FluentInclude<T> fi, Expression<Func<F, T?>> lambdaToMethodOrProperty)
where T : Entity
{
QueryLogic.Expressions.Register(lambdaToMethodOrProperty, () => typeof(T).NiceName());
return fi;
}

public static FluentInclude<T> WithExpressionFrom<T, F>(this FluentInclude<T> fi, Expression<Func<F, T>> lambdaToMethodOrProperty, Func<string> niceName)
public static FluentInclude<T> WithExpressionFrom<T, F>(this FluentInclude<T> fi, Expression<Func<F, T?>> lambdaToMethodOrProperty, Func<string> niceName)
where T : Entity
{
QueryLogic.Expressions.Register(lambdaToMethodOrProperty, niceName);
Expand Down
2 changes: 2 additions & 0 deletions Signum.Entities/Basics/OperationLog.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,10 @@ public OperationLogEntity()

public Lite<IUserEntity> User { get; set; }

[Format("G")]
public DateTime Start { get; set; }

[Format("G")]
public DateTime? End { get; set; }

static Expression<Func<OperationLogEntity, double?>> DurationExpression =
Expand Down
3 changes: 3 additions & 0 deletions Signum.Entities/Translations/Signum.Entities.de.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
<Member Name="Min" Description="Min" />
<Member Name="Sum" Description="Summe" />
</Type>
<Type Name="BigStringEmbedded" Description="Große Saite">
<Member Name="Text" Description="Text" />
</Type>
<Type Name="BooleanEnum">
<Member Name="False" Description="Nein" />
<Member Name="True" Description="Ja" />
Expand Down
1 change: 1 addition & 0 deletions Signum.Entities/Translations/Signum.Entities.en.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Translations>
<Type Name="AggregateFunction" />
<Type Name="BigStringEmbedded" />
<Type Name="BooleanEnum" />
<Type Name="CalendarMessage" />
<Type Name="CollectionAnyAllType" />
Expand Down
1 change: 1 addition & 0 deletions Signum.React/Facades/SignumServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ public static MvcNewtonsoftJsonOptions AddSignumJsonConverters(this MvcNewtonsof

public static MvcOptions AddSignumGlobalFilters(this MvcOptions options)
{
options.Filters.Add(new SignumInitializeFilterAttribute());
options.Filters.Add(new SignumExceptionFilterAttribute());
options.Filters.Add(new CleanThreadContextAndAssertFilter());
options.Filters.Add(new SignumEnableBufferingFilter());
Expand Down
24 changes: 24 additions & 0 deletions Signum.React/Filters/SignumExceptionFilterAttribute.cs
Original file line number Diff line number Diff line change
Expand Up @@ -154,4 +154,28 @@ public HttpError(Exception e, bool includeErrorDetails = true)
public string? StackTrace;
public HttpError? InnerException;
}

public class SignumInitializeFilterAttribute : IAsyncResourceFilter
{
public static Action InitializeDatabase = () => throw new InvalidOperationException("SignumInitializeFilterAttribute.InitializeDatabase should be set in Startup");
static object lockKey = new object();
public bool Initialized = false;

public Task OnResourceExecutionAsync(ResourceExecutingContext context, ResourceExecutionDelegate next)
{
if (!Initialized)
{
lock (lockKey)
{
if (!Initialized)
{
InitializeDatabase();
Initialized = true;
}
}
}

return next();
}
}
}
2 changes: 1 addition & 1 deletion Signum.React/JsonConverters/EntityJsonConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -408,7 +408,7 @@ public void ReadJsonProperty(JsonReader reader, JsonSerializer serializer, Modif
private bool IsEquals(object? newValue, object? oldValue)
{
if (newValue is byte[] nba && oldValue is byte[] oba)
return MemComparer.Equals(nba, oba);
return MemoryExtensions.SequenceEqual<byte>(nba, oba);

if (newValue is DateTime ndt && oldValue is DateTime odt)
return Math.Abs(ndt.Subtract(odt).TotalMilliseconds) < 10; //Json dates get rounded
Expand Down
50 changes: 33 additions & 17 deletions Signum.React/Scripts/Finder.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -512,18 +512,17 @@ export function toFindOptions(fo: FindOptionsParsed, qd: QueryDescription, defau
systemTime: fo.systemTime,
} as FindOptions;

if (!findOptions.groupResults && findOptions.orderOptions && findOptions.orderOptions.length == 1) {
var onlyOrder = findOptions.orderOptions[0]
if (!findOptions.groupResults && findOptions.orderOptions) {
var defaultOrder = getDefaultOrder(qd, qs);

if (defaultOrder && onlyOrder.token == defaultOrder.token && onlyOrder.orderType == defaultOrder.orderType)
findOptions.orderOptions.remove(onlyOrder);
if (equalOrders(defaultOrder, findOptions.orderOptions))
findOptions.orderOptions = undefined;
}

if (findOptions.filterOptions) {
var defaultFilters = getDefaultFilter(qd, qs);
if (defaultFilters && defaultFilters.length <= findOptions.filterOptions.length) {
if (isEqual(defaultFilters, findOptions.filterOptions.slice(0, defaultFilters.length))) {
if (equalFilters(defaultFilters, findOptions.filterOptions.slice(0, defaultFilters.length))) {
findOptions.filterOptions = findOptions.filterOptions.slice(defaultFilters.length);
findOptions.includeDefaultFilters = true;
}
Expand All @@ -538,7 +537,22 @@ export function toFindOptions(fo: FindOptionsParsed, qd: QueryDescription, defau
return findOptions;
}

function isEqual(as: FilterOption[] | undefined, bs: FilterOption[] | undefined): boolean {
function equalOrders(as: OrderOption[] | undefined, bs: OrderOption[] | undefined): boolean {
if (as == undefined && bs == undefined)
return true;

if (as == undefined || bs == undefined)
return true;

return as.length == bs.length && as.every((a, i) => {
var b = bs![i];

return (a.token && a.token.toString()) == (b.token && b.token.toString()) &&
a.orderType == b.orderType;
});
}

function equalFilters(as: FilterOption[] | undefined, bs: FilterOption[] | undefined): boolean {

if (as == undefined && bs == undefined)
return true;
Expand All @@ -554,23 +568,25 @@ function isEqual(as: FilterOption[] | undefined, bs: FilterOption[] | undefined)
((a as FilterConditionOption).operation ?? "EqualTo") == ((b as FilterConditionOption).operation ?? "EqualTo") &&
(a.value == b.value || is(a.value, b.value)) &&
Dic.equals(a.pinned, b.pinned, true) &&
isEqual((a as FilterGroupOption).filters, (b as FilterGroupOption).filters);
equalFilters((a as FilterGroupOption).filters, (b as FilterGroupOption).filters);
});
}

export const defaultOrderColumn: string = "Id";

export function getDefaultOrder(qd: QueryDescription, qs: QuerySettings | undefined): OrderOption | undefined {
const defaultOrder = qs?.defaultOrderColumn ?? defaultOrderColumn;
export function getDefaultOrder(qd: QueryDescription, qs: QuerySettings | undefined): OrderOption[] | undefined {
if (qs?.defaultOrders)
return qs.defaultOrders;

const tis = getTypeInfos(qd.columns["Entity"].type);

if (defaultOrder == defaultOrderColumn && !qd.columns[defaultOrderColumn])
if (!qd.columns[defaultOrderColumn])
return undefined;

return {
token: defaultOrder,
orderType: qs?.defaultOrderType ?? (tis.some(a => a.entityData == "Transactional") ? "Descending" as OrderType : "Ascending" as OrderType)
} as OrderOption;
return [{
token: defaultOrderColumn,
orderType: tis.some(a => a.entityData == "Transactional") ? "Descending" : "Ascending"
}];
}

export function getDefaultFilter(qd: QueryDescription | undefined, qs: QuerySettings | undefined): FilterOption[] | undefined {
Expand Down Expand Up @@ -651,7 +667,7 @@ export function parseFindOptions(findOptions: FindOptions, qd: QueryDescription,
var defaultOrder = getDefaultOrder(qd, qs);

if (defaultOrder)
fo.orderOptions = [defaultOrder];
fo.orderOptions = defaultOrder;
}

if (fo.includeDefaultFilters == null ? defaultIncludeDefaultFilters : fo.includeDefaultFilters) {
Expand Down Expand Up @@ -1468,8 +1484,7 @@ export interface QuerySettings {
queryName: PseudoType | QueryKey;
pagination?: Pagination;
allowSystemTime?: boolean;
defaultOrderColumn?: string | QueryTokenString<any>;
defaultOrderType?: OrderType;
defaultOrders?: OrderOption[];
defaultFilters?: FilterOption[];
hiddenColumns?: ColumnOption[];
formatters?: { [token: string]: CellFormatter };
Expand Down Expand Up @@ -1511,6 +1526,7 @@ export class CellFormatter {
export interface CellFormatterContext {
refresh?: () => void;
systemTime?: SystemTime;
columns: string[];
row: ResultRow;
rowIndex: number;
}
Expand Down
8 changes: 8 additions & 0 deletions Signum.React/Scripts/Hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,14 @@ export function useSize<T extends HTMLElement = HTMLDivElement>(initialTimeout =
return { size, setContainer: setContainerMemo };
}

export function useDocumentEvent(type: string, handler: (e: Event) => void, deps: any[]) {
React.useEffect(() => {
document.addEventListener(type, handler);
return () => {
document.removeEventListener(type, handler);
}
}, deps);
}

export function useStateWithPromise<T>(defaultValue: T): [T, (newValue: React.SetStateAction<T>) => Promise<T>] {
const [state, setState] = React.useState({ value: defaultValue, resolve: (val: T) => { } });
Expand Down
16 changes: 10 additions & 6 deletions Signum.React/Scripts/Lines/Lines.css
Original file line number Diff line number Diff line change
Expand Up @@ -222,27 +222,31 @@ ul.nav-tabs {


/*buton colors*/
.sf-create:hover {
.sf-create:not(.disabled):hover {
color: #22BA00;
}

.sf-remove:hover {
.sf-remove:not(.disabled):hover {
color: #CF0000;
}

.sf-find:hover {
.sf-find:not(.disabled):hover {
color: #FFCC00;
}

.sf-view:hover {
.sf-view:not(.disabled):hover {
color: #007CE8;
}

.sf-move:hover {
.sf-extra:not(.disabled):hover {
color: #9900E0;
}

.sf-move:not(.disabled):hover {
color: #9900E0;
cursor: move;
}
.sf-move.sf-move-step:hover {
.sf-move:not(.disabled).sf-move-step:hover {
cursor: pointer;
}

Expand Down
2 changes: 2 additions & 0 deletions Signum.React/Scripts/Modals/ErrorModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,8 @@ export default function ErrorModal(p: ErrorModalProps) {
}

ErrorModal.showAppropriateError = (error: any): Promise<void> => {
if (error.code === 20) //abort
return Promise.resolve();

if (new RegExp(/^Loading chunk?/i).test(error.message))
return MessageModal.show({
Expand Down
12 changes: 8 additions & 4 deletions Signum.React/Scripts/Operations/EntityOperations.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -154,11 +154,12 @@ interface OperationButtonProps extends ButtonProps {
variant?: BsColor;
canExecute?: string | null;
className?: string;
onOperationClick?: (eoc: EntityOperationContext<any /*Entity*/>) => void;
outline?: boolean;
onOperationClick?: (eoc: EntityOperationContext<any /*Entity*/>, event: React.MouseEvent) => void;
children?: React.ReactNode
}

export function OperationButton({ group, onOperationClick, canExecute, eoc: eocOrNull, ...props }: OperationButtonProps): React.ReactElement<any> | null {
export function OperationButton({ group, onOperationClick, canExecute, eoc: eocOrNull, outline, ...props }: OperationButtonProps): React.ReactElement<any> | null {

if (eocOrNull == null)
return null;
Expand Down Expand Up @@ -200,7 +201,10 @@ export function OperationButton({ group, onOperationClick, canExecute, eoc: eocO
);
}

var button = <Button variant={(eoc.outline ? ("outline-" + eoc.color) as OutlineBsColor: eoc.color)}
if (outline == null)
outline = eoc.outline;

var button = <Button variant={(outline? ("outline-" + eoc.color) as OutlineBsColor: eoc.color)}
{...props}
key="button"
title={eoc.keyboardShortcut && getShortcutToString(eoc.keyboardShortcut)}
Expand Down Expand Up @@ -288,7 +292,7 @@ export function OperationButton({ group, onOperationClick, canExecute, eoc: eocO
event.persist();

if (onOperationClick)
onOperationClick(eoc);
onOperationClick(eoc, event);
else
eoc.click();
}
Expand Down
4 changes: 4 additions & 0 deletions Signum.React/Scripts/SearchControl/Search.css
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,10 @@ span.guid {
white-space: nowrap;
}

.dropdown-item.active span.guid {
color: lightblue;
}

bdi.date {
white-space: nowrap;
}
Expand Down
1 change: 1 addition & 0 deletions Signum.React/Scripts/SearchControl/SearchControlLoaded.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1307,6 +1307,7 @@ export default class SearchControlLoaded extends React.Component<SearchControlLo
const ctx: Finder.CellFormatterContext = {
refresh: () => this.doSearch(true).done(),
systemTime: this.props.findOptions.systemTime,
columns: resultTable.columns,
row: row,
rowIndex : i,
};
Expand Down
7 changes: 5 additions & 2 deletions Signum.React/Scripts/SearchControl/ValueSearchControlLine.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export interface ValueSearchControlLineProps extends React.Props<ValueSearchCont
labelHtmlAttributes?: React.HTMLAttributes<HTMLLabelElement>;
unitText?: React.ReactChild;
formGroupHtmlAttributes?: React.HTMLAttributes<HTMLDivElement>;
helpText?: React.ReactChild;
initialValue?: any;
isLink?: boolean;
isBadge?: boolean | "MoreThanZero";
Expand Down Expand Up @@ -140,7 +141,9 @@ export default class ValueSearchControlLine extends React.Component<ValueSearchC
<FormGroup ctx={this.props.ctx}
labelText={this.props.labelText ?? token?.niceName ?? getQueryNiceName(fo.queryName)}
labelHtmlAttributes={this.props.labelHtmlAttributes}
htmlAttributes={{ ...this.props.formGroupHtmlAttributes, ...{ "data-value-query-key": getQueryKey(fo.queryName)}}}>
htmlAttributes={{ ...this.props.formGroupHtmlAttributes, ...{ "data-value-query-key": getQueryKey(fo.queryName) } }}
helpText={this.props.helpText}
>
<div className={isFormControl ? ((unit || view || extra || find || create) ? this.props.ctx.inputGroupClass : undefined) : this.props.ctx.formControlPlainTextClass}>
<ValueSearchControl
ref={this.handleValueSearchControlLoaded}
Expand All @@ -152,7 +155,7 @@ export default class ValueSearchControlLine extends React.Component<ValueSearchC
customStyle={this.props.customStyle}
badgeColor={this.props.badgeColor}
isLink={this.props.isLink ?? Boolean(this.props.multipleValues)}
formControlClass={isFormControl && !this.props.multipleValues ? this.props.ctx.formControlClass : undefined}
formControlClass={isFormControl && !this.props.multipleValues ? this.props.ctx.formControlClass + " readonly" : undefined}
valueToken={this.props.valueToken}
onValueChange={v => { this.forceUpdate(); this.props.onValueChanged && this.props.onValueChanged(v); }}
onTokenLoaded={() => this.forceUpdate()}
Expand Down
4 changes: 2 additions & 2 deletions Signum.React/Scripts/SelectorModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,8 @@ SelectorModal.chooseType = (options: TypeInfo[]): Promise<TypeInfo | undefined>
});
};

SelectorModal.chooseEnum = <T extends string>(enumType: EnumType<T>, title?: React.ReactNode, message?: React.ReactNode): Promise<T | undefined> => {
return SelectorModal.chooseElement(enumType.values(),
SelectorModal.chooseEnum = <T extends string>(enumType: EnumType<T>, title?: React.ReactNode, message?: React.ReactNode, values?: T[]): Promise<T | undefined> => {
return SelectorModal.chooseElement(values ?? enumType.values(),
{
buttonDisplay: a => enumType.niceToString(a),
buttonName: a => a,
Expand Down
2 changes: 1 addition & 1 deletion Signum.React/Signum.React.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.1.7" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.1.8" />
<PackageReference Include="Microsoft.TypeScript.MSBuild" Version="4.0.2">
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
Expand Down
2 changes: 1 addition & 1 deletion Signum.React/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
"@types/d3-scale-chromatic": "1.5.0",
"@types/history": "4.7.6",
"@types/prop-types": "15.7.3",
"@types/react": "^16.9.48",
"@types/react": "16.9.49",
"@types/react-dom": "16.9.8",
"@types/react-router": "5.1.8",
"@types/react-router-dom": "5.1.5",
Expand Down
Loading

0 comments on commit 70b9dde

Please sign in to comment.