From 8a842c66f01201063fe9c368d054475b3f8b91a7 Mon Sep 17 00:00:00 2001 From: Daniel <845765@qq.com> Date: Sun, 30 Jul 2023 20:53:40 +0800 Subject: [PATCH] :art: Add URL type column to Attribute View https://github.com/siyuan-note/siyuan/issues/8854 --- kernel/av/av.go | 6 ++++ kernel/av/table.go | 65 ++++++++++++++++++++++++++++++++++ kernel/model/attribute_view.go | 4 +-- 3 files changed, 73 insertions(+), 2 deletions(-) diff --git a/kernel/av/av.go b/kernel/av/av.go index 7a9e4eb36..c9109d0fb 100644 --- a/kernel/av/av.go +++ b/kernel/av/av.go @@ -59,6 +59,7 @@ const ( KeyTypeDate KeyType = "date" KeyTypeSelect KeyType = "select" KeyTypeMSelect KeyType = "mSelect" + KeyTypeURL KeyType = "url" ) // Key 描述了属性视图属性列的基础结构。 @@ -97,6 +98,7 @@ type Value struct { Number *ValueNumber `json:"number,omitempty"` Date *ValueDate `json:"date,omitempty"` MSelect []*ValueSelect `json:"mSelect,omitempty"` + URL *ValueURL `json:"url,omitempty"` } func (value *Value) ToJSONString() string { @@ -222,6 +224,10 @@ type ValueSelect struct { Color string `json:"color"` } +type ValueURL struct { + Content string `json:"content"` +} + // View 描述了视图的结构。 type View struct { ID string `json:"id"` // 视图 ID diff --git a/kernel/av/table.go b/kernel/av/table.go index 82c928c31..7d430569b 100644 --- a/kernel/av/table.go +++ b/kernel/av/table.go @@ -379,6 +379,8 @@ func (table *Table) CalcCols() { table.calcColSelect(col, i) case KeyTypeMSelect: table.calcColMSelect(col, i) + case KeyTypeURL: + table.calcColURL(col, i) } } } @@ -813,6 +815,69 @@ func (table *Table) calcColText(col *TableColumn, colIndex int) { } } +func (table *Table) calcColURL(col *TableColumn, colIndex int) { + switch col.Calc.Operator { + case CalcOperatorCountAll: + col.Calc.Result = &Value{Number: NewFormattedValueNumber(float64(len(table.Rows)), NumberFormatNone)} + case CalcOperatorCountValues: + countValues := 0 + for _, row := range table.Rows { + if nil != row.Cells[colIndex] && nil != row.Cells[colIndex].Value && nil != row.Cells[colIndex].Value.URL && "" != row.Cells[colIndex].Value.URL.Content { + countValues++ + } + } + col.Calc.Result = &Value{Number: NewFormattedValueNumber(float64(countValues), NumberFormatNone)} + case CalcOperatorCountUniqueValues: + countUniqueValues := 0 + uniqueValues := map[string]bool{} + for _, row := range table.Rows { + if nil != row.Cells[colIndex] && nil != row.Cells[colIndex].Value && nil != row.Cells[colIndex].Value.URL && "" != row.Cells[colIndex].Value.URL.Content { + if !uniqueValues[row.Cells[colIndex].Value.URL.Content] { + uniqueValues[row.Cells[colIndex].Value.URL.Content] = true + countUniqueValues++ + } + } + } + col.Calc.Result = &Value{Number: NewFormattedValueNumber(float64(countUniqueValues), NumberFormatNone)} + case CalcOperatorCountEmpty: + countEmpty := 0 + for _, row := range table.Rows { + if nil == row.Cells[colIndex] || nil == row.Cells[colIndex].Value || nil == row.Cells[colIndex].Value.URL || "" == row.Cells[colIndex].Value.URL.Content { + countEmpty++ + } + } + col.Calc.Result = &Value{Number: NewFormattedValueNumber(float64(countEmpty), NumberFormatNone)} + case CalcOperatorCountNotEmpty: + countNotEmpty := 0 + for _, row := range table.Rows { + if nil != row.Cells[colIndex] && nil != row.Cells[colIndex].Value && nil != row.Cells[colIndex].Value.URL && "" != row.Cells[colIndex].Value.URL.Content { + countNotEmpty++ + } + } + col.Calc.Result = &Value{Number: NewFormattedValueNumber(float64(countNotEmpty), NumberFormatNone)} + case CalcOperatorPercentEmpty: + countEmpty := 0 + for _, row := range table.Rows { + if nil == row.Cells[colIndex] || nil == row.Cells[colIndex].Value || nil == row.Cells[colIndex].Value.URL || "" == row.Cells[colIndex].Value.URL.Content { + countEmpty++ + } + } + if 0 < len(table.Rows) { + col.Calc.Result = &Value{Number: NewFormattedValueNumber(float64(countEmpty)/float64(len(table.Rows)), NumberFormatPercent)} + } + case CalcOperatorPercentNotEmpty: + countNotEmpty := 0 + for _, row := range table.Rows { + if nil != row.Cells[colIndex] && nil != row.Cells[colIndex].Value && nil != row.Cells[colIndex].Value.URL && "" != row.Cells[colIndex].Value.URL.Content { + countNotEmpty++ + } + } + if 0 < len(table.Rows) { + col.Calc.Result = &Value{Number: NewFormattedValueNumber(float64(countNotEmpty)/float64(len(table.Rows)), NumberFormatPercent)} + } + } +} + func (table *Table) calcColBlock(col *TableColumn, colIndex int) { switch col.Calc.Operator { case CalcOperatorCountAll: diff --git a/kernel/model/attribute_view.go b/kernel/model/attribute_view.go index ff587ae33..74adc59e8 100644 --- a/kernel/model/attribute_view.go +++ b/kernel/model/attribute_view.go @@ -711,7 +711,7 @@ func addAttributeViewColumn(operation *Operation) (err error) { keyType := av.KeyType(operation.Typ) switch keyType { - case av.KeyTypeText, av.KeyTypeNumber, av.KeyTypeDate, av.KeyTypeSelect, av.KeyTypeMSelect: + case av.KeyTypeText, av.KeyTypeNumber, av.KeyTypeDate, av.KeyTypeSelect, av.KeyTypeMSelect, av.KeyTypeURL: key := av.NewKey(operation.ID, operation.Name, keyType) attrView.KeyValues = append(attrView.KeyValues, &av.KeyValues{Key: key}) @@ -741,7 +741,7 @@ func updateAttributeViewColumn(operation *Operation) (err error) { colType := av.KeyType(operation.Typ) switch colType { - case av.KeyTypeText, av.KeyTypeNumber, av.KeyTypeDate, av.KeyTypeSelect, av.KeyTypeMSelect: + case av.KeyTypeText, av.KeyTypeNumber, av.KeyTypeDate, av.KeyTypeSelect, av.KeyTypeMSelect, av.KeyTypeURL: for _, keyValues := range attrView.KeyValues { if keyValues.Key.ID == operation.ID { keyValues.Key.Name = operation.Name