🎨 Improve adding row prompt when database filter exists https://github.com/siyuan-note/siyuan/issues/10517

Improve adding row prompt when database sort exists https://github.com/siyuan-note/siyuan/issues/10525
This commit is contained in:
Daniel 2024-03-06 11:20:20 +08:00
parent 1848f5aae0
commit b134313b16
No known key found for this signature in database
GPG key ID: 86211BA83DF03017
4 changed files with 169 additions and 53 deletions

View file

@ -17,8 +17,6 @@
package av package av
import ( import (
"strings"
"github.com/siyuan-note/siyuan/kernel/util" "github.com/siyuan-note/siyuan/kernel/util"
) )
@ -77,7 +75,7 @@ const (
FilterOperatorIsFalse FilterOperator = "Is false" FilterOperatorIsFalse FilterOperator = "Is false"
) )
func (filter *ViewFilter) GetAffectValue(key *Key) (ret *Value) { func (filter *ViewFilter) GetAffectValue(key *Key, defaultVal *Value) (ret *Value) {
if nil != filter.Value { if nil != filter.Value {
if filter.Value.IsGenerated() { if filter.Value.IsGenerated() {
// 自动生成类型的过滤条件不设置默认值 // 自动生成类型的过滤条件不设置默认值
@ -99,17 +97,29 @@ func (filter *ViewFilter) GetAffectValue(key *Key) (ret *Value) {
} }
ret = filter.Value.Clone() ret = filter.Value.Clone()
if nil != defaultVal {
// 如果有默认值则优先使用默认值
clonedDefaultVal := defaultVal.Clone()
defaultRawVal := clonedDefaultVal.GetValByType(filter.Value.Type)
if nil != defaultRawVal {
ret.SetValByType(filter.Value.Type, defaultRawVal)
return
}
}
// 没有默认值则使用过滤条件的值
switch filter.Value.Type { switch filter.Value.Type {
case KeyTypeBlock: case KeyTypeBlock:
switch filter.Operator { switch filter.Operator {
case FilterOperatorIsEqual: case FilterOperatorIsEqual:
ret.Block = &ValueBlock{ID: filter.Value.Block.ID, Content: filter.Value.Block.Content} ret.Block = &ValueBlock{ID: filter.Value.Block.ID, Content: filter.Value.Block.Content}
case FilterOperatorIsNotEqual: case FilterOperatorIsNotEqual:
ret.Block = &ValueBlock{ID: filter.Value.Block.ID, Content: strings.TrimSpace(filter.Value.Block.Content + " Untitled")} ret.Block = &ValueBlock{ID: filter.Value.Block.ID, Content: ""}
case FilterOperatorContains: case FilterOperatorContains:
ret.Block = &ValueBlock{ID: filter.Value.Block.ID, Content: filter.Value.Block.Content} ret.Block = &ValueBlock{ID: filter.Value.Block.ID, Content: filter.Value.Block.Content}
case FilterOperatorDoesNotContain: case FilterOperatorDoesNotContain:
ret.Block = &ValueBlock{ID: filter.Value.Block.ID, Content: strings.ReplaceAll("Untitled", filter.Value.Block.Content, "")} ret.Block = &ValueBlock{ID: filter.Value.Block.ID, Content: ""}
case FilterOperatorStartsWith: case FilterOperatorStartsWith:
ret.Block = &ValueBlock{ID: filter.Value.Block.ID, Content: filter.Value.Block.Content} ret.Block = &ValueBlock{ID: filter.Value.Block.ID, Content: filter.Value.Block.Content}
case FilterOperatorEndsWith: case FilterOperatorEndsWith:
@ -117,18 +127,18 @@ func (filter *ViewFilter) GetAffectValue(key *Key) (ret *Value) {
case FilterOperatorIsEmpty: case FilterOperatorIsEmpty:
ret.Block = &ValueBlock{ID: filter.Value.Block.ID, Content: ""} ret.Block = &ValueBlock{ID: filter.Value.Block.ID, Content: ""}
case FilterOperatorIsNotEmpty: case FilterOperatorIsNotEmpty:
ret.Block = &ValueBlock{ID: filter.Value.Block.ID, Content: "Untitled"} ret.Block = &ValueBlock{ID: filter.Value.Block.ID, Content: ""}
} }
case KeyTypeText: case KeyTypeText:
switch filter.Operator { switch filter.Operator {
case FilterOperatorIsEqual: case FilterOperatorIsEqual:
ret.Text = &ValueText{Content: filter.Value.Text.Content} ret.Text = &ValueText{Content: filter.Value.Text.Content}
case FilterOperatorIsNotEqual: case FilterOperatorIsNotEqual:
ret.Text = &ValueText{Content: strings.TrimSpace(filter.Value.Text.Content + " Untitled")} ret.Text = &ValueText{Content: ""}
case FilterOperatorContains: case FilterOperatorContains:
ret.Text = &ValueText{Content: filter.Value.Text.Content} ret.Text = &ValueText{Content: filter.Value.Text.Content}
case FilterOperatorDoesNotContain: case FilterOperatorDoesNotContain:
ret.Text = &ValueText{Content: strings.ReplaceAll("Untitled", filter.Value.Text.Content, "")} ret.Text = &ValueText{Content: ""}
case FilterOperatorStartsWith: case FilterOperatorStartsWith:
ret.Text = &ValueText{Content: filter.Value.Text.Content} ret.Text = &ValueText{Content: filter.Value.Text.Content}
case FilterOperatorEndsWith: case FilterOperatorEndsWith:
@ -136,7 +146,7 @@ func (filter *ViewFilter) GetAffectValue(key *Key) (ret *Value) {
case FilterOperatorIsEmpty: case FilterOperatorIsEmpty:
ret.Text = &ValueText{Content: ""} ret.Text = &ValueText{Content: ""}
case FilterOperatorIsNotEmpty: case FilterOperatorIsNotEmpty:
ret.Text = &ValueText{Content: "Untitled"} ret.Text = &ValueText{Content: ""}
} }
case KeyTypeNumber: case KeyTypeNumber:
switch filter.Operator { switch filter.Operator {
@ -182,32 +192,21 @@ func (filter *ViewFilter) GetAffectValue(key *Key) (ret *Value) {
case FilterOperatorIsNotEmpty: case FilterOperatorIsNotEmpty:
ret.Date = &ValueDate{Content: util.CurrentTimeMillis(), IsNotEmpty: true} ret.Date = &ValueDate{Content: util.CurrentTimeMillis(), IsNotEmpty: true}
} }
case KeyTypeSelect: case KeyTypeSelect, KeyTypeMSelect:
switch filter.Operator { switch filter.Operator {
case FilterOperatorIsEqual: case FilterOperatorIsEqual:
if 0 < len(filter.Value.MSelect) { valueSelect := &ValueSelect{Content: "", Color: "1"}
ret.MSelect = []*ValueSelect{{Content: filter.Value.MSelect[0].Content, Color: filter.Value.MSelect[0].Color}} if 0 < len(key.Options) {
valueSelect.Color = key.Options[0].Color
} }
if 0 < len(filter.Value.MSelect) {
valueSelect.Content = filter.Value.MSelect[0].Content
valueSelect.Color = filter.Value.MSelect[0].Color
}
ret.MSelect = []*ValueSelect{valueSelect}
case FilterOperatorIsNotEqual: case FilterOperatorIsNotEqual:
if 0 < len(filter.Value.MSelect) { if 0 < len(filter.Value.MSelect) {
ret.MSelect = []*ValueSelect{{Content: filter.Value.MSelect[0].Content + " Untitled", Color: "1"}} ret.MSelect = []*ValueSelect{}
}
case FilterOperatorIsEmpty:
ret.MSelect = []*ValueSelect{}
case FilterOperatorIsNotEmpty:
if 0 < len(key.Options) {
ret.MSelect = []*ValueSelect{{Content: key.Options[0].Name, Color: key.Options[0].Color}}
}
}
case KeyTypeMSelect:
switch filter.Operator {
case FilterOperatorIsEqual, FilterOperatorContains:
if 0 < len(filter.Value.MSelect) {
ret.MSelect = []*ValueSelect{{Content: filter.Value.MSelect[0].Content, Color: filter.Value.MSelect[0].Color}}
}
case FilterOperatorIsNotEqual, FilterOperatorDoesNotContain:
if 0 < len(filter.Value.MSelect) {
ret.MSelect = []*ValueSelect{{Content: filter.Value.MSelect[0].Content + " Untitled", Color: "1"}}
} }
case FilterOperatorIsEmpty: case FilterOperatorIsEmpty:
ret.MSelect = []*ValueSelect{} ret.MSelect = []*ValueSelect{}
@ -221,30 +220,30 @@ func (filter *ViewFilter) GetAffectValue(key *Key) (ret *Value) {
case FilterOperatorIsEqual: case FilterOperatorIsEqual:
ret.URL = &ValueURL{Content: filter.Value.URL.Content} ret.URL = &ValueURL{Content: filter.Value.URL.Content}
case FilterOperatorIsNotEqual: case FilterOperatorIsNotEqual:
ret.URL = &ValueURL{Content: filter.Value.URL.Content + " Untitled"} ret.URL = &ValueURL{Content: filter.Value.URL.Content}
case FilterOperatorContains: case FilterOperatorContains:
ret.URL = &ValueURL{Content: filter.Value.URL.Content} ret.URL = &ValueURL{Content: filter.Value.URL.Content}
case FilterOperatorDoesNotContain: case FilterOperatorDoesNotContain:
ret.URL = &ValueURL{Content: strings.ReplaceAll("Untitled", filter.Value.URL.Content, "")} ret.URL = &ValueURL{Content: ""}
case FilterOperatorStartsWith: case FilterOperatorStartsWith:
ret.URL = &ValueURL{Content: filter.Value.URL.Content} ret.URL = &ValueURL{Content: filter.Value.URL.Content}
case FilterOperatorEndsWith: case FilterOperatorEndsWith:
ret.URL = &ValueURL{Content: filter.Value.URL.Content} ret.URL = &ValueURL{Content: filter.Value.URL.Content}
case FilterOperatorIsEmpty: case FilterOperatorIsEmpty:
ret.URL = &ValueURL{Content: ""} ret.URL = &ValueURL{}
case FilterOperatorIsNotEmpty: case FilterOperatorIsNotEmpty:
ret.URL = &ValueURL{Content: "Untitled"} ret.URL = &ValueURL{}
} }
case KeyTypeEmail: case KeyTypeEmail:
switch filter.Operator { switch filter.Operator {
case FilterOperatorIsEqual: case FilterOperatorIsEqual:
ret.Email = &ValueEmail{Content: filter.Value.Email.Content} ret.Email = &ValueEmail{Content: filter.Value.Email.Content}
case FilterOperatorIsNotEqual: case FilterOperatorIsNotEqual:
ret.Email = &ValueEmail{Content: filter.Value.Email.Content + " Untitled"} ret.Email = &ValueEmail{Content: filter.Value.Email.Content}
case FilterOperatorContains: case FilterOperatorContains:
ret.Email = &ValueEmail{Content: filter.Value.Email.Content} ret.Email = &ValueEmail{Content: filter.Value.Email.Content}
case FilterOperatorDoesNotContain: case FilterOperatorDoesNotContain:
ret.Email = &ValueEmail{Content: strings.ReplaceAll("Untitled", filter.Value.Email.Content, "")} ret.Email = &ValueEmail{Content: ""}
case FilterOperatorStartsWith: case FilterOperatorStartsWith:
ret.Email = &ValueEmail{Content: filter.Value.Email.Content} ret.Email = &ValueEmail{Content: filter.Value.Email.Content}
case FilterOperatorEndsWith: case FilterOperatorEndsWith:
@ -252,18 +251,18 @@ func (filter *ViewFilter) GetAffectValue(key *Key) (ret *Value) {
case FilterOperatorIsEmpty: case FilterOperatorIsEmpty:
ret.Email = &ValueEmail{Content: ""} ret.Email = &ValueEmail{Content: ""}
case FilterOperatorIsNotEmpty: case FilterOperatorIsNotEmpty:
ret.Email = &ValueEmail{Content: "Untitled"} ret.Email = &ValueEmail{Content: ""}
} }
case KeyTypePhone: case KeyTypePhone:
switch filter.Operator { switch filter.Operator {
case FilterOperatorIsEqual: case FilterOperatorIsEqual:
ret.Phone = &ValuePhone{Content: filter.Value.Phone.Content} ret.Phone = &ValuePhone{Content: filter.Value.Phone.Content}
case FilterOperatorIsNotEqual: case FilterOperatorIsNotEqual:
ret.Phone = &ValuePhone{Content: filter.Value.Phone.Content + " Untitled"} ret.Phone = &ValuePhone{Content: filter.Value.Phone.Content + ""}
case FilterOperatorContains: case FilterOperatorContains:
ret.Phone = &ValuePhone{Content: filter.Value.Phone.Content} ret.Phone = &ValuePhone{Content: filter.Value.Phone.Content}
case FilterOperatorDoesNotContain: case FilterOperatorDoesNotContain:
ret.Phone = &ValuePhone{Content: strings.ReplaceAll("Untitled", filter.Value.Phone.Content, "")} ret.Phone = &ValuePhone{Content: ""}
case FilterOperatorStartsWith: case FilterOperatorStartsWith:
ret.Phone = &ValuePhone{Content: filter.Value.Phone.Content} ret.Phone = &ValuePhone{Content: filter.Value.Phone.Content}
case FilterOperatorEndsWith: case FilterOperatorEndsWith:
@ -271,7 +270,7 @@ func (filter *ViewFilter) GetAffectValue(key *Key) (ret *Value) {
case FilterOperatorIsEmpty: case FilterOperatorIsEmpty:
ret.Phone = &ValuePhone{Content: ""} ret.Phone = &ValuePhone{Content: ""}
case FilterOperatorIsNotEmpty: case FilterOperatorIsNotEmpty:
ret.Phone = &ValuePhone{Content: "Untitled"} ret.Phone = &ValuePhone{Content: ""}
} }
case KeyTypeMAsset: case KeyTypeMAsset:
switch filter.Operator { switch filter.Operator {

View file

@ -921,6 +921,16 @@ func (row *TableRow) GetBlockValue() (ret *Value) {
return return
} }
func (row *TableRow) GetValue(keyID string) (ret *Value) {
for _, cell := range row.Cells {
if nil != cell.Value && keyID == cell.Value.KeyID {
ret = cell.Value
break
}
}
return
}
func (table *Table) GetType() LayoutType { func (table *Table) GetType() LayoutType {
return LayoutTypeTable return LayoutTypeTable
} }

View file

@ -276,10 +276,84 @@ func (value *Value) IsEmpty() bool {
case KeyTypeRollup: case KeyTypeRollup:
return 1 > len(value.Rollup.Contents) return 1 > len(value.Rollup.Contents)
} }
return false return false
} }
func (value *Value) SetValByType(typ KeyType, val interface{}) {
switch typ {
case KeyTypeBlock:
value.Block = val.(*ValueBlock)
case KeyTypeText:
value.Text = val.(*ValueText)
case KeyTypeNumber:
value.Number = val.(*ValueNumber)
case KeyTypeDate:
value.Date = val.(*ValueDate)
case KeyTypeSelect:
value.MSelect = val.([]*ValueSelect)
case KeyTypeMSelect:
value.MSelect = val.([]*ValueSelect)
case KeyTypeURL:
value.URL = val.(*ValueURL)
case KeyTypeEmail:
value.Email = val.(*ValueEmail)
case KeyTypePhone:
value.Phone = val.(*ValuePhone)
case KeyTypeMAsset:
value.MAsset = val.([]*ValueAsset)
case KeyTypeTemplate:
value.Template = val.(*ValueTemplate)
case KeyTypeCreated:
value.Created = val.(*ValueCreated)
case KeyTypeUpdated:
value.Updated = val.(*ValueUpdated)
case KeyTypeCheckbox:
value.Checkbox = val.(*ValueCheckbox)
case KeyTypeRelation:
value.Relation = val.(*ValueRelation)
case KeyTypeRollup:
value.Rollup = val.(*ValueRollup)
}
}
func (value *Value) GetValByType(typ KeyType) (ret interface{}) {
switch typ {
case KeyTypeBlock:
return value.Block
case KeyTypeText:
return value.Text
case KeyTypeNumber:
return value.Number
case KeyTypeDate:
return value.Date
case KeyTypeSelect:
return value.MSelect
case KeyTypeMSelect:
return value.MSelect
case KeyTypeURL:
return value.URL
case KeyTypeEmail:
return value.Email
case KeyTypePhone:
return value.Phone
case KeyTypeMAsset:
return value.MAsset
case KeyTypeTemplate:
return value.Template
case KeyTypeCreated:
return value.Created
case KeyTypeUpdated:
return value.Updated
case KeyTypeCheckbox:
return value.Checkbox
case KeyTypeRelation:
return value.Relation
case KeyTypeRollup:
return value.Rollup
}
return
}
type ValueBlock struct { type ValueBlock struct {
ID string `json:"id"` ID string `json:"id"`
Content string `json:"content"` Content string `json:"content"`

View file

@ -1854,22 +1854,55 @@ func addAttributeViewBlock(avID, blockID, previousBlockID, addingBlockID string,
viewable, _ := renderAttributeViewTable(attrView, view) viewable, _ := renderAttributeViewTable(attrView, view)
viewable.FilterRows(attrView) viewable.FilterRows(attrView)
for _, filter := range view.Table.Filters { sameKeyFilterSort := false // 是否在同一个字段上同时存在过滤和排序
for _, keyValues := range attrView.KeyValues { var lastRow *av.TableRow
if keyValues.Key.ID == filter.Column { if 0 < len(viewable.Sorts) {
newValue := filter.GetAffectValue(keyValues.Key) viewable.SortRows()
if nil == newValue { if 0 < len(viewable.Rows) {
continue lastRow = viewable.Rows[len(viewable.Rows)-1]
} }
newValue.ID = ast.NewNodeID()
newValue.KeyID = keyValues.Key.ID filterKeys, sortKeys := map[string]bool{}, map[string]bool{}
newValue.BlockID = addingBlockID for _, filter := range view.Table.Filters {
newValue.IsDetached = isDetached filterKeys[filter.Column] = true
keyValues.Values = append(keyValues.Values, newValue) }
for _, sort := range view.Table.Sorts {
sortKeys[sort.Column] = true
}
for key := range filterKeys {
if sortKeys[key] {
sameKeyFilterSort = true
break break
} }
} }
} }
if !sameKeyFilterSort {
// 如果在同一个字段上仅存在过滤条件,则将过滤条件应用到新添加的块上
for _, filter := range view.Table.Filters {
for _, keyValues := range attrView.KeyValues {
if keyValues.Key.ID == filter.Column {
var defaultVal *av.Value
if nil != lastRow {
defaultVal = lastRow.GetValue(filter.Column)
}
newValue := filter.GetAffectValue(keyValues.Key, defaultVal)
if nil == newValue {
continue
}
newValue.ID = ast.NewNodeID()
newValue.KeyID = keyValues.Key.ID
newValue.BlockID = addingBlockID
newValue.IsDetached = isDetached
keyValues.Values = append(keyValues.Values, newValue)
break
}
}
}
}
} }
if !isDetached { if !isDetached {