mirror of
https://github.com/siyuan-note/siyuan.git
synced 2025-05-15 08:30:42 +08:00
Merge remote-tracking branch 'origin/dev' into dev
This commit is contained in:
commit
f404d7fe85
@ -169,6 +169,8 @@ func (value *Value) ToJSONString() string {
|
|||||||
type ValueBlock struct {
|
type ValueBlock struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
Content string `json:"content"`
|
Content string `json:"content"`
|
||||||
|
Created int64 `json:"created"`
|
||||||
|
Updated int64 `json:"updated"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type ValueText struct {
|
type ValueText struct {
|
||||||
@ -510,6 +512,28 @@ func ParseAttributeView(avID string) (ret *AttributeView, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func SaveAttributeView(av *AttributeView) (err error) {
|
func SaveAttributeView(av *AttributeView) (err error) {
|
||||||
|
// 做一些数据兼容处理
|
||||||
|
now := util.CurrentTimeMillis()
|
||||||
|
for _, kv := range av.KeyValues {
|
||||||
|
if KeyTypeBlock == kv.Key.Type {
|
||||||
|
// 补全 block 的创建时间和更新时间
|
||||||
|
for _, v := range kv.Values {
|
||||||
|
if 0 == v.Block.Created {
|
||||||
|
createdStr := v.Block.ID[:len("20060102150405")]
|
||||||
|
created, parseErr := time.ParseInLocation("20060102150405", createdStr, time.Local)
|
||||||
|
if nil == parseErr {
|
||||||
|
v.Block.Created = created.UnixMilli()
|
||||||
|
} else {
|
||||||
|
v.Block.Created = now
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if 0 == v.Block.Updated {
|
||||||
|
v.Block.Updated = now
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
data, err := gulu.JSON.MarshalIndentJSON(av, "", "\t") // TODO: single-line for production
|
data, err := gulu.JSON.MarshalIndentJSON(av, "", "\t") // TODO: single-line for production
|
||||||
if nil != err {
|
if nil != err {
|
||||||
logging.LogErrorf("marshal attribute view [%s] failed: %s", av.ID, err)
|
logging.LogErrorf("marshal attribute view [%s] failed: %s", av.ID, err)
|
||||||
|
@ -40,6 +40,15 @@ type BlockAttributeViewKeys struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func renderTemplateCol(ial map[string]string, tplContent string, rowValues []*av.KeyValues) string {
|
func renderTemplateCol(ial map[string]string, tplContent string, rowValues []*av.KeyValues) string {
|
||||||
|
if "" == ial["id"] {
|
||||||
|
block := getRowBlockValue(rowValues)
|
||||||
|
ial["id"] = block.Block.ID
|
||||||
|
}
|
||||||
|
if "" == ial["updated"] {
|
||||||
|
block := getRowBlockValue(rowValues)
|
||||||
|
ial["updated"] = time.UnixMilli(block.Block.Updated).Format("20060102150405")
|
||||||
|
}
|
||||||
|
|
||||||
funcMap := sprig.TxtFuncMap()
|
funcMap := sprig.TxtFuncMap()
|
||||||
goTpl := template.New("").Delims(".action{", "}")
|
goTpl := template.New("").Delims(".action{", "}")
|
||||||
tplContent = strings.ReplaceAll(tplContent, ".custom-", ".custom_") // 模板中的属性名不允许包含 - 字符,因此这里需要替换
|
tplContent = strings.ReplaceAll(tplContent, ".custom-", ".custom_") // 模板中的属性名不允许包含 - 字符,因此这里需要替换
|
||||||
@ -71,7 +80,6 @@ func renderTemplateCol(ial map[string]string, tplContent string, rowValues []*av
|
|||||||
if nil == parseErr {
|
if nil == parseErr {
|
||||||
dataModel["updated"] = updated
|
dataModel["updated"] = updated
|
||||||
} else {
|
} else {
|
||||||
logging.LogWarnf("parse updated [%s] failed: %s", updatedStr, parseErr)
|
|
||||||
dataModel["updated"] = time.Now()
|
dataModel["updated"] = time.Now()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -142,13 +150,9 @@ func GetBlockAttributeViewKeys(blockID string) (ret []*BlockAttributeViewKeys) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 渲染自动生成的列值,比如模板列、创建时间列和更新时间列
|
// 渲染自动生成的列值,比如模板列、创建时间列和更新时间列
|
||||||
|
// 先处理创建时间和更新时间
|
||||||
for _, kv := range keyValues {
|
for _, kv := range keyValues {
|
||||||
switch kv.Key.Type {
|
switch kv.Key.Type {
|
||||||
case av.KeyTypeTemplate:
|
|
||||||
if 0 < len(kv.Values) {
|
|
||||||
ial := GetBlockAttrs(blockID)
|
|
||||||
kv.Values[0].Template.Content = renderTemplateCol(ial, kv.Key.Template, keyValues)
|
|
||||||
}
|
|
||||||
case av.KeyTypeCreated:
|
case av.KeyTypeCreated:
|
||||||
createdStr := blockID[:len("20060102150405")]
|
createdStr := blockID[:len("20060102150405")]
|
||||||
created, parseErr := time.ParseInLocation("20060102150405", createdStr, time.Local)
|
created, parseErr := time.ParseInLocation("20060102150405", createdStr, time.Local)
|
||||||
@ -172,6 +176,16 @@ func GetBlockAttributeViewKeys(blockID string) (ret []*BlockAttributeViewKeys) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 再处理模板列
|
||||||
|
for _, kv := range keyValues {
|
||||||
|
switch kv.Key.Type {
|
||||||
|
case av.KeyTypeTemplate:
|
||||||
|
if 0 < len(kv.Values) {
|
||||||
|
ial := GetBlockAttrs(blockID)
|
||||||
|
kv.Values[0].Template.Content = renderTemplateCol(ial, kv.Key.Template, keyValues)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Attribute Panel - Database sort attributes by view column order https://github.com/siyuan-note/siyuan/issues/9319
|
// Attribute Panel - Database sort attributes by view column order https://github.com/siyuan-note/siyuan/issues/9319
|
||||||
view, _ := attrView.GetView()
|
view, _ := attrView.GetView()
|
||||||
@ -229,6 +243,28 @@ func RenderAttributeView(avID string) (viewable av.Viewable, attrView *av.Attrib
|
|||||||
view = attrView.Views[0]
|
view = attrView.Views[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 做一些数据兼容处理,保存的时候也会做 av.SaveAttributeView()
|
||||||
|
now := util.CurrentTimeMillis()
|
||||||
|
for _, kv := range attrView.KeyValues {
|
||||||
|
switch kv.Key.Type {
|
||||||
|
case av.KeyTypeBlock: // 补全 block 的创建时间和更新时间
|
||||||
|
for _, v := range kv.Values {
|
||||||
|
if 0 == v.Block.Created {
|
||||||
|
createdStr := v.Block.ID[:len("20060102150405")]
|
||||||
|
created, parseErr := time.ParseInLocation("20060102150405", createdStr, time.Local)
|
||||||
|
if nil == parseErr {
|
||||||
|
v.Block.Created = created.UnixMilli()
|
||||||
|
} else {
|
||||||
|
v.Block.Created = now
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if 0 == v.Block.Updated {
|
||||||
|
v.Block.Updated = now
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch view.LayoutType {
|
switch view.LayoutType {
|
||||||
case av.LayoutTypeTable:
|
case av.LayoutTypeTable:
|
||||||
// 列删除以后需要删除设置的过滤和排序
|
// 列删除以后需要删除设置的过滤和排序
|
||||||
@ -393,12 +429,18 @@ func renderAttributeViewTable(attrView *av.AttributeView, view *av.View) (ret *a
|
|||||||
case av.KeyTypeUpdated: // 渲染更新时间
|
case av.KeyTypeUpdated: // 渲染更新时间
|
||||||
ial := GetBlockAttrs(row.ID)
|
ial := GetBlockAttrs(row.ID)
|
||||||
updatedStr := ial["updated"]
|
updatedStr := ial["updated"]
|
||||||
updated, parseErr := time.ParseInLocation("20060102150405", updatedStr, time.Local)
|
if "" == updatedStr {
|
||||||
if nil == parseErr {
|
block := getTableRowBlockValue(row)
|
||||||
cell.Value.Updated = av.NewFormattedValueUpdated(updated.UnixMilli(), 0, av.UpdatedFormatNone)
|
cell.Value.Updated = av.NewFormattedValueUpdated(block.Block.Updated, 0, av.UpdatedFormatNone)
|
||||||
cell.Value.Updated.IsNotEmpty = true
|
cell.Value.Updated.IsNotEmpty = true
|
||||||
} else {
|
} else {
|
||||||
cell.Value.Updated = av.NewFormattedValueUpdated(time.Now().UnixMilli(), 0, av.UpdatedFormatNone)
|
updated, parseErr := time.ParseInLocation("20060102150405", updatedStr, time.Local)
|
||||||
|
if nil == parseErr {
|
||||||
|
cell.Value.Updated = av.NewFormattedValueUpdated(updated.UnixMilli(), 0, av.UpdatedFormatNone)
|
||||||
|
cell.Value.Updated.IsNotEmpty = true
|
||||||
|
} else {
|
||||||
|
cell.Value.Updated = av.NewFormattedValueUpdated(time.Now().UnixMilli(), 0, av.UpdatedFormatNone)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -433,6 +475,16 @@ func getRowBlockValue(keyValues []*av.KeyValues) (ret *av.Value) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getTableRowBlockValue(row *av.TableRow) (ret *av.Value) {
|
||||||
|
for _, cell := range row.Cells {
|
||||||
|
if av.KeyTypeBlock == cell.ValueType {
|
||||||
|
ret = cell.Value
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
func (tx *Transaction) doSetAttrViewName(operation *Operation) (ret *TxErr) {
|
func (tx *Transaction) doSetAttrViewName(operation *Operation) (ret *TxErr) {
|
||||||
err := setAttributeViewName(operation)
|
err := setAttributeViewName(operation)
|
||||||
if nil != err {
|
if nil != err {
|
||||||
@ -640,7 +692,8 @@ func addAttributeViewBlock(blockID string, operation *Operation, tree *parse.Tre
|
|||||||
if !operation.IsDetached {
|
if !operation.IsDetached {
|
||||||
content = getNodeRefText(node)
|
content = getNodeRefText(node)
|
||||||
}
|
}
|
||||||
value := &av.Value{ID: ast.NewNodeID(), KeyID: blockValues.Key.ID, BlockID: blockID, Type: av.KeyTypeBlock, IsDetached: operation.IsDetached, Block: &av.ValueBlock{ID: blockID, Content: content}}
|
now := time.Now().UnixMilli()
|
||||||
|
value := &av.Value{ID: ast.NewNodeID(), KeyID: blockValues.Key.ID, BlockID: blockID, Type: av.KeyTypeBlock, IsDetached: operation.IsDetached, Block: &av.ValueBlock{ID: blockID, Content: content, Created: now, Updated: now}}
|
||||||
blockValues.Values = append(blockValues.Values, value)
|
blockValues.Values = append(blockValues.Values, value)
|
||||||
|
|
||||||
if !operation.IsDetached {
|
if !operation.IsDetached {
|
||||||
@ -1243,6 +1296,10 @@ func UpdateAttributeViewCell(tx *Transaction, avID, keyID, rowID, cellID string,
|
|||||||
bindBlockAv(tx, avID, rowID)
|
bindBlockAv(tx, avID, rowID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if nil != val.Block {
|
||||||
|
val.Block.Updated = time.Now().UnixMilli()
|
||||||
|
}
|
||||||
|
|
||||||
if err = av.SaveAttributeView(attrView); nil != err {
|
if err = av.SaveAttributeView(attrView); nil != err {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user