diff --git a/kernel/av/av.go b/kernel/av/av.go index 36de95fda..87b13b67e 100644 --- a/kernel/av/av.go +++ b/kernel/av/av.go @@ -254,7 +254,6 @@ func NewGalleryView() (ret *View) { type Viewable interface { Filterable Sortable - Groupable Calculable GetType() LayoutType diff --git a/kernel/av/group.go b/kernel/av/group.go index 3cd846c13..25ee349d0 100644 --- a/kernel/av/group.go +++ b/kernel/av/group.go @@ -16,13 +16,6 @@ package av -// Groupable 定义了可分组的视图类型。 -type Groupable interface { - - // Group 根据视图中设置的分组规则进行分组。 - Group(attrView *AttributeView) -} - type ViewGroup struct { Field string `json:"field"` // 分组字段 ID Method GroupMethod `json:"method"` // 分组方式 diff --git a/kernel/av/layout.go b/kernel/av/layout.go index 437e50b36..5610af3c5 100644 --- a/kernel/av/layout.go +++ b/kernel/av/layout.go @@ -316,7 +316,3 @@ func filter0(collection Collection, attrView *AttributeView) { } collection.SetItems(items) } - -func group0(collection Collection, attrView *AttributeView) { - // TODO 分组 Database grouping by field https://github.com/siyuan-note/siyuan/issues/10964 -} diff --git a/kernel/av/layout_gallery.go b/kernel/av/layout_gallery.go index 0c6c01a63..231404597 100644 --- a/kernel/av/layout_gallery.go +++ b/kernel/av/layout_gallery.go @@ -190,7 +190,3 @@ func (gallery *Gallery) Sort(attrView *AttributeView) { func (gallery *Gallery) Filter(attrView *AttributeView) { filter0(gallery, attrView) } - -func (gallery *Gallery) Group(attrView *AttributeView) { - group0(gallery, attrView) -} diff --git a/kernel/av/layout_table.go b/kernel/av/layout_table.go index 6dad96825..e7dcf2105 100644 --- a/kernel/av/layout_table.go +++ b/kernel/av/layout_table.go @@ -168,7 +168,3 @@ func (table *Table) Sort(attrView *AttributeView) { func (table *Table) Filter(attrView *AttributeView) { filter0(table, attrView) } - -func (table *Table) Group(attrView *AttributeView) { - group0(table, attrView) -} diff --git a/kernel/model/attribute_view.go b/kernel/model/attribute_view.go index 220381ed2..7ec39eacf 100644 --- a/kernel/model/attribute_view.go +++ b/kernel/model/attribute_view.go @@ -44,6 +44,59 @@ import ( "github.com/xrash/smetrics" ) +func (tx *Transaction) doSetAttrViewGroup(operation *Operation) (ret *TxErr) { + err := setAttrViewGroup(operation) + if err != nil { + return &TxErr{code: TxErrWriteAttributeView, id: operation.AvID, msg: err.Error()} + } + return +} + +func setAttrViewGroup(operation *Operation) error { + attrView, err := av.ParseAttributeView(operation.AvID) + if err != nil { + return err + } + + view, err := getAttrViewViewByBlockID(attrView, operation.BlockID) + if err != nil { + return err + } + + group := operation.Data.(*av.ViewGroup) + view.Group = group + + // TODO Database grouping by field https://github.com/siyuan-note/siyuan/issues/10964 + // 生成分组数据 + switch view.LayoutType { + case av.LayoutTypeTable: + table := sql.RenderAttributeViewTable(attrView, view, "") + groupRows := map[string][]*av.TableRow{} + for _, row := range table.Rows { + value := row.GetValue(group.Field) + switch group.Method { + case av.GroupMethodValue: + strVal := value.String(false) + groupRows[strVal] = append(groupRows[strVal], row) + } + } + + for _, rows := range groupRows { + v := av.NewTableView() + v.Table = av.NewLayoutTable() + for _, row := range rows { + v.Table.RowIDs = append(v.Table.RowIDs, row.ID) + } + view.Groups = append(view.Groups, v) + } + case av.LayoutTypeGallery: + + } + + err = av.SaveAttributeView(attrView) + return err +} + func (tx *Transaction) doSetAttrViewCardAspectRatio(operation *Operation) (ret *TxErr) { err := setAttrViewCardAspectRatio(operation) if err != nil { @@ -1232,7 +1285,37 @@ func renderAttributeView(attrView *av.AttributeView, viewID, query string, page, checkAttrView(attrView, view) upgradeAttributeViewSpec(attrView) + if nil != view.Group && 0 < len(view.Groups) { + var instances []av.Viewable + for _, groupView := range view.Groups { + groupViewable := sql.RenderView(groupView, attrView, query) + err = renderViewableInstance(groupViewable, view, attrView, page, pageSize) + if nil != err { + return + } + instances = append(instances, groupViewable) + } + + viewable = instances[0] + switch view.LayoutType { + case av.LayoutTypeTable: + for i := 1; i < len(instances); i++ { + viewable.(*av.Table).Groups = append(viewable.(*av.Table).Groups, instances[i].(*av.Table).Groups...) + } + case av.LayoutTypeGallery: + for i := 1; i < len(instances); i++ { + viewable.(*av.Gallery).Groups = append(viewable.(*av.Gallery).Groups, instances[i].(*av.Gallery).Groups...) + } + } + return + } + viewable = sql.RenderView(view, attrView, query) + err = renderViewableInstance(viewable, view, attrView, page, pageSize) + return +} + +func renderViewableInstance(viewable av.Viewable, view *av.View, attrView *av.AttributeView, page, pageSize int) (err error) { if nil == viewable { err = av.ErrViewNotFound logging.LogErrorf("render attribute view [%s] failed", attrView.ID) diff --git a/kernel/model/transaction.go b/kernel/model/transaction.go index 3a122efcc..0c1530c31 100644 --- a/kernel/model/transaction.go +++ b/kernel/model/transaction.go @@ -296,6 +296,8 @@ func performTx(tx *Transaction) (ret *TxErr) { ret = tx.doSetAttrViewBlockView(op) case "setAttrViewCardAspectRatio": ret = tx.doSetAttrViewCardAspectRatio(op) + case "doSetAttrViewGroup": + ret = tx.doSetAttrViewGroup(op) } if nil != ret {