diff --git a/kernel/av/layout.go b/kernel/av/layout.go index ca8e7e466..5a3235100 100644 --- a/kernel/av/layout.go +++ b/kernel/av/layout.go @@ -16,6 +16,8 @@ package av +import "sort" + // BaseLayout 描述了布局的基础结构。 type BaseLayout struct { Spec int `json:"spec"` // 布局格式版本 @@ -44,6 +46,10 @@ type BaseInstance struct { PageSize int `json:"pageSize"` // 每页项目 } +func (baseInstance *BaseInstance) GetSorts() []*ViewSort { + return baseInstance.Sorts +} + func (baseInstance *BaseInstance) GetFilters() []*ViewFilter { return baseInstance.Filters } @@ -91,6 +97,9 @@ type Collection interface { // GetFields 返回集合的所有字段。 GetFields() []Field + // GetSorts 返回集合的排序规则。 + GetSorts() []*ViewSort + // GetFilters 返回集合的过滤规则。 GetFilters() []*ViewFilter } @@ -119,7 +128,122 @@ type Item interface { GetID() string } -func filter(collection Collection, attrView *AttributeView) { +func sort0(collection Collection, attrView *AttributeView) { + sorts := collection.GetSorts() + if 1 > len(sorts) { + return + } + + type FieldIndexSort struct { + Index int + Order SortOrder + } + + var fieldIndexSorts []*FieldIndexSort + for _, s := range sorts { + for i, c := range collection.GetFields() { + if c.GetID() == s.Column { + fieldIndexSorts = append(fieldIndexSorts, &FieldIndexSort{Index: i, Order: s.Order}) + break + } + } + } + + items := collection.GetItems() + editedValItems := map[string]bool{} + for i, item := range items { + for _, fieldIndexSort := range fieldIndexSorts { + val := items[i].GetValues()[fieldIndexSort.Index] + if KeyTypeCheckbox == val.Type { + if block := item.GetBlockValue(); nil != block && block.IsEdited() { + // 如果主键编辑过,则勾选框也算作编辑过,参与排序 https://github.com/siyuan-note/siyuan/issues/11016 + editedValItems[item.GetID()] = true + break + } + } + + if val.IsEdited() { + // 如果该卡片某字段的值已经编辑过,则该卡片可参与排序 + editedValItems[item.GetID()] = true + break + } + } + } + + // 将未编辑的卡片和已编辑的卡片分开排序 + var uneditedItems, editedItems []Item + for _, item := range items { + if _, ok := editedValItems[item.GetID()]; ok { + editedItems = append(editedItems, item) + } else { + uneditedItems = append(uneditedItems, item) + } + } + + sort.Slice(uneditedItems, func(i, j int) bool { + val1 := uneditedItems[i].GetBlockValue() + if nil == val1 { + return true + } + val2 := uneditedItems[j].GetBlockValue() + if nil == val2 { + return false + } + return val1.CreatedAt < val2.CreatedAt + }) + + sort.Slice(editedItems, func(i, j int) bool { + sorted := true + for _, fieldIndexSort := range fieldIndexSorts { + val1 := editedItems[i].GetValues()[fieldIndexSort.Index] + val2 := editedItems[j].GetValues()[fieldIndexSort.Index] + if nil == val1 || val1.IsEmpty() { + if nil != val2 && !val2.IsEmpty() { + return false + } + sorted = false + continue + } else { + if nil == val2 || val2.IsEmpty() { + return true + } + } + + result := val1.Compare(val2, attrView) + if 0 == result { + sorted = false + continue + } + sorted = true + + if fieldIndexSort.Order == SortOrderAsc { + return 0 > result + } + return 0 < result + } + + if !sorted { + key1 := editedItems[i].GetBlockValue() + if nil == key1 { + return false + } + key2 := editedItems[j].GetBlockValue() + if nil == key2 { + return false + } + return key1.CreatedAt < key2.CreatedAt + } + return false + }) + + // 将包含未编辑的卡片放在最后 + collection.SetItems(append(editedItems, uneditedItems...)) + if 1 > len(collection.GetItems()) { + collection.SetItems([]Item{}) + } +} + +func filter0(collection Collection, attrView *AttributeView) { filters := collection.GetFilters() if 1 > len(filters) { return @@ -135,12 +259,12 @@ func filter(collection Collection, attrView *AttributeView) { } } - items := []Item{} + var items []Item attrViewCache := map[string]*AttributeView{} attrViewCache[attrView.ID] = attrView - for _, row := range collection.GetItems() { + for _, item := range collection.GetItems() { pass := true - values := row.GetValues() + values := item.GetValues() for j, index := range colIndexes { operator := filters[j].Operator @@ -158,13 +282,13 @@ func filter(collection Collection, attrView *AttributeView) { break } - if !values[index].Filter(filters[j], attrView, row.GetID(), &attrViewCache) { + if !values[index].Filter(filters[j], attrView, item.GetID(), &attrViewCache) { pass = false break } } if pass { - items = append(items, row) + items = append(items, item) } } collection.SetItems(items) diff --git a/kernel/av/layout_gallery.go b/kernel/av/layout_gallery.go index bbcc55cec..39696ff08 100644 --- a/kernel/av/layout_gallery.go +++ b/kernel/av/layout_gallery.go @@ -17,8 +17,6 @@ package av import ( - "sort" - "github.com/88250/lute/ast" ) @@ -163,12 +161,12 @@ func (gallery *Gallery) SetItems(items []Item) { } } -func (gallery *Gallery) GetFields() []Field { - fields := []Field{} +func (gallery *Gallery) GetFields() (ret []Field) { + ret = []Field{} for _, field := range gallery.Fields { - fields = append(fields, field) + ret = append(ret, field) } - return fields + return ret } func (gallery *Gallery) GetType() LayoutType { @@ -180,118 +178,9 @@ func (gallery *Gallery) GetID() string { } func (gallery *Gallery) Sort(attrView *AttributeView) { - if 1 > len(gallery.Sorts) { - return - } - - type FieldIndexSort struct { - Index int - Order SortOrder - } - - var fieldIndexSorts []*FieldIndexSort - for _, s := range gallery.Sorts { - for i, c := range gallery.Fields { - if c.ID == s.Column { - fieldIndexSorts = append(fieldIndexSorts, &FieldIndexSort{Index: i, Order: s.Order}) - break - } - } - } - - editedValCards := map[string]bool{} - for i, card := range gallery.Cards { - for _, fieldIndexSort := range fieldIndexSorts { - val := gallery.Cards[i].Values[fieldIndexSort.Index].Value - if KeyTypeCheckbox == val.Type { - if block := card.GetBlockValue(); nil != block && block.IsEdited() { - // 如果主键编辑过,则勾选框也算作编辑过,参与排序 https://github.com/siyuan-note/siyuan/issues/11016 - editedValCards[card.ID] = true - break - } - } - - if val.IsEdited() { - // 如果该卡片某字段的值已经编辑过,则该卡片可参与排序 - editedValCards[card.ID] = true - break - } - } - } - - // 将未编辑的卡片和已编辑的卡片分开排序 - var uneditedCards, editedCards []*GalleryCard - for _, card := range gallery.Cards { - if _, ok := editedValCards[card.ID]; ok { - editedCards = append(editedCards, card) - } else { - uneditedCards = append(uneditedCards, card) - } - } - - sort.Slice(uneditedCards, func(i, j int) bool { - val1 := uneditedCards[i].GetBlockValue() - if nil == val1 { - return true - } - val2 := uneditedCards[j].GetBlockValue() - if nil == val2 { - return false - } - return val1.CreatedAt < val2.CreatedAt - }) - - sort.Slice(editedCards, func(i, j int) bool { - sorted := true - for _, fieldIndexSort := range fieldIndexSorts { - val1 := editedCards[i].Values[fieldIndexSort.Index].Value - val2 := editedCards[j].Values[fieldIndexSort.Index].Value - if nil == val1 || val1.IsEmpty() { - if nil != val2 && !val2.IsEmpty() { - return false - } - sorted = false - continue - } else { - if nil == val2 || val2.IsEmpty() { - return true - } - } - - result := val1.Compare(val2, attrView) - if 0 == result { - sorted = false - continue - } - sorted = true - - if fieldIndexSort.Order == SortOrderAsc { - return 0 > result - } - return 0 < result - } - - if !sorted { - key1 := editedCards[i].GetBlockValue() - if nil == key1 { - return false - } - key2 := editedCards[j].GetBlockValue() - if nil == key2 { - return false - } - return key1.CreatedAt < key2.CreatedAt - } - return false - }) - - // 将包含未编辑的卡片放在最后 - gallery.Cards = append(editedCards, uneditedCards...) - if 1 > len(gallery.Cards) { - gallery.Cards = []*GalleryCard{} - } + sort0(gallery, attrView) } func (gallery *Gallery) Filter(attrView *AttributeView) { - filter(gallery, attrView) + filter0(gallery, attrView) } diff --git a/kernel/av/layout_table.go b/kernel/av/layout_table.go index 0b303c3a2..9c2ee3515 100644 --- a/kernel/av/layout_table.go +++ b/kernel/av/layout_table.go @@ -17,8 +17,6 @@ package av import ( - "sort" - "github.com/88250/lute/ast" ) @@ -151,12 +149,12 @@ func (table *Table) SetItems(items []Item) { } } -func (table *Table) GetFields() []Field { - fields := []Field{} +func (table *Table) GetFields() (ret []Field) { + ret = []Field{} for _, column := range table.Columns { - fields = append(fields, column) + ret = append(ret, column) } - return fields + return ret } func (*Table) GetType() LayoutType { @@ -168,118 +166,9 @@ func (table *Table) GetID() string { } func (table *Table) Sort(attrView *AttributeView) { - if 1 > len(table.Sorts) { - return - } - - type ColIndexSort struct { - Index int - Order SortOrder - } - - var colIndexSorts []*ColIndexSort - for _, s := range table.Sorts { - for i, c := range table.Columns { - if c.ID == s.Column { - colIndexSorts = append(colIndexSorts, &ColIndexSort{Index: i, Order: s.Order}) - break - } - } - } - - editedValRows := map[string]bool{} - for i, row := range table.Rows { - for _, colIndexSort := range colIndexSorts { - val := table.Rows[i].Cells[colIndexSort.Index].Value - if KeyTypeCheckbox == val.Type { - if block := row.GetBlockValue(); nil != block && block.IsEdited() { - // 如果主键编辑过,则勾选框也算作编辑过,参与排序 https://github.com/siyuan-note/siyuan/issues/11016 - editedValRows[row.ID] = true - break - } - } - - if val.IsEdited() { - // 如果该行某列的值已经编辑过,则该行可参与排序 - editedValRows[row.ID] = true - break - } - } - } - - // 将未编辑的行和已编辑的行分开排序 - var uneditedRows, editedRows []*TableRow - for _, row := range table.Rows { - if _, ok := editedValRows[row.ID]; ok { - editedRows = append(editedRows, row) - } else { - uneditedRows = append(uneditedRows, row) - } - } - - sort.Slice(uneditedRows, func(i, j int) bool { - val1 := uneditedRows[i].GetBlockValue() - if nil == val1 { - return true - } - val2 := uneditedRows[j].GetBlockValue() - if nil == val2 { - return false - } - return val1.CreatedAt < val2.CreatedAt - }) - - sort.Slice(editedRows, func(i, j int) bool { - sorted := true - for _, colIndexSort := range colIndexSorts { - val1 := editedRows[i].Cells[colIndexSort.Index].Value - val2 := editedRows[j].Cells[colIndexSort.Index].Value - if nil == val1 || val1.IsEmpty() { - if nil != val2 && !val2.IsEmpty() { - return false - } - sorted = false - continue - } else { - if nil == val2 || val2.IsEmpty() { - return true - } - } - - result := val1.Compare(val2, attrView) - if 0 == result { - sorted = false - continue - } - sorted = true - - if colIndexSort.Order == SortOrderAsc { - return 0 > result - } - return 0 < result - } - - if !sorted { - key1 := editedRows[i].GetBlockValue() - if nil == key1 { - return false - } - key2 := editedRows[j].GetBlockValue() - if nil == key2 { - return false - } - return key1.CreatedAt < key2.CreatedAt - } - return false - }) - - // 将包含未编辑的行放在最后 - table.Rows = append(editedRows, uneditedRows...) - if 1 > len(table.Rows) { - table.Rows = []*TableRow{} - } + sort0(table, attrView) } func (table *Table) Filter(attrView *AttributeView) { - filter(table, attrView) + filter0(table, attrView) }