diff --git a/app/src/assets/scss/business/_av.scss b/app/src/assets/scss/business/_av.scss index 23b06bd6a..158ba692d 100644 --- a/app/src/assets/scss/business/_av.scss +++ b/app/src/assets/scss/business/_av.scss @@ -462,7 +462,7 @@ vertical-align: bottom; } - img:first-child{ + img:first-child { height: calc(1.625em - 10px); float: left; margin-top: 5px; @@ -589,23 +589,6 @@ color: var(--b3-protyle-inline-blockref-color); } - .b3-menu__avemoji { - display: inline-block; - font-size: 1em; - line-height: 1.625; - height: auto; - margin: 0 5px 0 -4px; - vertical-align: top; - - img { - height: calc(1.625em - 8px); - font-size: 1em; - width: calc(1.625em - 8px); - float: left; - margin: 4px 0; - } - } - &[data-wrap="true"] { white-space: pre-wrap; } @@ -1000,3 +983,21 @@ img.av__cellassetimg { font-size: inherit; cursor: zoom-in; } + +.av__cell, +.custom-attr__avvalue { + .b3-menu__avemoji { + font-size: 1em; + line-height: 1.625; + height: auto; + margin: 0 5px 0 -4px; + vertical-align: top; + + img { + height: calc(1.625em - 8px); + font-size: 1em; + width: calc(1.625em - 8px); + margin: 4px 0; + } + } +} diff --git a/app/src/assets/scss/business/_custom.scss b/app/src/assets/scss/business/_custom.scss index d074eabda..dd428762c 100644 --- a/app/src/assets/scss/business/_custom.scss +++ b/app/src/assets/scss/business/_custom.scss @@ -130,8 +130,4 @@ .av__row.dragover__top::after { top: -1.5px; } - - .av__cell--relation { - display: inline-flex; - } } diff --git a/app/src/assets/scss/component/_list.scss b/app/src/assets/scss/component/_list.scss index 4d6745ae2..717d32db9 100644 --- a/app/src/assets/scss/component/_list.scss +++ b/app/src/assets/scss/component/_list.scss @@ -174,7 +174,7 @@ padding: 0 4px; flex-shrink: 0; border-radius: var(--b3-border-radius); - display: flex; + display: inline-flex; align-items: center; justify-content: center; diff --git a/app/src/protyle/render/av/cell.ts b/app/src/protyle/render/av/cell.ts index 7db7628d2..fed2ccd07 100644 --- a/app/src/protyle/render/av/cell.ts +++ b/app/src/protyle/render/av/cell.ts @@ -430,14 +430,18 @@ export const cellScrollIntoView = (blockElement: HTMLElement, cellElement: Eleme // 属性面板 return; } - const avHeaderRect = blockElement.querySelector(".av__row--header").getBoundingClientRect(); + const bodyElement = hasClosestByClassName(cellElement, "av__body"); + if (!bodyElement) { + return; + } + const avHeaderRect = bodyElement.querySelector(".av__row--header").getBoundingClientRect(); if (avHeaderRect.bottom > cellRect.top) { const contentElement = hasClosestByClassName(blockElement, "protyle-content", true); if (contentElement) { contentElement.scrollTop = contentElement.scrollTop + cellRect.top - avHeaderRect.bottom; } } else { - const footerElement = blockElement.querySelector(".av__row--footer"); + const footerElement = bodyElement.querySelector(".av__row--footer"); if (footerElement?.querySelector(".av__calc--ashow")) { const avFooterRect = footerElement.getBoundingClientRect(); if (avFooterRect.top < cellRect.bottom) { diff --git a/app/src/protyle/render/av/render.ts b/app/src/protyle/render/av/render.ts index c83d73b26..1e9e3678e 100644 --- a/app/src/protyle/render/av/render.ts +++ b/app/src/protyle/render/av/render.ts @@ -782,7 +782,8 @@ export const refreshAV = (protyle: IProtyle, operation: IOperation) => { popCellElement = popCellElements[0] as HTMLElement; } } - if (popCellElement && popCellElement.getAttribute("data-detached") === "true") { + if (popCellElement && popCellElement.getAttribute("data-detached") === "true" && + popCellElement.querySelector(".av__celltext").textContent === "") { popTextCell(protyle, [popCellElement], "block"); } } diff --git a/app/src/protyle/wysiwyg/transaction.ts b/app/src/protyle/wysiwyg/transaction.ts index 5b780cbba..94f2014c1 100644 --- a/app/src/protyle/wysiwyg/transaction.ts +++ b/app/src/protyle/wysiwyg/transaction.ts @@ -864,9 +864,10 @@ 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", "setAttrViewDisplayFieldName"].includes(operation.action)) { + "foldAttrViewGroup", "hideAttrViewAllGroups", "setAttrViewFitImage", "setAttrViewDisplayFieldName", + "insertAttrViewBlock"].includes(operation.action)) { + // 撤销 transaction 会进行推送,需使用推送来进行刷新最新数据 https://github.com/siyuan-note/siyuan/issues/13607 if (!isUndo) { - // 撤销 transaction 会进行推送,需使用推送来进行刷新最新数据 https://github.com/siyuan-note/siyuan/issues/13607 refreshAV(protyle, operation); } else if (operation.action === "setAttrViewName") { // setAttrViewName 同文档不会推送,需手动刷新 @@ -1327,8 +1328,6 @@ export const transaction = (protyle: IProtyle, doOperations: IOperation[], undoO blockRender(protyle, item); } }); - } else if (operation.action === "insertAttrViewBlock") { - refreshAV(protyle, operation); } }); }); diff --git a/kernel/av/value.go b/kernel/av/value.go index ee826c5dc..2be6b01f1 100644 --- a/kernel/av/value.go +++ b/kernel/av/value.go @@ -19,6 +19,7 @@ package av import ( "fmt" "math" + "reflect" "sort" "strconv" "strings" @@ -807,6 +808,12 @@ func (r *ValueRollup) BuildContents(keyValues []*KeyValues, destKey *Key, relati if nil == destVal { continue } + + if val := destVal.GetValByType(destKey.Type); nil == val || reflect.ValueOf(val).IsNil() { + // 目标字段因为修改类型导致空值 + continue + } + if KeyTypeNumber == destKey.Type { destVal.Number.Format = destKey.NumberFormat destVal.Number.FormatNumber() diff --git a/kernel/model/assets.go b/kernel/model/assets.go index fa0d3753f..980dac5a8 100644 --- a/kernel/model/assets.go +++ b/kernel/model/assets.go @@ -724,7 +724,7 @@ func RenameAsset(oldPath, newName string) (newPath string, err error) { defer util.PushClearProgress() newName = strings.TrimSpace(newName) - newName = util.FilterFileName(newName) + newName = util.FilterUploadFileName(newName) if path.Base(oldPath) == newName { return } diff --git a/kernel/model/attribute_view.go b/kernel/model/attribute_view.go index af0479068..0232e222c 100644 --- a/kernel/model/attribute_view.go +++ b/kernel/model/attribute_view.go @@ -532,7 +532,7 @@ func SetAttributeViewGroup(avID, blockID string, group *av.ViewGroup) (err error groupStates := getAttrViewGroupStates(view) view.Group = group - regenAttrViewGroups(attrView, "force") + regenAttrViewGroups(attrView) setAttrViewGroupStates(view, groupStates) if view.Group.HideEmpty != oldHideEmpty { @@ -715,7 +715,7 @@ func ChangeAttrViewLayout(blockID, avID string, layout av.LayoutType) (err error } } - regenAttrViewGroups(attrView, "force") + regenAttrViewGroups(attrView) if err = av.SaveAttributeView(attrView); nil != err { logging.LogErrorf("save attribute view [%s] failed: %s", avID, err) @@ -2292,13 +2292,13 @@ func updateAttributeViewColRelation(operation *Operation) (err error) { } } - regenAttrViewGroups(srcAv, "force") + regenAttrViewGroups(srcAv) err = av.SaveAttributeView(srcAv) if err != nil { return } if !isSameAv { - regenAttrViewGroups(destAv, "force") + regenAttrViewGroups(destAv) err = av.SaveAttributeView(destAv) ReloadAttrView(destAv.ID) } @@ -2555,7 +2555,7 @@ func (tx *Transaction) doDuplicateAttrViewView(operation *Operation) (ret *TxErr } view.GroupItemIDs = masterView.GroupItemIDs - regenAttrViewGroups(attrView, "force") + regenAttrViewGroups(attrView) } if err = av.SaveAttributeView(attrView); err != nil { @@ -3140,7 +3140,7 @@ func addAttributeViewBlock(now int64, avID, dbBlockID, groupID, previousItemID, } } - regenAttrViewGroups(attrView, "force") + regenAttrViewGroups(attrView) err = av.SaveAttributeView(attrView) return } @@ -3277,7 +3277,7 @@ func removeAttributeViewBlock(srcIDs []string, avID string, tx *Transaction) (er } } - regenAttrViewGroups(attrView, "force") + regenAttrViewGroups(attrView) err = av.SaveAttributeView(attrView) if nil != err { @@ -3703,7 +3703,7 @@ func sortAttributeViewRow(operation *Operation) (err error) { if av.KeyTypeMSelect == groupKey.Type || av.KeyTypeRelation == groupKey.Type { // 跨多选分组时一个项目可能会同时存在于多个分组中,需要重新生成分组 - regenAttrViewGroups(attrView, "force") + regenAttrViewGroups(attrView) } } else { // 同分组内排序 for i, r := range groupView.GroupItemIDs { @@ -4006,7 +4006,7 @@ func updateAttributeViewColTemplate(operation *Operation) (err error) { } } - regenAttrViewGroups(attrView, operation.ID) + regenAttrViewGroups(attrView) err = av.SaveAttributeView(attrView) return } @@ -4086,7 +4086,33 @@ func updateAttributeViewColumn(operation *Operation) (err error) { } } - err = av.SaveAttributeView(attrView) + if err = av.SaveAttributeView(attrView); nil != err { + return + } + + if changeType { + relatedAvIDs := av.GetSrcAvIDs(attrView.ID) + for _, relatedAvID := range relatedAvIDs { + destAv, _ := av.ParseAttributeView(relatedAvID) + if nil == destAv { + continue + } + + for _, keyValues := range destAv.KeyValues { + if av.KeyTypeRollup == keyValues.Key.Type && keyValues.Key.Rollup.KeyID == operation.ID { + // 置空关联过来的汇总 + for _, val := range keyValues.Values { + val.Rollup.Contents = nil + } + keyValues.Key.Rollup.Calc = &av.RollupCalc{Operator: av.CalcOperatorNone} + } + } + + regenAttrViewGroups(destAv) + av.SaveAttributeView(destAv) + ReloadAttrView(destAv.ID) + } + } return } @@ -4234,7 +4260,7 @@ func RemoveAttributeViewKey(avID, keyID string, removeRelationDest bool) (err er } } - regenAttrViewGroups(destAv, "force") + regenAttrViewGroups(destAv) av.SaveAttributeView(destAv) ReloadAttrView(destAv.ID) } @@ -4283,7 +4309,7 @@ func replaceAttributeViewBlock0(attrView *av.AttributeView, oldBlockID, newNodeI content = util.UnescapeHTML(content) blockVal.Block.Icon, blockVal.Block.Content = icon, content blockVal.UpdatedAt = now - regenAttrViewGroups(attrView, "force") + regenAttrViewGroups(attrView) return } } @@ -4313,7 +4339,7 @@ func replaceAttributeViewBlock0(attrView *av.AttributeView, oldBlockID, newNodeI } } - regenAttrViewGroups(attrView, "force") + regenAttrViewGroups(attrView) return } @@ -4561,7 +4587,7 @@ func updateAttributeViewValue(tx *Transaction, attrView *av.AttributeView, keyID updateTwoWayRelationDestAttrView(attrView, key, val, relationChangeMode, oldRelationBlockIDs) } - regenAttrViewGroups(attrView, "force") + regenAttrViewGroups(attrView) if err = av.SaveAttributeView(attrView); nil != err { return } @@ -4578,7 +4604,7 @@ func refreshRelatedSrcAvs(destAvID string) { continue } - regenAttrViewGroups(destAv, "force") + regenAttrViewGroups(destAv) av.SaveAttributeView(destAv) ReloadAttrView(relatedAvID) } @@ -4648,27 +4674,19 @@ func updateTwoWayRelationDestAttrView(attrView *av.AttributeView, relKey *av.Key } if destAv != attrView { - regenAttrViewGroups(destAv, "force") + regenAttrViewGroups(destAv) av.SaveAttributeView(destAv) } } // regenAttrViewGroups 重新生成分组视图。 -// keyID: 如果是 "force" 则强制重新生成所有分组视图,否则只生成 keyID 指定的分组字段的分组视图 -func regenAttrViewGroups(attrView *av.AttributeView, keyID string) { +func regenAttrViewGroups(attrView *av.AttributeView) { for _, view := range attrView.Views { groupKey := view.GetGroupKey(attrView) if nil == groupKey { continue } - if "force" != keyID { - if av.KeyTypeTemplate != groupKey.Type && av.KeyTypeRollup != groupKey.Type && av.KeyTypeCreated != groupKey.Type && av.KeyTypeUpdated != groupKey.Type && - view.Group.Field != keyID { - continue - } - } - genAttrViewGroups(view, attrView) } } @@ -4858,7 +4876,7 @@ func updateAttributeViewColumnOptions(operation *Operation) (err error) { }) } - regenAttrViewGroups(attrView, operation.ID) + regenAttrViewGroups(attrView) err = av.SaveAttributeView(attrView) return } @@ -4942,7 +4960,7 @@ func removeAttributeViewColumnOption(operation *Operation) (err error) { } } - regenAttrViewGroups(attrView, operation.ID) + regenAttrViewGroups(attrView) err = av.SaveAttributeView(attrView) return } @@ -5061,7 +5079,7 @@ func updateAttributeViewColumnOption(operation *Operation) (err error) { } } - regenAttrViewGroups(attrView, operation.ID) + regenAttrViewGroups(attrView) err = av.SaveAttributeView(attrView) return } diff --git a/kernel/model/attribute_view_render.go b/kernel/model/attribute_view_render.go index 51c19dd58..033c0b9b7 100644 --- a/kernel/model/attribute_view_render.go +++ b/kernel/model/attribute_view_render.go @@ -92,7 +92,7 @@ func renderAttributeViewGroups(viewable av.Viewable, attrView *av.AttributeView, if isGroupByDate(view) { createdDate := time.UnixMilli(view.GroupCreated).Format("2006-01-02") if time.Now().Format("2006-01-02") != createdDate { - regenAttrViewGroups(attrView, "force") + regenAttrViewGroups(attrView) av.SaveAttributeView(attrView) } } @@ -108,7 +108,7 @@ func renderAttributeViewGroups(viewable av.Viewable, attrView *av.AttributeView, for _, groupView := range view.Groups { if (nil == groupView.GroupVal || nil == groupView.GroupKey) && !fixDev { // TODO 分组上线后删除,预计 2025 年 9 月后可以删除 - regenAttrViewGroups(attrView, "force") + regenAttrViewGroups(attrView) av.SaveAttributeView(attrView) fixDev = true } diff --git a/kernel/model/transaction.go b/kernel/model/transaction.go index e0a3c8640..23404b2b6 100644 --- a/kernel/model/transaction.go +++ b/kernel/model/transaction.go @@ -1008,7 +1008,7 @@ func syncDelete2AttributeView(node *ast.Node) (changedAvIDs []string) { } if changedAv { - regenAttrViewGroups(attrView, "force") + regenAttrViewGroups(attrView) av.SaveAttributeView(attrView) changedAvIDs = append(changedAvIDs, avID) } @@ -1569,7 +1569,7 @@ func upsertAvBlockRel(node *ast.Node) { for _, avID := range affectedAvIDs { attrView, _ := av.ParseAttributeView(avID) if nil != attrView { - regenAttrViewGroups(attrView, "force") + regenAttrViewGroups(attrView) av.SaveAttributeView(attrView) }