diff --git a/app/src/protyle/render/av/layout.ts b/app/src/protyle/render/av/layout.ts index f983f1e12..cbdfed9e2 100644 --- a/app/src/protyle/render/av/layout.ts +++ b/app/src/protyle/render/av/layout.ts @@ -190,12 +190,12 @@ export const bindLayoutEvent = (options: { const blockID = options.blockElement.getAttribute("data-node-id"); const checked = toggleNameElement.checked; transaction(options.protyle, [{ - action: "setDisplayFieldName", + action: "setAttrViewDisplayFieldName", avID, blockID, data: checked }], [{ - action: "setDisplayFieldName", + action: "setAttrViewDisplayFieldName", avID, blockID, data: !checked diff --git a/app/src/protyle/wysiwyg/transaction.ts b/app/src/protyle/wysiwyg/transaction.ts index 9fee7f47f..5b780cbba 100644 --- a/app/src/protyle/wysiwyg/transaction.ts +++ b/app/src/protyle/wysiwyg/transaction.ts @@ -864,7 +864,7 @@ export const onTransaction = (protyle: IProtyle, operation: IOperation, isUndo: "duplicateAttrViewKey", "setAttrViewViewDesc", "setAttrViewCoverFrom", "setAttrViewCoverFromAssetKeyID", "setAttrViewBlockView", "setAttrViewCardSize", "setAttrViewCardAspectRatio", "hideAttrViewName", "setAttrViewShowIcon", "setAttrViewWrapField", "setAttrViewGroup", "removeAttrViewGroup", "hideAttrViewGroup", "sortAttrViewGroup", - "foldAttrViewGroup", "hideAttrViewAllGroups", "setAttrViewFitImage", "setDisplayFieldName"].includes(operation.action)) { + "foldAttrViewGroup", "hideAttrViewAllGroups", "setAttrViewFitImage", "setAttrViewDisplayFieldName"].includes(operation.action)) { if (!isUndo) { // 撤销 transaction 会进行推送,需使用推送来进行刷新最新数据 https://github.com/siyuan-note/siyuan/issues/13607 refreshAV(protyle, operation); diff --git a/app/src/types/index.d.ts b/app/src/types/index.d.ts index 7b2181328..d1b5d16c3 100644 --- a/app/src/types/index.d.ts +++ b/app/src/types/index.d.ts @@ -69,7 +69,7 @@ type TOperation = | "hideAttrViewGroup" | "sortAttrViewGroup" | "foldAttrViewGroup" - | "setDisplayFieldName" + | "setAttrViewDisplayFieldName" type TBazaarType = "templates" | "icons" | "widgets" | "themes" | "plugins" type TCardType = "doc" | "notebook" | "all" type TEventBus = "ws-main" | "sync-start" | "sync-end" | "sync-fail" | diff --git a/kernel/av/filter.go b/kernel/av/filter.go index cded60be1..7a6b94f6d 100644 --- a/kernel/av/filter.go +++ b/kernel/av/filter.go @@ -26,11 +26,11 @@ import ( // ViewFilter 描述了视图过滤规则的结构。 type ViewFilter struct { - Column string `json:"column"` // 列(字段)ID - Operator FilterOperator `json:"operator"` // 过滤操作符 - Value *Value `json:"value"` // 过滤值 - RelativeDate *RelativeDate `json:"relativeDate"` // 相对时间 - RelativeDate2 *RelativeDate `json:"relativeDate2"` // 第二个相对时间,用于某些操作符,比如 FilterOperatorIsBetween + Column string `json:"column"` // 列(字段)ID + Operator FilterOperator `json:"operator"` // 过滤操作符 + Value *Value `json:"value"` // 过滤值 + RelativeDate *RelativeDate `json:"relativeDate,omitempty"` // 相对时间 + RelativeDate2 *RelativeDate `json:"relativeDate2,omitempty"` // 第二个相对时间,用于某些操作符,比如 FilterOperatorIsBetween } type RelativeDateUnit int @@ -360,6 +360,10 @@ func (value *Value) filter(other *Value, relativeDate, relativeDate2 *RelativeDa } case KeyTypeSelect, KeyTypeMSelect: if nil != value.MSelect { + if 1 > len(other.MSelect) { + return true + } + switch operator { case FilterOperatorIsEqual, FilterOperatorContains: contains := false diff --git a/kernel/av/value.go b/kernel/av/value.go index 2c5380661..cb41e279f 100644 --- a/kernel/av/value.go +++ b/kernel/av/value.go @@ -374,11 +374,11 @@ func (value *Value) GetValByType(typ KeyType) (ret interface{}) { } type ValueBlock struct { - ID string `json:"id"` // 绑定的块 ID,非绑定块时为空 - Icon string `json:"icon"` + ID string `json:"id,omitempty"` // 绑定的块 ID,非绑定块时为空 + Icon string `json:"icon,omitempty"` Content string `json:"content"` - Created int64 `json:"created"` - Updated int64 `json:"updated"` + Created int64 `json:"created,omitempty"` + Updated int64 `json:"updated,omitempty"` } type ValueText struct { diff --git a/kernel/model/attribute_view.go b/kernel/model/attribute_view.go index 0f8537f04..c74673904 100644 --- a/kernel/model/attribute_view.go +++ b/kernel/model/attribute_view.go @@ -1174,6 +1174,7 @@ type AvSearchResult struct { AvID string `json:"avID"` AvName string `json:"avName"` ViewName string `json:"viewName"` + ViewID string `json:"viewID"` BlockID string `json:"blockID"` HPath string `json:"hPath"` Children []*AvSearchResult `json:"children,omitempty"` @@ -1264,92 +1265,80 @@ func SearchAttributeView(keyword string, excludeAvIDs []string) (ret []*AvSearch avIDs = append(avIDs, a.AvID) } - avBlocks := treenode.BatchGetMirrorAttrViewBlocks(avIDs) var blockIDs []string - for _, avBlock := range avBlocks { - blockIDs = append(blockIDs, avBlock.BlockIDs...) + for _, bIDs := range avBlockRels { + blockIDs = append(blockIDs, bIDs...) } blockIDs = gulu.Str.RemoveDuplicatedElem(blockIDs) trees := filesys.LoadTrees(blockIDs) - for _, avBlock := range avBlocks { - parentResult := buildSearchAttributeViewResult(avSearchTmpResults, avBlock.BlockIDs[0], trees, excludeAvIDs) - if nil == parentResult { + hitAttrViews := map[string]bool{} + for _, blockID := range blockIDs { + tree := trees[blockID] + if nil == tree { continue } - ret = append(ret, parentResult) - for _, blockID := range avBlock.BlockIDs { - result := buildSearchAttributeViewResult(avSearchTmpResults, blockID, trees, excludeAvIDs) - if nil != result { - parentResult.Children = append(parentResult.Children, result) + + node := treenode.GetNodeInTree(tree, blockID) + if nil == node || "" == node.AttributeViewID { + continue + } + + avID := node.AttributeViewID + var existAv *AvSearchTempResult + for _, tmpResult := range avSearchTmpResults { + if tmpResult.AvID == avID { + existAv = tmpResult + break } } - } - return -} - -func buildSearchAttributeViewResult(avSearchTempResults []*AvSearchTempResult, blockID string, trees map[string]*parse.Tree, excludeAvIDs []string) (ret *AvSearchResult) { - tree := trees[blockID] - if nil == tree { - return - } - - node := treenode.GetNodeInTree(tree, blockID) - if nil == node { - return - } - - if "" == node.AttributeViewID { - return - } - - avID := node.AttributeViewID - var existAv *AvSearchTempResult - for _, tmpResult := range avSearchTempResults { - if tmpResult.AvID == avID { - existAv = tmpResult - break + if nil == existAv || gulu.Str.Contains(avID, excludeAvIDs) { + continue } - } - if nil == existAv { - return - } - attrView, _ := av.ParseAttributeView(avID) - if nil == attrView { - return - } - viewID := node.IALAttr(av.NodeAttrView) - if "" == viewID { - viewID = attrView.ViewID - } - view, _ := attrView.GetCurrentView(viewID) - if nil == view { - return - } + if hitAttrViews[avID] { + continue + } + hitAttrViews[avID] = true - var hPath string - baseBlock := treenode.GetBlockTreeRootByPath(node.Box, node.Path) - if nil != baseBlock { - hPath = baseBlock.HPath - } - box := Conf.Box(node.Box) - if nil != box { - hPath = box.Name + hPath - } + attrView, _ := av.ParseAttributeView(avID) + if nil == attrView { + continue + } - name := existAv.AvName - if "" == name { - name = Conf.language(267) - } + var hPath string + baseBlock := treenode.GetBlockTreeRootByPath(node.Box, node.Path) + if nil != baseBlock { + hPath = baseBlock.HPath + } + box := Conf.Box(node.Box) + if nil != box { + hPath = box.Name + hPath + } - if !gulu.Str.Contains(avID, excludeAvIDs) { - ret = &AvSearchResult{ - AvID: avID, - AvName: existAv.AvName, - ViewName: view.Name, - BlockID: blockID, - HPath: hPath, + name := existAv.AvName + if "" == name { + name = Conf.language(267) + } + + parent := &AvSearchResult{ + AvID: avID, + AvName: existAv.AvName, + BlockID: blockID, + HPath: hPath, + } + ret = append(ret, parent) + + for _, view := range attrView.Views { + child := &AvSearchResult{ + AvID: avID, + AvName: existAv.AvName, + ViewName: view.Name, + ViewID: view.ID, + BlockID: blockID, + HPath: hPath, + } + parent.Children = append(parent.Children, child) } } return diff --git a/kernel/model/transaction.go b/kernel/model/transaction.go index 1cc4b5afa..57223ea61 100644 --- a/kernel/model/transaction.go +++ b/kernel/model/transaction.go @@ -287,7 +287,7 @@ func performTx(tx *Transaction) (ret *TxErr) { ret = tx.doSetAttrViewCardSize(op) case "setAttrViewFitImage": ret = tx.doSetAttrViewFitImage(op) - case "setDisplayFieldName": + case "setAttrViewDisplayFieldName": ret = tx.doSetAttrViewDisplayFieldName(op) case "setAttrViewShowIcon": ret = tx.doSetAttrViewShowIcon(op) diff --git a/kernel/treenode/av.go b/kernel/treenode/av.go index 5bd3bebfe..4c6492a7c 100644 --- a/kernel/treenode/av.go +++ b/kernel/treenode/av.go @@ -55,46 +55,3 @@ func GetMirrorAttrViewBlockIDs(avID string) (ret []string) { } return } - -type AvBlock struct { - AvID string - BlockIDs []string -} - -func BatchGetMirrorAttrViewBlocks(avIDs []string) (ret []*AvBlock) { - av.AttributeViewBlocksLock.Lock() - defer av.AttributeViewBlocksLock.Unlock() - - ret = []*AvBlock{} - - blocks := filepath.Join(util.DataDir, "storage", "av", "blocks.msgpack") - if !filelock.IsExist(blocks) { - return - } - - data, err := filelock.ReadFile(blocks) - if err != nil { - logging.LogErrorf("read attribute view blocks failed: %s", err) - return - } - - avBlocks := map[string][]string{} - if err = msgpack.Unmarshal(data, &avBlocks); err != nil { - logging.LogErrorf("unmarshal attribute view blocks failed: %s", err) - return - } - - for _, avID := range avIDs { - var blockIDs []string - bts := GetBlockTrees(avBlocks[avID]) - for blockID := range bts { - blockIDs = append(blockIDs, blockID) - } - avBlock := &AvBlock{ - AvID: avID, - BlockIDs: blockIDs, - } - ret = append(ret, avBlock) - } - return -}