1
0
Fork 0
mirror of https://github.com/anyproto/anytype-heart.git synced 2025-06-08 05:47:07 +09:00

Merge pull request #2140 from anyproto/go-5126-migrate-icons-for-bundled-non-system-types

GO-5184 Migrate icons for bundled non system types
This commit is contained in:
Kirill Stonozhenko 2025-02-26 16:01:13 +01:00 committed by mcrakhman
parent 76d473031b
commit 2bfc73668f
No known key found for this signature in database
GPG key ID: DED12CFEF5B8396B
4 changed files with 76 additions and 50 deletions

View file

@ -9,7 +9,7 @@ import (
"github.com/anyproto/anytype-heart/pkg/lib/pb/model"
)
const TypeChecksum = "55b112c49ecef2287e6a8a0b17d70955608139e1805dcb3fb742dc7eb43236be"
const TypeChecksum = "c4f1cd92b533a4b5f533c01185049b8c7c170401c2f0bf09d6d888cad6a61669"
const (
TypePrefix = "_ot"
)
@ -70,6 +70,7 @@ var (
Name: "Book",
Readonly: true,
RelationLinks: []*model.RelationLink{MustGetRelationLink(RelationKeyTag), MustGetRelationLink(RelationKeyAuthor), MustGetRelationLink(RelationKeyStarred), MustGetRelationLink(RelationKeyStatus), MustGetRelationLink(RelationKeyUrl)},
Revision: 1,
Types: []model.SmartBlockType{model.SmartBlockType_Page},
Url: TypePrefix + "book",
},
@ -136,6 +137,7 @@ var (
Name: "Contact",
Readonly: true,
RelationLinks: []*model.RelationLink{MustGetRelationLink(RelationKeyTag), MustGetRelationLink(RelationKeyCompany), MustGetRelationLink(RelationKeyEmail), MustGetRelationLink(RelationKeyPhone)},
Revision: 1,
Types: []model.SmartBlockType{model.SmartBlockType_Page},
Url: TypePrefix + "contact",
},
@ -173,6 +175,7 @@ var (
Name: "Diary Entry",
Readonly: true,
RelationLinks: []*model.RelationLink{MustGetRelationLink(RelationKeyTag), MustGetRelationLink(RelationKeyMood)},
Revision: 1,
Types: []model.SmartBlockType{model.SmartBlockType_Page},
Url: TypePrefix + "diaryEntry",
},
@ -199,6 +202,7 @@ var (
Name: "Goal",
Readonly: true,
RelationLinks: []*model.RelationLink{MustGetRelationLink(RelationKeyTag), MustGetRelationLink(RelationKeyDueDate), MustGetRelationLink(RelationKeyProgress), MustGetRelationLink(RelationKeyStatus), MustGetRelationLink(RelationKeyTasks)},
Revision: 1,
Types: []model.SmartBlockType{model.SmartBlockType_Page},
Url: TypePrefix + "goal",
},
@ -225,6 +229,7 @@ var (
Name: "Movie",
Readonly: true,
RelationLinks: []*model.RelationLink{MustGetRelationLink(RelationKeyTag), MustGetRelationLink(RelationKeyGenre), MustGetRelationLink(RelationKeyStatus)},
Revision: 1,
Types: []model.SmartBlockType{model.SmartBlockType_Page},
Url: TypePrefix + "movie",
},
@ -303,6 +308,7 @@ var (
Name: "Project",
Readonly: true,
RelationLinks: []*model.RelationLink{MustGetRelationLink(RelationKeyTag), MustGetRelationLink(RelationKeyTasks)},
Revision: 1,
Types: []model.SmartBlockType{model.SmartBlockType_Page},
Url: TypePrefix + "project",
},
@ -315,6 +321,7 @@ var (
Name: "Recipe",
Readonly: true,
RelationLinks: []*model.RelationLink{MustGetRelationLink(RelationKeyTag), MustGetRelationLink(RelationKeyIngredients), MustGetRelationLink(RelationKeyTime)},
Revision: 1,
Types: []model.SmartBlockType{model.SmartBlockType_Page},
Url: TypePrefix + "recipe",
},

View file

