mirror of
https://github.com/siyuan-note/siyuan.git
synced 2025-12-17 15:10:12 +01:00
♻️ Refactor av data structure
This commit is contained in:
parent
cea83ad522
commit
ad77e4d7f3
5 changed files with 129 additions and 97 deletions
|
|
@ -47,8 +47,8 @@ type View struct {
|
|||
Name string `json:"name"` // 视图名称
|
||||
Type ViewType `json:"type"` // 视图类型
|
||||
|
||||
Filters []*ViewFilter `json:"filters"` // 过滤规则
|
||||
Sorts []*ViewSort `json:"sorts"` // 排序规则
|
||||
Table *Table `json:"table,omitempty"` // 表格视图
|
||||
// TODO Kanban *Kanban `json:"kanban,omitempty"` // 看板视图
|
||||
}
|
||||
|
||||
// ViewType 描述了视图的类型。
|
||||
|
|
@ -59,6 +59,22 @@ const (
|
|||
ViewTypeKanban ViewType = "kanban" // 属性视图类型 - 看板
|
||||
)
|
||||
|
||||
func NewView() *View {
|
||||
id := ast.NewNodeID()
|
||||
name := "Table"
|
||||
return &View{
|
||||
ID: id,
|
||||
Name: name,
|
||||
Type: ViewTypeTable,
|
||||
Table: &Table{
|
||||
Spec: 0,
|
||||
ID: id,
|
||||
Filters: []*ViewFilter{},
|
||||
Sorts: []*ViewSort{},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// Viewable 描述了视图的接口。
|
||||
type Viewable interface {
|
||||
Filterable
|
||||
|
|
@ -70,13 +86,7 @@ type Viewable interface {
|
|||
}
|
||||
|
||||
func NewAttributeView(id string) *AttributeView {
|
||||
view := &View{
|
||||
ID: ast.NewNodeID(),
|
||||
Name: "Table",
|
||||
Type: ViewTypeTable,
|
||||
Filters: []*ViewFilter{},
|
||||
Sorts: []*ViewSort{},
|
||||
}
|
||||
view := NewView()
|
||||
|
||||
return &AttributeView{
|
||||
Spec: 0,
|
||||
|
|
@ -108,14 +118,7 @@ func ParseAttributeView(avID string) (ret *AttributeView, err error) {
|
|||
}
|
||||
|
||||
if 1 > len(ret.Views) {
|
||||
view := &View{
|
||||
ID: ast.NewNodeID(),
|
||||
Name: "Table",
|
||||
Type: ViewTypeTable,
|
||||
Filters: []*ViewFilter{},
|
||||
Sorts: []*ViewSort{},
|
||||
}
|
||||
|
||||
view := NewView()
|
||||
ret.CurrentViewID = view.ID
|
||||
ret.Views = []*View{view}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,8 +29,6 @@ const (
|
|||
ColumnTypeDate ColumnType = "date"
|
||||
ColumnTypeSelect ColumnType = "select"
|
||||
ColumnTypeMSelect ColumnType = "mSelect"
|
||||
ColumnTypeRelation ColumnType = "relation"
|
||||
ColumnTypeRollup ColumnType = "rollup"
|
||||
)
|
||||
|
||||
// Column 描述了属性视图的基础结构。
|
||||
|
|
@ -39,15 +37,9 @@ type Column struct {
|
|||
Name string `json:"name"` // 列名
|
||||
Type ColumnType `json:"type"` // 列类型
|
||||
Icon string `json:"icon"` // 列图标
|
||||
Wrap bool `json:"wrap"` // 是否换行
|
||||
Hidden bool `json:"hidden"` // 是否隐藏
|
||||
Width string `json:"width"` // 列宽度
|
||||
Calc *ColumnCalc `json:"calc"` // 计算
|
||||
|
||||
// 以下是某些列类型的特有属性
|
||||
|
||||
AttributeViewID string `json:"attributeViewId"` // 关联的属性视图 ID
|
||||
RelationColumnID string `json:"relationColumnId"` // 目标关联列 ID
|
||||
Options []*ColumnSelectOption `json:"options"` // 选项列表
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,15 +24,31 @@ import (
|
|||
// Table 描述了表格视图的结构。
|
||||
type Table struct {
|
||||
Spec int `json:"spec"` // 视图格式版本
|
||||
ID string `json:"id"` // 视图 ID
|
||||
|
||||
ID string `json:"id"` // 表格 ID
|
||||
Name string `json:"name"` // 表格名称
|
||||
Columns []*Column `json:"columns"` // 表格列
|
||||
Rows []*Row `json:"rows"` // 表格行
|
||||
Columns []*TableColumn `json:"columns"` // 表格列
|
||||
Rows []*TableRow `json:"rows"` // 表格行
|
||||
Filters []*ViewFilter `json:"filters"` // 过滤规则
|
||||
Sorts []*ViewSort `json:"sorts"` // 排序规则
|
||||
}
|
||||
|
||||
type TableColumn struct {
|
||||
ID string `json:"id"` // 列 ID
|
||||
Name string `json:"name"` // 列名
|
||||
Type ColumnType `json:"type"` // 列类型
|
||||
Icon string `json:"icon"` // 列图标
|
||||
|
||||
Wrap bool `json:"wrap"` // 是否换行
|
||||
Hidden bool `json:"hidden"` // 是否隐藏
|
||||
Width string `json:"width"` // 列宽度
|
||||
Calc *ColumnCalc `json:"calc"` // 计算
|
||||
}
|
||||
|
||||
type TableRow struct {
|
||||
ID string `json:"id"`
|
||||
Cells []*Cell `json:"cells"`
|
||||
}
|
||||
|
||||
func (table *Table) GetType() ViewType {
|
||||
return ViewTypeTable
|
||||
}
|
||||
|
|
@ -97,7 +113,7 @@ func (table *Table) FilterRows() {
|
|||
}
|
||||
}
|
||||
|
||||
rows := []*Row{}
|
||||
rows := []*TableRow{}
|
||||
for _, row := range table.Rows {
|
||||
pass := true
|
||||
for j, index := range colIndexes {
|
||||
|
|
@ -143,7 +159,7 @@ func (table *Table) CalcCols() {
|
|||
}
|
||||
}
|
||||
|
||||
func (table *Table) calcColMSelect(col *Column, colIndex int) {
|
||||
func (table *Table) calcColMSelect(col *TableColumn, colIndex int) {
|
||||
switch col.Calc.Operator {
|
||||
case CalcOperatorCountAll:
|
||||
col.Calc.Result = &Value{Number: &ValueNumber{Content: float64(len(table.Rows))}}
|
||||
|
|
@ -204,7 +220,7 @@ func (table *Table) calcColMSelect(col *Column, colIndex int) {
|
|||
}
|
||||
}
|
||||
|
||||
func (table *Table) calcColSelect(col *Column, colIndex int) {
|
||||
func (table *Table) calcColSelect(col *TableColumn, colIndex int) {
|
||||
switch col.Calc.Operator {
|
||||
case CalcOperatorCountAll:
|
||||
col.Calc.Result = &Value{Number: &ValueNumber{Content: float64(len(table.Rows))}}
|
||||
|
|
@ -261,7 +277,7 @@ func (table *Table) calcColSelect(col *Column, colIndex int) {
|
|||
}
|
||||
}
|
||||
|
||||
func (table *Table) calcColDate(col *Column, colIndex int) {
|
||||
func (table *Table) calcColDate(col *TableColumn, colIndex int) {
|
||||
switch col.Calc.Operator {
|
||||
case CalcOperatorCountAll:
|
||||
col.Calc.Result = &Value{Number: &ValueNumber{Content: float64(len(table.Rows))}}
|
||||
|
|
@ -360,7 +376,7 @@ func (table *Table) calcColDate(col *Column, colIndex int) {
|
|||
}
|
||||
}
|
||||
|
||||
func (table *Table) calcColNumber(col *Column, colIndex int) {
|
||||
func (table *Table) calcColNumber(col *TableColumn, colIndex int) {
|
||||
switch col.Calc.Operator {
|
||||
case CalcOperatorCountAll:
|
||||
col.Calc.Result = &Value{Number: &ValueNumber{Content: float64(len(table.Rows))}}
|
||||
|
|
@ -500,7 +516,7 @@ func (table *Table) calcColNumber(col *Column, colIndex int) {
|
|||
}
|
||||
}
|
||||
|
||||
func (table *Table) calcColText(col *Column, colIndex int) {
|
||||
func (table *Table) calcColText(col *TableColumn, colIndex int) {
|
||||
switch col.Calc.Operator {
|
||||
case CalcOperatorCountAll:
|
||||
col.Calc.Result = &Value{Number: &ValueNumber{Content: float64(len(table.Rows))}}
|
||||
|
|
|
|||
|
|
@ -70,14 +70,10 @@ func RenderAttributeView(avID string) (viewable av.Viewable, attrView *av.Attrib
|
|||
}
|
||||
|
||||
func renderAttributeViewTable(attrView *av.AttributeView, view *av.View) (ret *av.Table, err error) {
|
||||
ret = &av.Table{
|
||||
Spec: attrView.Spec,
|
||||
ID: view.ID,
|
||||
Name: view.Name,
|
||||
Columns: attrView.Columns,
|
||||
Rows: attrView.Rows,
|
||||
Filters: view.Filters,
|
||||
Sorts: view.Sorts,
|
||||
ret = view.Table
|
||||
for _, avRow := range attrView.Rows {
|
||||
row := &av.TableRow{ID: avRow.ID, Cells: avRow.Cells}
|
||||
ret.Rows = append(ret.Rows, row)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
|
@ -139,7 +135,7 @@ func setAttributeViewFilters(operation *Operation) (err error) {
|
|||
return
|
||||
}
|
||||
|
||||
if err = gulu.JSON.UnmarshalJSON(data, &view.Filters); nil != err {
|
||||
if err = gulu.JSON.UnmarshalJSON(data, &view.Table.Filters); nil != err {
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -174,7 +170,7 @@ func setAttributeViewSorts(operation *Operation) (err error) {
|
|||
return
|
||||
}
|
||||
|
||||
if err = gulu.JSON.UnmarshalJSON(data, &view.Sorts); nil != err {
|
||||
if err = gulu.JSON.UnmarshalJSON(data, &view.Table.Sorts); nil != err {
|
||||
return
|
||||
}
|
||||
|
||||
|
|
@ -320,7 +316,13 @@ func setAttributeViewColWidth(operation *Operation) (err error) {
|
|||
return
|
||||
}
|
||||
|
||||
for _, column := range attrView.Columns {
|
||||
view := attrView.GetView(operation.ViewID)
|
||||
if nil == view {
|
||||
err = av.ErrViewNotFound
|
||||
return
|
||||
}
|
||||
|
||||
for _, column := range view.Table.Columns {
|
||||
if column.ID == operation.ID {
|
||||
column.Width = operation.Data.(string)
|
||||
break
|
||||
|
|
@ -345,7 +347,13 @@ func setAttributeViewColWrap(operation *Operation) (err error) {
|
|||
return
|
||||
}
|
||||
|
||||
for _, column := range attrView.Columns {
|
||||
view := attrView.GetView(operation.ViewID)
|
||||
if nil == view {
|
||||
err = av.ErrViewNotFound
|
||||
return
|
||||
}
|
||||
|
||||
for _, column := range view.Table.Columns {
|
||||
if column.ID == operation.ID {
|
||||
column.Wrap = operation.Data.(bool)
|
||||
break
|
||||
|
|
@ -370,7 +378,13 @@ func setAttributeViewColHidden(operation *Operation) (err error) {
|
|||
return
|
||||
}
|
||||
|
||||
for _, column := range attrView.Columns {
|
||||
view := attrView.GetView(operation.ViewID)
|
||||
if nil == view {
|
||||
err = av.ErrViewNotFound
|
||||
return
|
||||
}
|
||||
|
||||
for _, column := range view.Table.Columns {
|
||||
if column.ID == operation.ID {
|
||||
column.Hidden = operation.Data.(bool)
|
||||
break
|
||||
|
|
@ -467,6 +481,47 @@ func sortAttributeViewColumn(operation *Operation) (err error) {
|
|||
return
|
||||
}
|
||||
|
||||
func (tx *Transaction) doAddAttrViewColumn(operation *Operation) (ret *TxErr) {
|
||||
err := addAttributeViewColumn(operation)
|
||||
if nil != err {
|
||||
return &TxErr{code: TxErrWriteAttributeView, id: operation.ParentID, msg: err.Error()}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func addAttributeViewColumn(operation *Operation) (err error) {
|
||||
attrView, err := av.ParseAttributeView(operation.AvID)
|
||||
if nil != err {
|
||||
return
|
||||
}
|
||||
|
||||
view := attrView.GetView(operation.ViewID)
|
||||
if nil == view {
|
||||
err = av.ErrViewNotFound
|
||||
return
|
||||
}
|
||||
|
||||
colType := av.ColumnType(operation.Typ)
|
||||
switch colType {
|
||||
case av.ColumnTypeText, av.ColumnTypeNumber, av.ColumnTypeDate, av.ColumnTypeSelect, av.ColumnTypeMSelect:
|
||||
col := &av.Column{ID: ast.NewNodeID(), Name: operation.Name, Type: colType}
|
||||
attrView.Columns = append(attrView.Columns, col)
|
||||
view.Table.Columns = append(view.Table.Columns, &av.TableColumn{ID: col.ID, Name: col.Name, Type: col.Type})
|
||||
|
||||
for _, row := range attrView.Rows {
|
||||
row.Cells = append(row.Cells, av.NewCell(colType))
|
||||
}
|
||||
default:
|
||||
msg := fmt.Sprintf("invalid column type [%s]", operation.Typ)
|
||||
logging.LogErrorf(msg)
|
||||
err = errors.New(msg)
|
||||
return
|
||||
}
|
||||
|
||||
err = av.SaveAttributeView(attrView)
|
||||
return
|
||||
}
|
||||
|
||||
// TODO 下面的方法要重写
|
||||
|
||||
func (tx *Transaction) doUpdateAttrViewCell(operation *Operation) (ret *TxErr) {
|
||||
|
|
@ -558,14 +613,6 @@ func (tx *Transaction) doUpdateAttrViewColOptions(operation *Operation) (ret *Tx
|
|||
return
|
||||
}
|
||||
|
||||
func (tx *Transaction) doAddAttrViewColumn(operation *Operation) (ret *TxErr) {
|
||||
err := addAttributeViewColumn(operation.Name, operation.Typ, operation.ParentID)
|
||||
if nil != err {
|
||||
return &TxErr{code: TxErrWriteAttributeView, id: operation.ParentID, msg: err.Error()}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (tx *Transaction) doUpdateAttrViewColumn(operation *Operation) (ret *TxErr) {
|
||||
err := updateAttributeViewColumn(operation.ID, operation.Name, operation.Typ, operation.ParentID)
|
||||
if nil != err {
|
||||
|
|
@ -590,31 +637,6 @@ func (tx *Transaction) doSetAttrView(operation *Operation) (ret *TxErr) {
|
|||
return
|
||||
}
|
||||
|
||||
func addAttributeViewColumn(name string, typ string, avID string) (err error) {
|
||||
attrView, err := av.ParseAttributeView(avID)
|
||||
if nil != err {
|
||||
return
|
||||
}
|
||||
|
||||
colType := av.ColumnType(typ)
|
||||
switch colType {
|
||||
case av.ColumnTypeText, av.ColumnTypeNumber, av.ColumnTypeDate, av.ColumnTypeSelect, av.ColumnTypeMSelect:
|
||||
col := &av.Column{ID: ast.NewNodeID(), Name: name, Type: colType}
|
||||
attrView.Columns = append(attrView.Columns, col)
|
||||
for _, row := range attrView.Rows {
|
||||
row.Cells = append(row.Cells, av.NewCell(colType))
|
||||
}
|
||||
default:
|
||||
msg := fmt.Sprintf("invalid column type [%s]", typ)
|
||||
logging.LogErrorf(msg)
|
||||
err = errors.New(msg)
|
||||
return
|
||||
}
|
||||
|
||||
err = av.SaveAttributeView(attrView)
|
||||
return
|
||||
}
|
||||
|
||||
func updateAttributeViewColumn(id, name string, typ string, avID string) (err error) {
|
||||
attrView, err := av.ParseAttributeView(avID)
|
||||
if nil != err {
|
||||
|
|
|
|||
|
|
@ -237,10 +237,9 @@ func performTx(tx *Transaction) (ret *TxErr) {
|
|||
ret = tx.doInsertAttrViewBlock(op)
|
||||
case "removeAttrViewBlock":
|
||||
ret = tx.doRemoveAttrViewBlock(op)
|
||||
// TODO 下面的方法要重写
|
||||
|
||||
case "addAttrViewCol":
|
||||
ret = tx.doAddAttrViewColumn(op)
|
||||
// TODO 下面的方法要重写
|
||||
case "updateAttrViewCol":
|
||||
ret = tx.doUpdateAttrViewColumn(op)
|
||||
case "removeAttrViewCol":
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue