Prechádzať zdrojové kódy

:art: Add template type column to Attribute View https://github.com/siyuan-note/siyuan/issues/8766

Daniel 1 rok pred
rodič
commit
c0424caf67
3 zmenil súbory, kde vykonal 95 pridanie a 21 odobranie
  1. 28 19
      kernel/av/av.go
  2. 65 0
      kernel/av/table.go
  3. 2 2
      kernel/model/attribute_view.go

+ 28 - 19
kernel/av/av.go

@@ -55,16 +55,17 @@ type KeyValues struct {
 type KeyType string
 
 const (
-	KeyTypeBlock   KeyType = "block"
-	KeyTypeText    KeyType = "text"
-	KeyTypeNumber  KeyType = "number"
-	KeyTypeDate    KeyType = "date"
-	KeyTypeSelect  KeyType = "select"
-	KeyTypeMSelect KeyType = "mSelect"
-	KeyTypeURL     KeyType = "url"
-	KeyTypeEmail   KeyType = "email"
-	KeyTypePhone   KeyType = "phone"
-	KeyTypeMAsset  KeyType = "mAsset"
+	KeyTypeBlock    KeyType = "block"
+	KeyTypeText     KeyType = "text"
+	KeyTypeNumber   KeyType = "number"
+	KeyTypeDate     KeyType = "date"
+	KeyTypeSelect   KeyType = "select"
+	KeyTypeMSelect  KeyType = "mSelect"
+	KeyTypeURL      KeyType = "url"
+	KeyTypeEmail    KeyType = "email"
+	KeyTypePhone    KeyType = "phone"
+	KeyTypeMAsset   KeyType = "mAsset"
+	KeyTypeTemplate KeyType = "template"
 )
 
 // Key 描述了属性视图属性列的基础结构。
@@ -100,15 +101,16 @@ type Value struct {
 	Type       KeyType `json:"type,omitempty"`
 	IsDetached bool    `json:"isDetached,omitempty"`
 
-	Block   *ValueBlock    `json:"block,omitempty"`
-	Text    *ValueText     `json:"text,omitempty"`
-	Number  *ValueNumber   `json:"number,omitempty"`
-	Date    *ValueDate     `json:"date,omitempty"`
-	MSelect []*ValueSelect `json:"mSelect,omitempty"`
-	URL     *ValueURL      `json:"url,omitempty"`
-	Email   *ValueEmail    `json:"email,omitempty"`
-	Phone   *ValuePhone    `json:"phone,omitempty"`
-	MAsset  []*ValueAsset  `json:"mAsset,omitempty"`
+	Block    *ValueBlock    `json:"block,omitempty"`
+	Text     *ValueText     `json:"text,omitempty"`
+	Number   *ValueNumber   `json:"number,omitempty"`
+	Date     *ValueDate     `json:"date,omitempty"`
+	MSelect  []*ValueSelect `json:"mSelect,omitempty"`
+	URL      *ValueURL      `json:"url,omitempty"`
+	Email    *ValueEmail    `json:"email,omitempty"`
+	Phone    *ValuePhone    `json:"phone,omitempty"`
+	MAsset   []*ValueAsset  `json:"mAsset,omitempty"`
+	Template *ValueTemplate `json:"template,omitempty"`
 }
 
 func (value *Value) String() string {
@@ -139,6 +141,8 @@ func (value *Value) String() string {
 			ret = append(ret, v.Content)
 		}
 		return strings.Join(ret, " ")
+	case KeyTypeTemplate:
+		return value.Template.RenderedContent
 	default:
 		return ""
 	}
@@ -345,6 +349,11 @@ type ValueAsset struct {
 	Content string    `json:"content"`
 }
 
+type ValueTemplate struct {
+	Content         string `json:"content"`
+	RenderedContent string `json:"renderedContent"`
+}
+
 // View 描述了视图的结构。
 type View struct {
 	ID   string `json:"id"`   // 视图 ID

+ 65 - 0
kernel/av/table.go

@@ -509,6 +509,71 @@ func (table *Table) CalcCols() {
 			table.calcColPhone(col, i)
 		case KeyTypeMAsset:
 			table.calcColMAsset(col, i)
+		case KeyTypeTemplate:
+			table.calcColTemplate(col, i)
+		}
+	}
+}
+
+func (table *Table) calcColTemplate(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.Template && "" != row.Cells[colIndex].Value.Template.RenderedContent {
+				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.Template && "" != row.Cells[colIndex].Value.Template.RenderedContent {
+				if !uniqueValues[row.Cells[colIndex].Value.Template.RenderedContent] {
+					uniqueValues[row.Cells[colIndex].Value.Template.RenderedContent] = 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.Template || "" == row.Cells[colIndex].Value.Template.RenderedContent {
+				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.Template && "" != row.Cells[colIndex].Value.Template.RenderedContent {
+				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.Template || "" == row.Cells[colIndex].Value.Template.RenderedContent {
+				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.Template && "" != row.Cells[colIndex].Value.Template.RenderedContent {
+				countNotEmpty++
+			}
+		}
+		if 0 < len(table.Rows) {
+			col.Calc.Result = &Value{Number: NewFormattedValueNumber(float64(countNotEmpty)/float64(len(table.Rows)), NumberFormatPercent)}
 		}
 	}
 }

+ 2 - 2
kernel/model/attribute_view.go

@@ -788,7 +788,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, av.KeyTypeURL, av.KeyTypeEmail, av.KeyTypePhone, av.KeyTypeMAsset:
+	case av.KeyTypeText, av.KeyTypeNumber, av.KeyTypeDate, av.KeyTypeSelect, av.KeyTypeMSelect, av.KeyTypeURL, av.KeyTypeEmail, av.KeyTypePhone, av.KeyTypeMAsset, av.KeyTypeTemplate:
 		key := av.NewKey(operation.ID, operation.Name, keyType)
 		attrView.KeyValues = append(attrView.KeyValues, &av.KeyValues{Key: key})
 
@@ -847,7 +847,7 @@ func updateAttributeViewColumn(operation *Operation) (err error) {
 
 	colType := av.KeyType(operation.Typ)
 	switch colType {
-	case av.KeyTypeBlock, av.KeyTypeText, av.KeyTypeNumber, av.KeyTypeDate, av.KeyTypeSelect, av.KeyTypeMSelect, av.KeyTypeURL, av.KeyTypeEmail, av.KeyTypePhone, av.KeyTypeMAsset:
+	case av.KeyTypeBlock, av.KeyTypeText, av.KeyTypeNumber, av.KeyTypeDate, av.KeyTypeSelect, av.KeyTypeMSelect, av.KeyTypeURL, av.KeyTypeEmail, av.KeyTypePhone, av.KeyTypeMAsset, av.KeyTypeTemplate:
 		for _, keyValues := range attrView.KeyValues {
 			if keyValues.Key.ID == operation.ID {
 				keyValues.Key.Name = operation.Name