diff --git a/kernel/av/av.go b/kernel/av/av.go index 63ac63bcc..42930afc0 100644 --- a/kernel/av/av.go +++ b/kernel/av/av.go @@ -39,10 +39,9 @@ type AttributeView struct { Columns []*Column `json:"columns"` // 表格列名 Rows []*Row `json:"rows"` // 表格行记录 - Type AttributeViewType `json:"type"` // 属性视图类型 - Projections []string `json:"projections"` // 显示的列名 - Filters []*AttributeViewFilter `json:"filters"` // 过滤规则 - Sorts []*AttributeViewSort `json:"sorts"` // 排序规则 + Type AttributeViewType `json:"type"` // 属性视图类型 + Filters []*AttributeViewFilter `json:"filters"` // 过滤规则 + Sorts []*AttributeViewSort `json:"sorts"` // 排序规则 } // AttributeViewType 描述了属性视图的类型。 @@ -54,15 +53,14 @@ const ( func NewAttributeView(id string) *AttributeView { return &AttributeView{ - Spec: 0, - ID: id, - Name: "Table", - Columns: []*Column{{ID: ast.NewNodeID(), Name: "Block", Type: ColumnTypeBlock}}, - Rows: []*Row{}, - Type: AttributeViewTypeTable, - Projections: []string{}, - Filters: []*AttributeViewFilter{}, - Sorts: []*AttributeViewSort{}, + Spec: 0, + ID: id, + Name: "Table", + Columns: []*Column{{ID: ast.NewNodeID(), Name: "Block", Type: ColumnTypeBlock}}, + Rows: []*Row{}, + Type: AttributeViewTypeTable, + Filters: []*AttributeViewFilter{}, + Sorts: []*AttributeViewSort{}, } } diff --git a/kernel/model/attribute_view.go b/kernel/model/attribute_view.go index f3c44184b..afb499338 100644 --- a/kernel/model/attribute_view.go +++ b/kernel/model/attribute_view.go @@ -24,10 +24,12 @@ import ( "github.com/88250/gulu" "github.com/88250/lute/ast" "github.com/88250/lute/parse" + "github.com/jinzhu/copier" "github.com/siyuan-note/logging" "github.com/siyuan-note/siyuan/kernel/av" "github.com/siyuan-note/siyuan/kernel/sql" "github.com/siyuan-note/siyuan/kernel/treenode" + "github.com/siyuan-note/siyuan/kernel/util" ) func RenderAttributeView(avID string) (ret *av.AttributeView, err error) { @@ -225,6 +227,14 @@ func (tx *Transaction) doSetAttrViewColumnWidth(operation *Operation) (ret *TxEr return } +func (tx *Transaction) doSetAttrView(operation *Operation) (ret *TxErr) { + err := setAttributeView(operation) + if nil != err { + return &TxErr{code: TxErrWriteAttributeView, id: operation.ParentID, msg: err.Error()} + } + return +} + func addAttributeViewColumn(name string, typ string, avID string) (err error) { attrView, err := av.ParseAttributeView(avID) if nil != err { @@ -327,12 +337,12 @@ func sortAttributeViewColumn(columnID, previousColumnID, avID string) (err error break } } - attrView.Columns = insertElement(attrView.Columns, previousIndex, col) + attrView.Columns = util.InsertElement(attrView.Columns, previousIndex, col) for _, row := range attrView.Rows { cel := row.Cells[index] row.Cells = append(row.Cells[:index], row.Cells[index+1:]...) - row.Cells = insertElement(row.Cells, previousIndex, cel) + row.Cells = util.InsertElement(row.Cells, previousIndex, cel) } err = av.SaveAttributeView(attrView) @@ -365,22 +375,12 @@ func sortAttributeViewRow(rowID, previousRowID, avID string) (err error) { break } } - attrView.Rows = insertElement(attrView.Rows, previousIndex, row) + attrView.Rows = util.InsertElement(attrView.Rows, previousIndex, row) err = av.SaveAttributeView(attrView) return } -// 0 <= index <= len(a) -func insertElement[T any](rows []T, index int, value T) []T { - if len(rows) == index { // nil or empty slice or after last element - return append(rows, value) - } - rows = append(rows[:index+1], rows[index:]...) // index < len(a) - rows[index] = value - return rows -} - func setAttributeViewColHidden(hidden bool, columnID, avID string) (err error) { attrView, err := av.ParseAttributeView(avID) if nil != err { @@ -432,6 +432,31 @@ func setAttributeViewColWidth(width, columnID, avID string) (err error) { return } +func setAttributeView(operation *Operation) (err error) { + avID := operation.ID + attrView, err := av.ParseAttributeView(avID) + if nil != err { + return + } + + data, err := gulu.JSON.MarshalJSON(operation.Data) + if nil != err { + return + } + + newAttrView := &av.AttributeView{} + if err = gulu.JSON.UnmarshalJSON(data, newAttrView); nil != err { + return + } + + if err = copier.Copy(attrView, newAttrView); nil != err { + return + } + + err = av.SaveAttributeView(attrView) + return +} + func removeAttributeViewBlock(blockID, avID string) (ret *av.AttributeView, err error) { ret, err = av.ParseAttributeView(avID) if nil != err { diff --git a/kernel/model/transaction.go b/kernel/model/transaction.go index f2de2be16..124d19238 100644 --- a/kernel/model/transaction.go +++ b/kernel/model/transaction.go @@ -238,6 +238,8 @@ func performTx(tx *Transaction) (ret *TxErr) { ret = tx.doSetAttrViewColumnWrap(op) case "setAttrViewColWidth": ret = tx.doSetAttrViewColumnWidth(op) + case "setAttrView": + ret = tx.doSetAttrView(op) } if nil != ret { diff --git a/kernel/util/string.go b/kernel/util/misc.go similarity index 82% rename from kernel/util/string.go rename to kernel/util/misc.go index cb96cdb4f..310f7fc29 100644 --- a/kernel/util/string.go +++ b/kernel/util/misc.go @@ -24,6 +24,18 @@ import ( "github.com/88250/lute/html" ) +// InsertElement inserts a new element value at the specified index position. +// 0 <= index <= len(a) +func InsertElement[T any](ret []T, index int, value T) []T { + if len(ret) == index { // nil or empty slice or after last element + return append(ret, value) + } + + ret = append(ret[:index+1], ret[index:]...) // index < len(a) + ret[index] = value + return ret +} + func EscapeHTML(s string) string { if strings.Contains(s, "&") { return s