diff --git a/core/block/bookmark/bookmark_service.go b/core/block/bookmark/bookmark_service.go index 15f28ee09..aded9d48d 100644 --- a/core/block/bookmark/bookmark_service.go +++ b/core/block/bookmark/bookmark_service.go @@ -48,7 +48,7 @@ type Service interface { } type ObjectCreator interface { - CreateSmartBlockFromState(ctx context.Context, sbType coresb.SmartBlockType, details *types.Struct, relationIds []string, s *state.State) (id string, newDetails *types.Struct, err error) + CreateSmartBlockFromState(ctx context.Context, sbType coresb.SmartBlockType, details *types.Struct, s *state.State) (id string, newDetails *types.Struct, err error) } type DetailsSetter interface { @@ -120,7 +120,7 @@ func (s *service) CreateBookmarkObject(details *types.Struct, getContent Content objectId = rec.Details.Fields[bundle.RelationKeyId.String()].GetStringValue() } else { details.Fields[bundle.RelationKeyType.String()] = pbtypes.String(bundle.TypeKeyBookmark.URL()) - objectId, newDetails, err = s.creator.CreateSmartBlockFromState(context.TODO(), coresb.SmartBlockTypePage, details, nil, nil) + objectId, newDetails, err = s.creator.CreateSmartBlockFromState(context.TODO(), coresb.SmartBlockTypePage, details, nil) if err != nil { return "", nil, fmt.Errorf("create bookmark object: %w", err) } diff --git a/core/block/create.go b/core/block/create.go index b9d71780e..13ea6db6c 100644 --- a/core/block/create.go +++ b/core/block/create.go @@ -30,7 +30,7 @@ func (s *Service) TemplateCreateFromObject(id string) (templateID string, err er return } - templateID, _, err = s.objectCreator.CreateSmartBlockFromState(context.TODO(), coresb.SmartBlockTypeTemplate, nil, nil, st) + templateID, _, err = s.objectCreator.CreateSmartBlockFromState(context.TODO(), coresb.SmartBlockTypeTemplate, nil, st) if err != nil { return } @@ -56,7 +56,7 @@ func (s *Service) TemplateClone(id string) (templateID string, err error) { }); err != nil { return } - templateID, _, err = s.objectCreator.CreateSmartBlockFromState(context.TODO(), coresb.SmartBlockTypeTemplate, nil, nil, st) + templateID, _, err = s.objectCreator.CreateSmartBlockFromState(context.TODO(), coresb.SmartBlockTypeTemplate, nil, st) if err != nil { return } @@ -81,7 +81,7 @@ func (s *Service) ObjectDuplicate(id string) (objectID string, err error) { return } - objectID, _, err = s.objectCreator.CreateSmartBlockFromState(context.TODO(), sbt, nil, nil, st) + objectID, _, err = s.objectCreator.CreateSmartBlockFromState(context.TODO(), sbt, nil, st) if err != nil { return } @@ -95,7 +95,7 @@ func (s *Service) TemplateCreateFromObjectByObjectType(otID string) (templateID var st = state.NewDoc("", nil).(*state.State) st.SetDetail(bundle.RelationKeyTargetObjectType.String(), pbtypes.String(otID)) st.SetObjectTypes([]string{bundle.TypeKeyTemplate.URL(), otID}) - templateID, _, err = s.objectCreator.CreateSmartBlockFromState(context.TODO(), coresb.SmartBlockTypeTemplate, nil, nil, st) + templateID, _, err = s.objectCreator.CreateSmartBlockFromState(context.TODO(), coresb.SmartBlockTypeTemplate, nil, st) if err != nil { return } @@ -103,13 +103,12 @@ func (s *Service) TemplateCreateFromObjectByObjectType(otID string) (templateID } func (s *Service) CreateWorkspace(req *pb.RpcWorkspaceCreateRequest) (workspaceID string, err error) { - id, _, err := s.objectCreator.CreateSmartBlockFromState(context.TODO(), coresb.SmartBlockTypeWorkspace, - &types.Struct{Fields: map[string]*types.Value{ - bundle.RelationKeyName.String(): pbtypes.String(req.Name), - bundle.RelationKeyType.String(): pbtypes.String(bundle.TypeKeySpace.URL()), - bundle.RelationKeyIconEmoji.String(): pbtypes.String("🌎"), - bundle.RelationKeyLayout.String(): pbtypes.Float64(float64(model.ObjectType_space)), - }}, nil, nil) + id, _, err := s.objectCreator.CreateSmartBlockFromState(context.TODO(), coresb.SmartBlockTypeWorkspace, &types.Struct{Fields: map[string]*types.Value{ + bundle.RelationKeyName.String(): pbtypes.String(req.Name), + bundle.RelationKeyType.String(): pbtypes.String(bundle.TypeKeySpace.URL()), + bundle.RelationKeyIconEmoji.String(): pbtypes.String("🌎"), + bundle.RelationKeyLayout.String(): pbtypes.Float64(float64(model.ObjectType_space)), + }}, nil) return id, err } diff --git a/core/block/editor/basic/extract_objects.go b/core/block/editor/basic/extract_objects.go index 31c2d5963..113977a59 100644 --- a/core/block/editor/basic/extract_objects.go +++ b/core/block/editor/basic/extract_objects.go @@ -19,7 +19,7 @@ import ( ) type ObjectCreator interface { - CreateSmartBlockFromState(ctx context.Context, sbType coresb.SmartBlockType, details *types.Struct, relationIds []string, createState *state.State) (id string, newDetails *types.Struct, err error) + CreateSmartBlockFromState(ctx context.Context, sbType coresb.SmartBlockType, details *types.Struct, createState *state.State) (id string, newDetails *types.Struct, err error) InjectWorkspaceID(details *types.Struct, objectID string) } @@ -72,7 +72,7 @@ func (bs *basic) ExtractBlocksToObjects(ctx *session.Context, s ObjectCreator, r det := &types.Struct{Fields: fields} s.InjectWorkspaceID(det, req.ContextId) - objectID, _, err := s.CreateSmartBlockFromState(context.TODO(), coresb.SmartBlockTypePage, det, nil, objState) + objectID, _, err := s.CreateSmartBlockFromState(context.TODO(), coresb.SmartBlockTypePage, det, objState) if err != nil { return nil, fmt.Errorf("create child object: %w", err) } diff --git a/core/block/editor/basic/extract_objects_test.go b/core/block/editor/basic/extract_objects_test.go index 12b109e6e..792e6e2a9 100644 --- a/core/block/editor/basic/extract_objects_test.go +++ b/core/block/editor/basic/extract_objects_test.go @@ -26,7 +26,7 @@ func (t testExtractObjects) Add(object *smarttest.SmartTest) { t.objects[object.Id()] = object } -func (t testExtractObjects) CreateSmartBlockFromState(ctx context.Context, sbType coresb.SmartBlockType, details *types.Struct, relationIds []string, createState *state.State) (id string, newDetails *types.Struct, err error) { +func (t testExtractObjects) CreateSmartBlockFromState(ctx context.Context, sbType coresb.SmartBlockType, details *types.Struct, createState *state.State) (id string, newDetails *types.Struct, err error) { id = bson.NewObjectId().Hex() object := smarttest.New(id) t.objects[id] = object diff --git a/core/block/editor/smartblock/smartblock.go b/core/block/editor/smartblock/smartblock.go index 51a2fb589..e70e3478e 100644 --- a/core/block/editor/smartblock/smartblock.go +++ b/core/block/editor/smartblock/smartblock.go @@ -131,7 +131,7 @@ type SmartBlock interface { type InitContext struct { Source source.Source ObjectTypeUrls []string - RelationIds []string + RelationKeys []string State *state.State Relations []*model.Relation Restriction restriction.Service @@ -256,7 +256,7 @@ func (sb *smartBlock) Init(ctx *InitContext) (err error) { return err } } - if err = sb.addRelations(ctx.State, ctx.RelationIds...); err != nil { + if err = sb.addRelations(ctx.State, ctx.RelationKeys...); err != nil { return } diff --git a/core/block/editor/template/template.go b/core/block/editor/template/template.go index 00b7cdc2e..931254d07 100644 --- a/core/block/editor/template/template.go +++ b/core/block/editor/template/template.go @@ -562,7 +562,21 @@ var WithDataviewRelationMigrationRelation = func(id string, source string, from var WithDataviewRequiredRelation = func(id string, key bundle.RelationKey) StateTransformer { return func(s *state.State) { + found := false + for _, r := range bundle.SystemRelations { + if r.String() == key.String() { + found = true + break + } + } rel := bundle.MustGetRelation(key) + if rel == nil { + return + } + if !found { + log.Errorf("WithDataviewRequiredRelation got not system relation %s; ignore", key) + return + } b := s.Get(id) if b == nil { return @@ -576,10 +590,11 @@ var WithDataviewRequiredRelation = func(id string, key bundle.RelationKey) State if dv == nil { return } - if exRel := pbtypes.GetRelation(dv.Relations, key.String()); exRel == nil { - dv.Relations = append(dv.Relations, rel) + if slice.FindPos(pbtypes.GetRelationListKeys(dv.RelationLinks), key.String()) == -1 { + dv.RelationLinks = append(dv.RelationLinks, &model.RelationLink{Key: key.String(), Format: rel.Format}) blockNeedToUpdate = true } + for i, view := range dv.Views { if view.Relations == nil { continue diff --git a/core/block/import/objectcreator.go b/core/block/import/objectcreator.go index 121db39fd..9636c679d 100644 --- a/core/block/import/objectcreator.go +++ b/core/block/import/objectcreator.go @@ -25,7 +25,7 @@ import ( ) type objectCreator interface { - CreateSmartBlockFromState(ctx context.Context, sbType coresb.SmartBlockType, details *types.Struct, relationIds []string, createState *state.State) (id string, newDetails *types.Struct, err error) + CreateSmartBlockFromState(ctx context.Context, sbType coresb.SmartBlockType, details *types.Struct, createState *state.State) (id string, newDetails *types.Struct, err error) CreateSubObjectInWorkspace(details *types.Struct, workspaceID string) (id string, newDetails *types.Struct, err error) CreateSubObjectsInWorkspace(details []*types.Struct) (ids []string, objects []*types.Struct, err error) } @@ -113,7 +113,7 @@ func (oc *ObjectCreator) Create(ctx *session.Context, } }() - newID, details, err := oc.objCreator.CreateSmartBlockFromState(context.TODO(), sbType, nil, nil, st) + newID, details, err := oc.objCreator.CreateSmartBlockFromState(context.TODO(), sbType, nil, st) if err != nil { return nil, fmt.Errorf("create object '%s'", st.RootId()) } diff --git a/core/block/object/creator.go b/core/block/object/creator.go index fef7492cb..fed943a66 100644 --- a/core/block/object/creator.go +++ b/core/block/object/creator.go @@ -21,6 +21,7 @@ import ( "github.com/anytypeio/go-anytype-middleware/pkg/lib/bundle" "github.com/anytypeio/go-anytype-middleware/pkg/lib/core" coresb "github.com/anytypeio/go-anytype-middleware/pkg/lib/core/smartblock" + "github.com/anytypeio/go-anytype-middleware/pkg/lib/localstore/addr" "github.com/anytypeio/go-anytype-middleware/pkg/lib/localstore/objectstore" "github.com/anytypeio/go-anytype-middleware/pkg/lib/logging" "github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/model" @@ -75,7 +76,7 @@ type BlockService interface { StateFromTemplate(templateID, name string) (st *state.State, err error) } -func (c *Creator) CreateSmartBlockFromTemplate(ctx context.Context, sbType coresb.SmartBlockType, details *types.Struct, relationIds []string, templateID string) (id string, newDetails *types.Struct, err error) { +func (c *Creator) CreateSmartBlockFromTemplate(ctx context.Context, sbType coresb.SmartBlockType, details *types.Struct, templateID string) (id string, newDetails *types.Struct, err error) { var createState *state.State if templateID != "" { if createState, err = c.blockService.StateFromTemplate(templateID, pbtypes.GetString(details, bundle.RelationKeyName.String())); err != nil { @@ -84,10 +85,10 @@ func (c *Creator) CreateSmartBlockFromTemplate(ctx context.Context, sbType cores } else { createState = state.NewDoc("", nil).NewState() } - return c.CreateSmartBlockFromState(ctx, sbType, details, relationIds, createState) + return c.CreateSmartBlockFromState(ctx, sbType, details, createState) } -func (c *Creator) CreateSmartBlockFromState(ctx context.Context, sbType coresb.SmartBlockType, details *types.Struct, relationIds []string, createState *state.State) (id string, newDetails *types.Struct, err error) { +func (c *Creator) CreateSmartBlockFromState(ctx context.Context, sbType coresb.SmartBlockType, details *types.Struct, createState *state.State) (id string, newDetails *types.Struct, err error) { if createState == nil { createState = state.NewDoc("", nil).(*state.State) } @@ -107,11 +108,18 @@ func (c *Creator) CreateSmartBlockFromState(ctx context.Context, sbType coresb.S } } + var relationKeys []string var workspaceID string if details != nil && details.Fields != nil { for k, v := range details.Fields { + relId := addr.RelationKeyToIdPrefix + k + if _, err2 := c.objectStore.GetRelationById(relId); err != nil { + // check if installed + err = fmt.Errorf("failed to get installed relation %s: %w", relId, err2) + return + } + relationKeys = append(relationKeys, k) createState.SetDetail(k, v) - // TODO: add relations to relationIds } detailsWorkspaceID := details.Fields[bundle.RelationKeyWorkspaceId.String()] @@ -161,7 +169,7 @@ func (c *Creator) CreateSmartBlockFromState(ctx context.Context, sbType coresb.S initCtx := &smartblock.InitContext{ ObjectTypeUrls: objectTypes, State: createState, - RelationIds: relationIds, + RelationKeys: relationKeys, } var sb smartblock.SmartBlock @@ -258,7 +266,7 @@ func (c *Creator) CreateSet(req *pb.RpcObjectCreateSetRequest) (setID string, ne } // TODO: here can be a deadlock if this is somehow created from workspace (as set) - return c.CreateSmartBlockFromState(context.TODO(), coresb.SmartBlockTypeSet, nil, nil, newState) + return c.CreateSmartBlockFromState(context.TODO(), coresb.SmartBlockTypeSet, nil, newState) } // TODO: it must be in another component @@ -349,5 +357,5 @@ func (c *Creator) CreateObject(req block.DetailsGetter, forcedType bundle.TypeKe sbType = coresb.SmartBlockTypeTemplate } - return c.CreateSmartBlockFromTemplate(context.TODO(), sbType, details, nil, templateID) + return c.CreateSmartBlockFromTemplate(context.TODO(), sbType, details, templateID) } diff --git a/core/block/service.go b/core/block/service.go index 7ed276b85..7b1a6abfb 100644 --- a/core/block/service.go +++ b/core/block/service.go @@ -114,7 +114,7 @@ func New() *Service { } type objectCreator interface { - CreateSmartBlockFromState(ctx context.Context, sbType coresb.SmartBlockType, details *types.Struct, relationIds []string, createState *state.State) (id string, newDetails *types.Struct, err error) + CreateSmartBlockFromState(ctx context.Context, sbType coresb.SmartBlockType, details *types.Struct, createState *state.State) (id string, newDetails *types.Struct, err error) InjectWorkspaceID(details *types.Struct, objectID string) CreateObject(req DetailsGetter, forcedType bundle.TypeKey) (id string, details *types.Struct, err error) diff --git a/pkg/lib/bundle/init.go b/pkg/lib/bundle/init.go index ffca9c5f9..ac45469ba 100644 --- a/pkg/lib/bundle/init.go +++ b/pkg/lib/bundle/init.go @@ -4,10 +4,11 @@ import ( "fmt" "strings" + types2 "github.com/gogo/protobuf/types" + coresb "github.com/anytypeio/go-anytype-middleware/pkg/lib/core/smartblock" "github.com/anytypeio/go-anytype-middleware/pkg/lib/localstore/addr" "github.com/anytypeio/go-anytype-middleware/pkg/lib/pb/model" - types2 "github.com/gogo/protobuf/types" "github.com/anytypeio/go-anytype-middleware/util/pbtypes" ) @@ -59,6 +60,7 @@ var SystemRelations = append(RequiredInternalRelations, []RelationKey{ RelationKeyIsReadonly, RelationKeyIsDeleted, RelationKeyIsHidden, + RelationKeyDone, RelationKeyIsArchived, RelationKeyTemplateIsBundled, RelationKeyTag, diff --git a/util/builtinobjects/builtinobjects.go b/util/builtinobjects/builtinobjects.go index 31b7f38f7..e517374ed 100644 --- a/util/builtinobjects/builtinobjects.go +++ b/util/builtinobjects/builtinobjects.go @@ -58,7 +58,7 @@ type BuiltinObjects interface { } type objectCreator interface { - CreateSmartBlockFromState(ctx context.Context, sbType coresb.SmartBlockType, details *types.Struct, relationIds []string, createState *state.State) (id string, newDetails *types.Struct, err error) + CreateSmartBlockFromState(ctx context.Context, sbType coresb.SmartBlockType, details *types.Struct, createState *state.State) (id string, newDetails *types.Struct, err error) } type builtinObjects struct { @@ -257,7 +257,7 @@ func (b *builtinObjects) createObject(ctx context.Context, rd io.ReadCloser) (er return err } - _, _, err = b.objectCreator.CreateSmartBlockFromState(ctx, sbt, nil, nil, st) + _, _, err = b.objectCreator.CreateSmartBlockFromState(ctx, sbt, nil, st) if isFavorite { err = b.service.SetPageIsFavorite(pb.RpcObjectSetIsFavoriteRequest{ContextId: newId, IsFavorite: true}) if err != nil {