Skip to content

Commit

Permalink
Merge pull request #35 from KorzhCom/dev
Browse files Browse the repository at this point in the history
Version 1.2.6
  • Loading branch information
antifree authored Apr 29, 2021
2 parents 71bca10 + 26ea01e commit 5b39636
Show file tree
Hide file tree
Showing 14 changed files with 314 additions and 78 deletions.
43 changes: 41 additions & 2 deletions easydata.js/packs/core/src/i18n/i18n.ts
Original file line number Diff line number Diff line change
Expand Up @@ -428,7 +428,10 @@ export namespace i18n {
export function numberToStr(number: number, format?: string): string {
if (format && format.length > 0) {
const type = format.charAt(0);
if (['D', 'F', 'C'].indexOf(type) >= 0) {
if (type === 'S') {
return formatWithSequence(number, format.slice(1));
}
else if (['D', 'F', 'C'].indexOf(type) >= 0) {
const locale = getCurrentLocale();
return number.toLocaleString(locale, getNumberFromatOptions(format));
}
Expand All @@ -442,11 +445,12 @@ export namespace i18n {
}

export function booleanToStr(bool: boolean, format?: string) {

if (format && format.length > 0) {
const type = format.charAt(0);
if (type === 'S') {
const values = format.slice(1).split('|');
if (values.length === 2) {
if (values.length > 1) {
const value = values[(bool) ? 1 : 0];
return i18n.getText(value) || value;
}
Expand All @@ -455,6 +459,41 @@ export namespace i18n {
return `${bool}`;
}

const cachedSequenceFormats: { [format: string]: {[key: number]: string} } = {};

function formatWithSequence(number: number, format: string): string {
if (!cachedSequenceFormats[format]) {

// parse and save in cache format values
const values = format.split('|')
.filter(v => v.length > 0)
.map(v => v.split('='));

cachedSequenceFormats[format] = {}
if (values.length > 0) {
if (values[0].length > 1) {
for (const value of values) {
cachedSequenceFormats[format][Number.parseInt(value[1])] = value[0];
}
}
else {
values.forEach((value, index) => {
cachedSequenceFormats[format][index] = value[0];
});
}
}

}

const values = cachedSequenceFormats[format];
if (values[number] !== undefined) {
const value = values[number];
return i18n.getText(value) || value;
}

return number.toString();
}

function convertWithMask(number: number, mask: string) {
let value = number.toString();
let result = '';
Expand Down
2 changes: 1 addition & 1 deletion easydata.js/packs/ui/src/grid/easy_grid.ts
Original file line number Diff line number Diff line change
Expand Up @@ -670,7 +670,7 @@ export class EasyGrid {
.catch(error => {
console.error(error);
return [];
});;
});
}

protected renderFooter() {
Expand Down
6 changes: 3 additions & 3 deletions easydata.js/version.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"version": "1.2.5",
"baseVersion": "1.2.5",
"assetVersion": "01_02_05"
"version": "1.2.6",
"baseVersion": "1.2.6",
"assetVersion": "01_02_06"
}
47 changes: 34 additions & 13 deletions easydata.net/src/EasyData.Core/DataUtils.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;

namespace EasyData
Expand Down Expand Up @@ -107,35 +108,55 @@ public static string ComposeKey(string parent, string child)
/// <returns></returns>
public static DataType GetDataTypeBySystemType(Type systemType)
{
if (systemType.IsEnum)
return GetDataTypeBySystemType(systemType.GetEnumUnderlyingType());
if (systemType == typeof(bool) || systemType == typeof(bool?))
return DataType.Bool;
else if (systemType == typeof(byte[]))
if (systemType == typeof(byte[]))
return DataType.Blob;
else if (systemType == typeof(Guid))
if (systemType == typeof(Guid))
return DataType.Guid;
else if (systemType == typeof(byte) || systemType == typeof(char) || systemType == typeof(sbyte) || systemType == typeof(byte?) || systemType == typeof(char?) || systemType == typeof(sbyte?))
if (systemType == typeof(byte) || systemType == typeof(char) || systemType == typeof(sbyte) || systemType == typeof(byte?) || systemType == typeof(char?) || systemType == typeof(sbyte?))
return DataType.Byte;
else if (systemType == typeof(DateTime) || systemType == typeof(DateTime?)
if (systemType == typeof(DateTime) || systemType == typeof(DateTime?)
|| systemType == typeof(DateTimeOffset) || systemType == typeof(DateTimeOffset?))
return DataType.DateTime;
else if (systemType == typeof(TimeSpan) || systemType == typeof(TimeSpan?))
if (systemType == typeof(TimeSpan) || systemType == typeof(TimeSpan?))
return DataType.Time;
else if (systemType == typeof(decimal) || systemType == typeof(decimal?))
if (systemType == typeof(decimal) || systemType == typeof(decimal?))
return DataType.Currency;
else if (systemType == typeof(double) || systemType == typeof(Single) || systemType == typeof(float) || systemType == typeof(double?) || systemType == typeof(Single?) || systemType == typeof(float?))
if (systemType == typeof(double) || systemType == typeof(Single) || systemType == typeof(float) || systemType == typeof(double?) || systemType == typeof(Single?) || systemType == typeof(float?))
return DataType.Float;
else if (systemType == typeof(short) || systemType == typeof(ushort) || systemType == typeof(short?) || systemType == typeof(ushort?))
if (systemType == typeof(short) || systemType == typeof(ushort) || systemType == typeof(short?) || systemType == typeof(ushort?))
return DataType.Word;
else if (systemType == typeof(int) || systemType == typeof(uint) || systemType == typeof(int?) || systemType == typeof(uint?))
if (systemType == typeof(int) || systemType == typeof(uint) || systemType == typeof(int?) || systemType == typeof(uint?))
return DataType.Int32;
else if (systemType == typeof(long) || systemType == typeof(ulong) || systemType == typeof(long?) || systemType == typeof(ulong?))
if (systemType == typeof(long) || systemType == typeof(ulong) || systemType == typeof(long?) || systemType == typeof(ulong?))
return DataType.Int64;
else if (systemType == typeof(string))
if (systemType == typeof(string))
return DataType.String;
else
return DataType.Unknown;

return DataType.Unknown;
}

/// <summary>
/// Builds sequence display format for enum.
/// </summary>
/// <param name="enumType">Type of the enum.</param>
/// <returns></returns>
public static string ComposeDisplayFormatForEnum(Type enumType)
{
if (!enumType.IsEnum)
return "";

var result = string.Join("|", enumType.GetFields()
.Where(f => f.Name != "value__")
.Select(f => $"{f.Name}={f.GetRawConstantValue()}"));

return "{0:S" + result + "}";
}



/// <summary>
/// Convert string representation in internal format to DateTime value.
Expand Down
67 changes: 56 additions & 11 deletions easydata.net/src/EasyData.Core/Formats/SequenceFormat.cs
Original file line number Diff line number Diff line change
@@ -1,23 +1,53 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Text;
using System.Linq;

namespace EasyData
{
public class SequenceFormat : IFormatProvider, ICustomFormatter
{

private readonly CultureInfo _culture;
private readonly string _format;

public SequenceFormat() : this(CultureInfo.InvariantCulture)
private readonly Dictionary<long, string> _values;

public SequenceFormat(string format) : this(format, CultureInfo.InvariantCulture)
{

}

public SequenceFormat(CultureInfo culture)
public SequenceFormat(string format, CultureInfo culture)
{
if (!format.StartsWith("S"))
throw new FormatException(string.Format("The format of '{0}' is invalid.", format));

_format = format;
_culture = culture;
_values = new Dictionary<long, string>();

var keyValues = format.Substring(1)
.Split('|')
.Where(v => v != string.Empty)
.Select(v => v.Split('='))
.ToArray();

if (keyValues.Length > 0) {
var containsKey = keyValues.First().Length == 2;
if (containsKey) {
foreach (var kv in keyValues) {
_values[long.Parse(kv[1])] = kv[0];
}
}
else {
for (long i = 0; i < keyValues.Length; i++) {
_values[i] = keyValues[i][0];
}
}

}

}

public object GetFormat(Type formatType)
Expand All @@ -28,10 +58,21 @@ public object GetFormat(Type formatType)
return null;
}

private static HashSet<Type> _appliedTypes = new HashSet<Type>
{
typeof(bool),
typeof(sbyte),
typeof(byte),
typeof(int),
typeof(uint),
typeof(long),
typeof(ulong),
};

public string Format(string fmt, object arg, IFormatProvider formatProvider)
{
// Provide default formatting if arg is not an Int64.
if (!fmt.StartsWith("S") || arg.GetType() != typeof(bool)) {
if (!fmt.StartsWith("S") || fmt != _format || !_appliedTypes.Contains(arg.GetType())) {
try {
return HandleOtherFormats(fmt, arg);
}
Expand All @@ -40,13 +81,17 @@ public string Format(string fmt, object arg, IFormatProvider formatProvider)
}
}

var values = fmt.Substring(1).Split('|');
if (values.Length != 2) {
throw new FormatException(String.Format("The format of '{0}' is invalid.", fmt));
if (arg is bool boolVal) {
if (_values.TryGetValue((boolVal) ? 1 : 0, out var result))
return result;
}

var value = (bool)arg;
return values[(value) ? 1 : 0];
else {
var longVal = (long)Convert.ChangeType(arg, typeof(long));
if (_values.TryGetValue(longVal, out var result))
return result;
}

return arg.ToString();
}

private string HandleOtherFormats(string format, object arg)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,10 @@ protected virtual void ProcessNavigationProperty(MetaEntity entity, IEntityType

lookUpAttr.PropInfo = navigation.PropertyInfo;

if (property.ClrType.IsEnum) {
lookUpAttr.DisplayFormat = DataUtils.ComposeDisplayFormatForEnum(property.ClrType);
}

var enabled = ApplyMetaEntityAttrAttribute(lookUpAttr, navigation.PropertyInfo);
if (!enabled)
return;
Expand Down Expand Up @@ -272,6 +276,10 @@ protected virtual MetaEntityAttr CreateEntityAttribute(MetaEntity entity, IEntit

entityAttr.IsNullable = property.IsNullable;

if (property.ClrType.IsEnum) {
entityAttr.DisplayFormat = DataUtils.ComposeDisplayFormatForEnum(property.ClrType);
}

var propInfo = property.PropertyInfo;
if (propInfo != null) {
if (propInfo.GetCustomAttribute(typeof(DisplayAttribute)) is DisplayAttribute displayAttr) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,9 @@ public async Task ExportAsync(IEasyDataResultSet data, Stream stream, IDataExpor
{
var mappedSettings = MapSettings(settings);

// predefined formatters
var predefinedFormatters = GetPredefinedFormatters(data.Cols, settings);

// replace forbidden symbols
var r = new Regex(@"[\/\*\?:\[\]]");
var result = r.Replace(mappedSettings.Title ?? "", "");
Expand Down Expand Up @@ -143,7 +146,16 @@ Task WriteRowAsync(EasyDataRow row, bool isExtra = false, CancellationToken canc
var dfmt = data.Cols[i].DisplayFormat;
var type = data.Cols[i].Type;

ws.Cell($"{rowCellLetter}{cellNum}").Value = row[i] ?? "";

object value;
if (!string.IsNullOrEmpty(dfmt) && predefinedFormatters.TryGetValue(dfmt, out var provider)) {
value = string.Format(provider, dfmt, row[i]);
}
else {
value = row[i];
}

ws.Cell($"{rowCellLetter}{cellNum}").Value = value ?? "";
if (isExtra)
ws.Cell($"{rowCellLetter}{cellNum}").Style.Font.Bold = true;
rowCellLetter++;
Expand All @@ -156,7 +168,8 @@ Task WriteRowAsync(EasyDataRow row, bool isExtra = false, CancellationToken canc
return Task.CompletedTask;
}

Func<EasyDataRow, CancellationToken, Task> WriteExtraRowAsync = (extraRow, cancellationToken) => WriteRowAsync(extraRow, true, cancellationToken);
Func<EasyDataRow, CancellationToken, Task> WriteExtraRowAsync = (extraRow, cancellationToken)
=> WriteRowAsync(extraRow, true, cancellationToken);

foreach (var row in data.Rows) {
var add = settings?.RowFilter?.Invoke(row);
Expand Down Expand Up @@ -185,18 +198,21 @@ Task WriteRowAsync(EasyDataRow row, bool isExtra = false, CancellationToken canc
var dfmt = col.DisplayFormat;
var colRange = ws.Range($"{letter}{endHeaderNum}:{letter}{cellNum}");
var dataType = MapDataType(type);
colRange.DataType = dataType;
if (type == DataType.Bool) {
colRange.Style.NumberFormat.Format = "\"True\";;\"False\";";
}
if (dataType == XLDataType.DateTime) {
var format = Utils.GetDateFormat(type, mappedSettings, dfmt);
colRange.Style.DateFormat.Format = format;
if (!string.IsNullOrEmpty(dfmt) && predefinedFormatters.ContainsKey(dfmt)) {
colRange.DataType = XLDataType.Text;
}
else if (!string.IsNullOrEmpty(dfmt)) {
var format = Utils.GetExcelDisplayFormat(mappedSettings, dfmt);
colRange.Style.NumberFormat.Format = format;
else {
colRange.DataType = dataType;
if (dataType == XLDataType.DateTime) {
var format = Utils.GetDateFormat(type, mappedSettings, dfmt);
colRange.Style.DateFormat.Format = format;
}
else if (!string.IsNullOrEmpty(dfmt)) {
var format = Utils.GetExcelDisplayFormat(mappedSettings, dfmt);
colRange.Style.NumberFormat.Format = format;
}
}

colRange.Style.Alignment.Horizontal = MapAlignment(col.Style.Alignment);
letter++;
}
Expand Down Expand Up @@ -240,6 +256,22 @@ Task WriteRowAsync(EasyDataRow row, bool isExtra = false, CancellationToken canc
}
}

private Dictionary<string, IFormatProvider> GetPredefinedFormatters(IReadOnlyList<EasyDataCol> cols, IDataExportSettings settings)
{
var result = new Dictionary<string, IFormatProvider>();
for (int i = 0; i < cols.Count; i++) {
var dfmt = cols[i].DisplayFormat;
if (!string.IsNullOrEmpty(dfmt) && !result.ContainsKey(dfmt)) {
var format = Utils.GetFormat(dfmt);
if (format.StartsWith("S")) {
result.Add(dfmt, new SequenceFormat(format, settings.Culture));
}
}

}
return result;
}

private static XLAlignmentHorizontalValues MapAlignment(ColumnAlignment alignment)
{
switch (alignment) {
Expand All @@ -257,12 +289,13 @@ private static XLAlignmentHorizontalValues MapAlignment(ColumnAlignment alignmen
private static XLDataType MapDataType(DataType type)
{
switch (type) {
case DataType.Bool:
return XLDataType.Boolean;
case DataType.Date:
case DataType.DateTime:
return XLDataType.DateTime;
case DataType.Time:
return XLDataType.TimeSpan;
case DataType.Bool:
case DataType.Byte:
case DataType.Currency:
case DataType.Int32:
Expand Down
Loading

0 comments on commit 5b39636

Please sign in to comment.