@ -14,7 +14,8 @@
"ingredients",
"time"
],
"description": "A recipe is a set of instructions that describes how to prepare or make something, especially a dish of prepared food"
"description": "A recipe is a set of instructions that describes how to prepare or make something, especially a dish of prepared food",
"revision": 1
},
{
"id": "note",
@ -48,7 +49,8 @@
"email",
"phone"
],
"description": "Information to make action of communicating or meeting with Human or Company"
"description": "Information to make action of communicating or meeting with Human or Company",
"revision": 1
},
{
"id": "bookmark",
@ -143,7 +145,8 @@
"status",
"url"
],
"description": "A book is a medium for recording information in the form of writing or images, typically composed of many pages bound together and protected by a cover"
"description": "A book is a medium for recording information in the form of writing or images, typically composed of many pages bound together and protected by a cover",
"revision": 1
},
{
"id": "video",
@ -200,7 +203,8 @@
"genre",
"status"
],
"description": "Motion picture or Moving picture, is a work of visual art used to simulate experiences that communicate ideas, stories, perceptions, feelings, beauty, or atmosphere through the use of moving images"
"description": "Motion picture or Moving picture, is a work of visual art used to simulate experiences that communicate ideas, stories, perceptions, feelings, beauty, or atmosphere through the use of moving images",
"revision": 1
},
{
"id": "objectType",
@ -345,7 +349,8 @@
"tag",
"mood"
],
"description": "Record of events and experiences"
"description": "Record of events and experiences",
"revision": 1
},
{
"id": "page",
@ -452,7 +457,8 @@
"status",
"tasks"
],
"description": "The object of a person's ambition or effort; an aim or desired result"
"description": "The object of a person's ambition or effort; an aim or desired result",
"revision": 1
},
{
"id": "file",
@ -489,7 +495,8 @@
"tag",
"tasks"
],
"description": "An individual or collaborative enterprise that is carefully planned to achieve a particular aim"
"description": "An individual or collaborative enterprise that is carefully planned to achieve a particular aim",
"revision": 1
},
{
"id": "chat",

View file

@ -87,7 +87,7 @@ func reviseObject(ctx context.Context, log logger.CtxLogger, space dependencies.
return false, fmt.Errorf("failed to unmarshal unique key '%s': %w", uniqueKeyRaw, err)
}
bundleObject := getBundleSystemObjectDetails(uk)
bundleObject, isSystem := getBundleObjectDetails(uk)
if bundleObject == nil {
return false, nil
}
@ -95,24 +95,26 @@ func reviseObject(ctx context.Context, log logger.CtxLogger, space dependencies.
if bundleObject.GetInt64(revisionKey) <= localObject.GetInt64(revisionKey) {
return false, nil
}
details := buildDiffDetails(bundleObject, localObject)
details := buildDiffDetails(bundleObject, localObject, isSystem)
recRelsDetails, err := checkRecommendedRelations(ctx, space, bundleObject, localObject)
if err != nil {
log.Error("failed to check recommended relations", zap.Error(err))
}
if isSystem {
recRelsDetails, err := checkRecommendedRelations(ctx, space, bundleObject, localObject)
if err != nil {
log.Error("failed to check recommended relations", zap.Error(err))
}
for _, recRelsDetail := range recRelsDetails {
details.Set(recRelsDetail.Key, recRelsDetail.Value)
}
for _, recRelsDetail := range recRelsDetails {
details.Set(recRelsDetail.Key, recRelsDetail.Value)
}
relFormatOTDetail, err := checkRelationFormatObjectTypes(ctx, space, bundleObject, localObject)
if err != nil {
log.Error("failed to check relation format object types", zap.Error(err))
}
relFormatOTDetail, err := checkRelationFormatObjectTypes(ctx, space, bundleObject, localObject)
if err != nil {
log.Error("failed to check relation format object types", zap.Error(err))
}
if relFormatOTDetail != nil {
details.Set(relFormatOTDetail.Key, relFormatOTDetail.Value)
if relFormatOTDetail != nil {
details.Set(relFormatOTDetail.Key, relFormatOTDetail.Value)
}
}
if details.Len() > 0 {
@ -130,44 +132,49 @@ func reviseObject(ctx context.Context, log logger.CtxLogger, space dependencies.
return true, nil
}
// getBundleSystemObjectDetails returns nil if the object with provided unique key is not either system relation or system type
func getBundleSystemObjectDetails(uk domain.UniqueKey) *domain.Details {
// getBundleObjectDetails returns nil if the object with provided unique key is not either system relation or bundled type
func getBundleObjectDetails(uk domain.UniqueKey) (details *domain.Details, isSystem bool) {
switch uk.SmartblockType() {
case coresb.SmartBlockTypeObjectType:
if !isSystemType(uk) {
// non system object type, no need to revise
return nil
}
typeKey := domain.TypeKey(uk.InternalKey())
objectType := bundle.MustGetType(typeKey)
return (&relationutils.ObjectType{ObjectType: objectType}).BundledTypeDetails()
objectType, err := bundle.GetType(typeKey)
if err != nil {
// not bundled type, no need to revise
return nil, false
}
return (&relationutils.ObjectType{ObjectType: objectType}).BundledTypeDetails(), isSystemType(uk)
case coresb.SmartBlockTypeRelation:
if !isSystemRelation(uk) {
// non system relation, no need to revise
return nil
return nil, false
}
relationKey := domain.RelationKey(uk.InternalKey())
relation := bundle.MustGetRelation(relationKey)
return (&relationutils.Relation{Relation: relation}).ToDetails()
return (&relationutils.Relation{Relation: relation}).ToDetails(), true
default:
return nil
return nil, false
}
}
func buildDiffDetails(origin, current *domain.Details) *domain.Details {
func buildDiffDetails(origin, current *domain.Details, isSystem bool) *domain.Details {
// non-system bundled types are going to update only icons for now
filterKeys := []domain.RelationKey{bundle.RelationKeyIconOption, bundle.RelationKeyIconName}
if isSystem {
filterKeys = []domain.RelationKey{
bundle.RelationKeyName,
bundle.RelationKeyDescription,
bundle.RelationKeyIsReadonly,
bundle.RelationKeyIsHidden,
bundle.RelationKeyRevision,
bundle.RelationKeyRelationReadonlyValue,
bundle.RelationKeyRelationMaxCount,
bundle.RelationKeyIconEmoji,
bundle.RelationKeyIconOption,
bundle.RelationKeyIconName,
}
}
diff, _ := domain.StructDiff(current, origin)
diff = diff.CopyOnlyKeys(
bundle.RelationKeyName,
bundle.RelationKeyDescription,
bundle.RelationKeyIsReadonly,
bundle.RelationKeyIsHidden,
bundle.RelationKeyRevision,
bundle.RelationKeyRelationReadonlyValue,
bundle.RelationKeyRelationMaxCount,
bundle.RelationKeyIconEmoji,
bundle.RelationKeyIconOption,
bundle.RelationKeyIconName,
)
diff = diff.CopyOnlyKeys(filterKeys...)
details := domain.NewDetails()
for key, value := range diff.Iterate() {

View file

@ -124,20 +124,25 @@ func TestReviseSystemObject(t *testing.T) {
assert.False(t, toRevise)
})
t.Run("non system object type is not updated", func(t *testing.T) {
t.Run("non system bundled object type is updated", func(t *testing.T) {
// given
objectType := domain.NewDetailsFromMap(map[domain.RelationKey]domain.Value{
bundle.RelationKeySourceObject: domain.String("_otcontact"),
bundle.RelationKeyUniqueKey: domain.String("ot-contact"),
})
space := mock_space.NewMockSpace(t) // if unexpected space.Do will be called, test will fail
space := mock_space.NewMockSpace(t)
space.EXPECT().DoCtx(mock.Anything, mock.Anything, mock.Anything).Times(1).Return(nil)
space.EXPECT().Id().Times(1).Return("")
space.EXPECT().DeriveObjectID(mock.Anything, mock.Anything).RunAndReturn(func(_ context.Context, key domain.UniqueKey) (string, error) {
return addr.ObjectTypeKeyToIdPrefix + key.InternalKey(), nil
}).Maybe()
// when
toRevise, err := reviseObject(ctx, log, space, objectType)
// then
assert.NoError(t, err)
assert.False(t, toRevise)
assert.True(t, toRevise)
})
t.Run("system object type with same revision is not updated", func(t *testing.T) {