diff --git a/app/appearance/langs/en_US.json b/app/appearance/langs/en_US.json
index b494551a2..0f957faae 100644
--- a/app/appearance/langs/en_US.json
+++ b/app/appearance/langs/en_US.json
@@ -482,7 +482,7 @@
"syncConfGuide4": "Sync now?",
"syncConfGuide5": "If the amount of data is large, the first sync will be slow, please wait patiently
Do not switch apps and keep the screen bright while the iOS/iPad is syncing",
"copyPlainText": "Copy plain text",
- "findInDoc": "Match ${y} items in ${x} docs",
+ "findInDoc": "Matches ${y} blocks in ${x} documents",
"jumpToParentNext": "Jump to the next block of the parent block",
"jumpToParentPrev": "Jump to the previous block of the parent block",
"jumpToParent": "Jump to parent block",
diff --git a/app/appearance/langs/es_ES.json b/app/appearance/langs/es_ES.json
index 2f73568b1..25df97454 100644
--- a/app/appearance/langs/es_ES.json
+++ b/app/appearance/langs/es_ES.json
@@ -482,7 +482,7 @@
"syncConfGuide4": "¿Sincronizar ahora?",
"syncConfGuide5": "Si la cantidad de datos es grande, la primera sincronización será lenta, espere pacientemente
No cambie de aplicación y mantenga la pantalla brillante mientras iOS/iPad se sincroniza",
"copyPlainText": "Copiar texto sin formato",
- "findInDoc": "Hacer coincidir ${y} elementos en ${x} documentos",
+ "findInDoc": "Coincide con bloques ${y} en documentos ${x}",
"jumpToParentNext": "Saltar al siguiente bloque del bloque principal",
"jumpToParentPrev": "Saltar al bloque anterior del bloque principal",
"jumpToParent": "Saltar al bloque principal",
diff --git a/app/appearance/langs/fr_FR.json b/app/appearance/langs/fr_FR.json
index 3c849d2ba..d8b12e1a8 100644
--- a/app/appearance/langs/fr_FR.json
+++ b/app/appearance/langs/fr_FR.json
@@ -482,7 +482,7 @@
"syncConfGuide4": "Synchroniser maintenant ?",
"syncConfGuide5": "Si la quantité de données est importante, la première synchronisation sera lente, veuillez patienter
Ne changez pas d'application et gardez l'écran lumineux pendant la synchronisation de l'iOS/iPad",
"copyPlainText": "Copier du texte brut",
- "findInDoc": "Faire correspondre les éléments ${y} dans les documents ${x}",
+ "findInDoc": "Correspond à ${y} blocs dans ${x} documents",
"jumpToParentNext": "Sauter au bloc suivant du bloc parent",
"jumpToParentPrev": "Sauter au bloc précédent du bloc parent",
"jumpToParent": "Sauter au bloc parent",
diff --git a/app/appearance/langs/ja_JP.json b/app/appearance/langs/ja_JP.json
index d62242147..7da8cdd77 100644
--- a/app/appearance/langs/ja_JP.json
+++ b/app/appearance/langs/ja_JP.json
@@ -482,7 +482,7 @@
"syncConfGuide4": "今すぐ同期しますか?",
"syncConfGuide5": "データ量が多い場合は最初の同期が遅くなる場合がありますのでしばらくお待ちください。
iOS/iPad で同期している間はアプリを切り替えず画面を明るく保ってください",
"copyPlainText": "プレーンテキストとしてコピー",
- "findInDoc": "${x} 個のドキュメントに ${y} 件の一致があります",
+ "findInDoc": "${x} ドキュメント内の ${y} ブロックと一致します",
"jumpToParentNext": "次の親ブロックに移動",
"jumpToParentPrev": "前の親ブロックに移動",
"jumpToParent": "親ブロックに移動",
diff --git a/app/appearance/langs/zh_CHT.json b/app/appearance/langs/zh_CHT.json
index e365bc8a5..144cee6dc 100644
--- a/app/appearance/langs/zh_CHT.json
+++ b/app/appearance/langs/zh_CHT.json
@@ -482,7 +482,7 @@
"syncConfGuide4": "立即同步?",
"syncConfGuide5": "如果資料量較大,第一次同步會比較慢,請耐心等待
iOS/iPad 端在同步時請勿切換應用並保持螢幕恆亮",
"copyPlainText": "複製純文字",
- "findInDoc": "${x} 個文檔中匹配 ${y} 項",
+ "findInDoc": "${x} 個文件中符合 ${y} 個區塊",
"jumpToParentNext": "跳到父區塊的下一個區塊",
"jumpToParentPrev": "跳到父區塊的上一個區塊",
"jumpToParent": "跳到父區塊",
diff --git a/app/appearance/langs/zh_CN.json b/app/appearance/langs/zh_CN.json
index ad7b573ab..16c6979a9 100644
--- a/app/appearance/langs/zh_CN.json
+++ b/app/appearance/langs/zh_CN.json
@@ -482,7 +482,7 @@
"syncConfGuide4": "立即同步?",
"syncConfGuide5": "如果数据量较大,第一次同步会比较慢,请耐心等待
iOS/iPad 端在同步时请勿切换应用并保持亮屏",
"copyPlainText": "复制纯文本",
- "findInDoc": "${x} 个文档中匹配 ${y} 项",
+ "findInDoc": "${x} 个文档中匹配 ${y} 个块",
"jumpToParentNext": "跳转到父块的下一个块",
"jumpToParentPrev": "跳转到父块的上一个块",
"jumpToParent": "跳转到父块",
diff --git a/kernel/api/av.go b/kernel/api/av.go
index 2cb0cc452..9670bc62d 100644
--- a/kernel/api/av.go
+++ b/kernel/api/av.go
@@ -211,7 +211,7 @@ func removeAttributeViewKey(c *gin.Context) {
util.PushReloadAttrView(avID)
}
-func sortAttributeViewKey(c *gin.Context) {
+func sortAttributeViewViewKey(c *gin.Context) {
ret := gulu.Ret.NewResult()
defer c.JSON(http.StatusOK, ret)
@@ -228,7 +228,30 @@ func sortAttributeViewKey(c *gin.Context) {
keyID := arg["keyID"].(string)
previousKeyID := arg["previousKeyID"].(string)
- err := model.SortAttributeViewKey(avID, viewID, keyID, previousKeyID)
+ err := model.SortAttributeViewViewKey(avID, viewID, keyID, previousKeyID)
+ if nil != err {
+ ret.Code = -1
+ ret.Msg = err.Error()
+ return
+ }
+
+ util.PushReloadAttrView(avID)
+}
+
+func sortAttributeViewKey(c *gin.Context) {
+ ret := gulu.Ret.NewResult()
+ defer c.JSON(http.StatusOK, ret)
+
+ arg, ok := util.JsonArg(c, ret)
+ if !ok {
+ return
+ }
+
+ avID := arg["avID"].(string)
+ keyID := arg["keyID"].(string)
+ previousKeyID := arg["previousKeyID"].(string)
+
+ err := model.SortAttributeViewKey(avID, keyID, previousKeyID)
if nil != err {
ret.Code = -1
ret.Msg = err.Error()
diff --git a/kernel/api/router.go b/kernel/api/router.go
index 4801ecc5a..77d4a4b47 100644
--- a/kernel/api/router.go
+++ b/kernel/api/router.go
@@ -416,6 +416,7 @@ func ServeAPI(ginServer *gin.Engine) {
ginServer.Handle("POST", "/api/av/getAttributeViewFilterSort", model.CheckAuth, model.CheckReadonly, getAttributeViewFilterSort)
ginServer.Handle("POST", "/api/av/addAttributeViewKey", model.CheckAuth, model.CheckReadonly, addAttributeViewKey)
ginServer.Handle("POST", "/api/av/removeAttributeViewKey", model.CheckAuth, model.CheckReadonly, removeAttributeViewKey)
+ ginServer.Handle("POST", "/api/av/sortAttributeViewViewKey", model.CheckAuth, model.CheckReadonly, sortAttributeViewViewKey)
ginServer.Handle("POST", "/api/av/sortAttributeViewKey", model.CheckAuth, model.CheckReadonly, sortAttributeViewKey)
ginServer.Handle("POST", "/api/av/addAttributeViewValues", model.CheckAuth, model.CheckReadonly, addAttributeViewValues)
ginServer.Handle("POST", "/api/av/removeAttributeViewValues", model.CheckAuth, model.CheckReadonly, removeAttributeViewValues)
diff --git a/kernel/av/av.go b/kernel/av/av.go
index f28ef2bad..54736adc4 100644
--- a/kernel/av/av.go
+++ b/kernel/av/av.go
@@ -40,7 +40,8 @@ type AttributeView struct {
Spec int `json:"spec"` // 格式版本
ID string `json:"id"` // 属性视图 ID
Name string `json:"name"` // 属性视图名称
- KeyValues []*KeyValues `json:"keyValues"` // 属性视图属性列值
+ KeyValues []*KeyValues `json:"keyValues"` // 属性视图属性键值
+ KeyIDs []string `json:"keyIDs"` // 属性视图属性键 ID,用于排序
ViewID string `json:"viewID"` // 当前视图 ID
Views []*View `json:"views"` // 视图
}
diff --git a/kernel/model/attribute_view.go b/kernel/model/attribute_view.go
index cf4781d61..1a82c4bb1 100644
--- a/kernel/model/attribute_view.go
+++ b/kernel/model/attribute_view.go
@@ -523,19 +523,14 @@ func GetBlockAttributeViewKeys(blockID string) (ret []*BlockAttributeViewKeys) {
util.PushErrMsg(fmt.Sprintf(Conf.Language(44), util.EscapeHTML(renderTemplateErr.Error())), 30000)
}
- // Attribute Panel - Database sort attributes by view column order https://github.com/siyuan-note/siyuan/issues/9319
- viewID := attrs[av.NodeAttrView]
- view, _ := attrView.GetCurrentView(viewID)
- if nil != view {
- sorts := map[string]int{}
- for i, col := range view.Table.Columns {
- sorts[col.ID] = i
- }
-
- sort.Slice(keyValues, func(i, j int) bool {
- return sorts[keyValues[i].Key.ID] < sorts[keyValues[j].Key.ID]
- })
+ // 字段排序
+ sorts := map[string]int{}
+ for i, k := range attrView.KeyIDs {
+ sorts[k] = i
}
+ sort.Slice(keyValues, func(i, j int) bool {
+ return sorts[keyValues[i].Key.ID] < sorts[keyValues[j].Key.ID]
+ })
blockIDs := treenode.GetMirrorAttrViewBlockIDs(avID)
if 1 > len(blockIDs) {
@@ -2269,14 +2264,14 @@ func sortAttributeViewRow(operation *Operation) (err error) {
}
func (tx *Transaction) doSortAttrViewColumn(operation *Operation) (ret *TxErr) {
- err := SortAttributeViewKey(operation.AvID, operation.BlockID, operation.ID, operation.PreviousID)
+ err := SortAttributeViewViewKey(operation.AvID, operation.BlockID, operation.ID, operation.PreviousID)
if nil != err {
return &TxErr{code: TxErrWriteAttributeView, id: operation.AvID, msg: err.Error()}
}
return
}
-func SortAttributeViewKey(avID, blockID, keyID, previousKeyID string) (err error) {
+func SortAttributeViewViewKey(avID, blockID, keyID, previousKeyID string) (err error) {
if keyID == previousKeyID {
// 拖拽到自己的右侧,不做任何操作 https://github.com/siyuan-note/siyuan/issues/11048
return
@@ -2321,6 +2316,57 @@ func SortAttributeViewKey(avID, blockID, keyID, previousKeyID string) (err error
return
}
+func (tx *Transaction) doSortAttrViewKey(operation *Operation) (ret *TxErr) {
+ err := SortAttributeViewKey(operation.AvID, operation.ID, operation.PreviousID)
+ if nil != err {
+ return &TxErr{code: TxErrWriteAttributeView, id: operation.AvID, msg: err.Error()}
+ }
+ return
+}
+
+func SortAttributeViewKey(avID, keyID, previousKeyID string) (err error) {
+ if keyID == previousKeyID {
+ return
+ }
+
+ attrView, err := av.ParseAttributeView(avID)
+ if nil != err {
+ return
+ }
+
+ if 1 > len(attrView.KeyIDs) {
+ for _, keyValues := range attrView.KeyValues {
+ attrView.KeyIDs = append(attrView.KeyIDs, keyValues.Key.ID)
+ }
+ }
+
+ var currentKeyID string
+ var idx, previousIndex int
+ for i, k := range attrView.KeyIDs {
+ if k == keyID {
+ currentKeyID = k
+ idx = i
+ break
+ }
+ }
+ if "" == currentKeyID {
+ return
+ }
+
+ attrView.KeyIDs = append(attrView.KeyIDs[:idx], attrView.KeyIDs[idx+1:]...)
+
+ for i, k := range attrView.KeyIDs {
+ if k == previousKeyID {
+ previousIndex = i + 1
+ break
+ }
+ }
+ attrView.KeyIDs = util.InsertElem(attrView.KeyIDs, previousIndex, currentKeyID)
+
+ err = av.SaveAttributeView(attrView)
+ return
+}
+
func (tx *Transaction) doAddAttrViewColumn(operation *Operation) (ret *TxErr) {
var icon string
if nil != operation.Data {
diff --git a/kernel/model/transaction.go b/kernel/model/transaction.go
index 072da7d4e..42a31d0c6 100644
--- a/kernel/model/transaction.go
+++ b/kernel/model/transaction.go
@@ -258,6 +258,8 @@ func performTx(tx *Transaction) (ret *TxErr) {
ret = tx.doSortAttrViewRow(op)
case "sortAttrViewCol":
ret = tx.doSortAttrViewColumn(op)
+ case "sortAttrViewKey":
+ ret = tx.doSortAttrViewKey(op)
case "updateAttrViewCell":
ret = tx.doUpdateAttrViewCell(op)
case "updateAttrViewColOptions":