diff --git a/app/src/protyle/render/av/number.ts b/app/src/protyle/render/av/number.ts index dcf772ba0..662d0d3d2 100644 --- a/app/src/protyle/render/av/number.ts +++ b/app/src/protyle/render/av/number.ts @@ -158,6 +158,69 @@ export const formatNumber = (options: { oldFormat: options.oldFormat, avPanelElement: options.avPanelElement, }); + addFormatItem({ + menu, + protyle: options.protyle, + colId: options.colId, + avID: options.avID, + format: "THB", + oldFormat: options.oldFormat, + avPanelElement: options.avPanelElement, + }); + addFormatItem({ + menu, + protyle: options.protyle, + colId: options.colId, + avID: options.avID, + format: "AUD", + oldFormat: options.oldFormat, + avPanelElement: options.avPanelElement, + }); + addFormatItem({ + menu, + protyle: options.protyle, + colId: options.colId, + avID: options.avID, + format: "HKD", + oldFormat: options.oldFormat, + avPanelElement: options.avPanelElement, + }); + addFormatItem({ + menu, + protyle: options.protyle, + colId: options.colId, + avID: options.avID, + format: "TWD", + oldFormat: options.oldFormat, + avPanelElement: options.avPanelElement, + }); + addFormatItem({ + menu, + protyle: options.protyle, + colId: options.colId, + avID: options.avID, + format: "MOP", + oldFormat: options.oldFormat, + avPanelElement: options.avPanelElement, + }); + addFormatItem({ + menu, + protyle: options.protyle, + colId: options.colId, + avID: options.avID, + format: "SGD", + oldFormat: options.oldFormat, + avPanelElement: options.avPanelElement, + }); + addFormatItem({ + menu, + protyle: options.protyle, + colId: options.colId, + avID: options.avID, + format: "NZD", + oldFormat: options.oldFormat, + avPanelElement: options.avPanelElement, + }); const rect = options.element.getBoundingClientRect(); menu.open({ x: rect.left, @@ -196,5 +259,19 @@ export const getLabelByNumberFormat = (format: string) => { return window.siyuan.languages.numberFormatCanadianDollar; case "franc": return window.siyuan.languages.numberFormatFranc; + case "THB": + return window.siyuan.languages.numberFormatTHB; + case "AUD": + return window.siyuan.languages.numberFormatAUD; + case "HKD": + return window.siyuan.languages.numberFormatHKD; + case "TWD": + return window.siyuan.languages.numberFormatTWD; + case "MOP": + return window.siyuan.languages.numberFormatMOP; + case "SGD": + return window.siyuan.languages.numberFormatSGD; + case "NZD": + return window.siyuan.languages.numberFormatNZD; } }; diff --git a/kernel/model/attribute_view.go b/kernel/model/attribute_view.go index 55d4f10eb..e0d23d541 100644 --- a/kernel/model/attribute_view.go +++ b/kernel/model/attribute_view.go @@ -147,18 +147,63 @@ func SetAttributeViewGroup(avID, blockID string, group *av.ViewGroup) (err error // TODO Database grouping by field https://github.com/siyuan-note/siyuan/issues/10964 // 生成分组数据 - groupItems := map[string][]av.Item{} + const ( + defaultGroupName = "_@default@_" + notInRange = "_@notInRange@_" + ) + var groupName string viewable := sql.RenderView(attrView, view, "") - collection := viewable.(av.Collection) - for _, item := range collection.GetItems() { - value := item.GetValue(group.Field) - switch group.Method { - case av.GroupMethodValue: - strVal := value.String(false) - groupItems[strVal] = append(groupItems[strVal], item) - } + + var items []av.Item + for _, item := range viewable.(av.Collection).GetItems() { + items = append(items, item) } - for _, items := range groupItems { + var rangeStart, rangeEnd float64 + switch group.Method { + case av.GroupMethodValue: + case av.GroupMethodRangeNum: + rangeStart, rangeEnd = group.Range.NumStart, group.Range.NumEnd + sort.SliceStable(items, func(i, j int) bool { + if av.GroupOrderAsc == group.Order { + return items[i].GetValue(group.Field).Number.Content < items[j].GetValue(group.Field).Number.Content + } + return items[i].GetValue(group.Field).Number.Content > items[j].GetValue(group.Field).Number.Content + }) + } + + groupItems := map[string][]av.Item{} + for _, item := range items { + value := item.GetValue(group.Field) + if value.IsEmpty() { + groupName = defaultGroupName + } else { + switch group.Method { + case av.GroupMethodValue: + groupName = value.String(false) + case av.GroupMethodRangeNum: + if nil != group.Range && value.Type == av.KeyTypeNumber { + if group.Range.NumStart > value.Number.Content || group.Range.NumEnd < value.Number.Content { + groupName = notInRange + break + } + + for rangeEnd <= group.Range.NumEnd { + if rangeEnd < value.Number.Content { + rangeStart += group.Range.NumStep + rangeEnd += group.Range.NumStep + } + } + + if rangeStart <= value.Number.Content && rangeEnd >= value.Number.Content { + groupName = fmt.Sprintf("%s - %s", strconv.FormatFloat(rangeStart, 'f', -1, 64), strconv.FormatFloat(rangeEnd, 'f', -1, 64)) + } + } + } + } + groupItems[groupName] = append(groupItems[groupName], item) + } + + for name, items := range groupItems { var v *av.View switch view.LayoutType { case av.LayoutTypeTable: @@ -172,6 +217,7 @@ func SetAttributeViewGroup(avID, blockID string, group *av.ViewGroup) (err error v.GroupItemIDs = append(v.GroupItemIDs, item.GetID()) } view.Groups = append(view.Groups, v) + view.GroupDefault = name == defaultGroupName } err = av.SaveAttributeView(attrView)