diff --git a/core/api/model/property.go b/core/api/model/property.go index b8b3fbf7d..3900b174b 100644 --- a/core/api/model/property.go +++ b/core/api/model/property.go @@ -44,10 +44,12 @@ type PropertyResponse struct { type CreatePropertyRequest struct { Name string `json:"name" binding:"required" example:"Last modified date"` // The name of the property Format PropertyFormat `json:"format" binding:"required" enums:"text,number,select,multi_select,date,files,checkbox,url,email,phone,objects"` // The format of the property + Key *string `json:"key,omitempty" example:"some_user_defined_property_key"` // The key of the property } type UpdatePropertyRequest struct { Name *string `json:"name,omitempty" binding:"required" example:"Last modified date"` // The name to set for the property + Key *string `json:"key,omitempty" example:"some_user_defined_property_key"` // The key to set for the property } type Property struct { diff --git a/core/api/service/list_test.go b/core/api/service/list_test.go index 41322749a..006455bcf 100644 --- a/core/api/service/list_test.go +++ b/core/api/service/list_test.go @@ -428,6 +428,7 @@ func TestListService_GetObjectsInList(t *testing.T) { Keys: []string{ bundle.RelationKeyId.String(), bundle.RelationKeyRelationKey.String(), + bundle.RelationKeyApiId.String(), bundle.RelationKeyName.String(), bundle.RelationKeyRelationFormat.String(), }, @@ -673,6 +674,7 @@ func TestListService_GetObjectsInList(t *testing.T) { Keys: []string{ bundle.RelationKeyId.String(), bundle.RelationKeyRelationKey.String(), + bundle.RelationKeyApiId.String(), bundle.RelationKeyName.String(), bundle.RelationKeyRelationFormat.String(), }, @@ -1128,6 +1130,7 @@ func TestListService_GetObjectsInList(t *testing.T) { Keys: []string{ bundle.RelationKeyId.String(), bundle.RelationKeyRelationKey.String(), + bundle.RelationKeyApiId.String(), bundle.RelationKeyName.String(), bundle.RelationKeyRelationFormat.String(), }, diff --git a/core/api/service/object_test.go b/core/api/service/object_test.go index d86cf344b..12ae5e34c 100644 --- a/core/api/service/object_test.go +++ b/core/api/service/object_test.go @@ -89,6 +89,7 @@ func TestObjectService_ListObjects(t *testing.T) { Keys: []string{ bundle.RelationKeyId.String(), bundle.RelationKeyRelationKey.String(), + bundle.RelationKeyApiId.String(), bundle.RelationKeyName.String(), bundle.RelationKeyRelationFormat.String(), }, @@ -381,6 +382,7 @@ func TestObjectService_GetObject(t *testing.T) { Keys: []string{ bundle.RelationKeyId.String(), bundle.RelationKeyRelationKey.String(), + bundle.RelationKeyApiId.String(), bundle.RelationKeyName.String(), bundle.RelationKeyRelationFormat.String(), }, diff --git a/core/api/service/property.go b/core/api/service/property.go index 72cb5b02a..b9233e2a0 100644 --- a/core/api/service/property.go +++ b/core/api/service/property.go @@ -129,6 +129,7 @@ func (s *Service) ListProperties(ctx context.Context, spaceId string, offset int Keys: []string{ bundle.RelationKeyId.String(), bundle.RelationKeyRelationKey.String(), + bundle.RelationKeyApiId.String(), bundle.RelationKeyName.String(), bundle.RelationKeyRelationFormat.String(), }, @@ -191,12 +192,19 @@ func (s *Service) GetProperty(ctx context.Context, spaceId string, propertyId st func (s *Service) CreateProperty(ctx context.Context, spaceId string, request apimodel.CreatePropertyRequest) (apimodel.Property, error) { details := &types.Struct{ Fields: map[string]*types.Value{ - bundle.RelationKeyName.String(): pbtypes.String(request.Name), + bundle.RelationKeyName.String(): pbtypes.String(s.sanitizedString(request.Name)), bundle.RelationKeyRelationFormat.String(): pbtypes.Int64(int64(PropertyFormatToRelationFormat[request.Format])), bundle.RelationKeyOrigin.String(): pbtypes.Int64(int64(model.ObjectOrigin_api)), }, } + if request.Key != nil { + details.Fields[bundle.RelationKeyApiId.String()] = pbtypes.String(s.sanitizedString(*request.Key)) + } else { + // TODO: transliterate instead + details.Fields[bundle.RelationKeyApiId.String()] = pbtypes.String(strings.ReplaceAll(request.Name, " ", "_")) + } + resp := s.mw.ObjectCreateRelation(ctx, &pb.RpcObjectCreateRelationRequest{ SpaceId: spaceId, Details: details, @@ -220,17 +228,25 @@ func (s *Service) UpdateProperty(ctx context.Context, spaceId string, propertyId return apimodel.Property{}, ErrPropertyCannotBeUpdated } + var detailsToUpdate []*model.Detail if request.Name != nil { - detail := model.Detail{ + detailsToUpdate = append(detailsToUpdate, &model.Detail{ Key: bundle.RelationKeyName.String(), Value: pbtypes.String(s.sanitizedString(*request.Name)), - } + }) + } + if request.Key != nil { + detailsToUpdate = append(detailsToUpdate, &model.Detail{ + Key: bundle.RelationKeyApiId.String(), + Value: pbtypes.String(s.sanitizedString(*request.Key)), + }) + } + if len(detailsToUpdate) > 0 { resp := s.mw.ObjectSetDetails(ctx, &pb.RpcObjectSetDetailsRequest{ ContextId: propertyId, - Details: []*model.Detail{&detail}, + Details: detailsToUpdate, }) - if resp.Error != nil && resp.Error.Code != pb.RpcObjectSetDetailsResponseError_NULL { return apimodel.Property{}, ErrFailedUpdateProperty } @@ -536,6 +552,7 @@ func (s *Service) getPropertyMapFromStore(ctx context.Context, spaceId string, k Keys: []string{ bundle.RelationKeyId.String(), bundle.RelationKeyRelationKey.String(), + bundle.RelationKeyApiId.String(), bundle.RelationKeyName.String(), bundle.RelationKeyRelationFormat.String(), }, @@ -561,10 +578,19 @@ func (s *Service) getPropertyMapFromStore(ctx context.Context, spaceId string, k // getPropertyFromStruct maps a property's details into an apimodel.Property and returns its relation key. func (s *Service) getPropertyFromStruct(details *types.Struct) (string, apimodel.Property) { rk := details.Fields[bundle.RelationKeyRelationKey.String()].GetStringValue() + + // apiId as key takes precedence over relation key + key := util.ToPropertyApiKey(rk) + if apiIDField, exists := details.Fields[bundle.RelationKeyApiId.String()]; exists { + if apiID := apiIDField.GetStringValue(); apiID != "" { + key = apiID + } + } + return rk, apimodel.Property{ Object: "property", Id: details.Fields[bundle.RelationKeyId.String()].GetStringValue(), - Key: util.ToPropertyApiKey(rk), + Key: key, Name: details.Fields[bundle.RelationKeyName.String()].GetStringValue(), Format: RelationFormatToPropertyFormat[model.RelationFormat(details.Fields[bundle.RelationKeyRelationFormat.String()].GetNumberValue())], } diff --git a/core/api/service/search_test.go b/core/api/service/search_test.go index a38d739c1..0274ab043 100644 --- a/core/api/service/search_test.go +++ b/core/api/service/search_test.go @@ -147,6 +147,7 @@ func TestSearchService_GlobalSearch(t *testing.T) { Keys: []string{ bundle.RelationKeyId.String(), bundle.RelationKeyRelationKey.String(), + bundle.RelationKeyApiId.String(), bundle.RelationKeyName.String(), bundle.RelationKeyRelationFormat.String(), }, @@ -456,6 +457,7 @@ func TestSearchService_Search(t *testing.T) { Keys: []string{ bundle.RelationKeyId.String(), bundle.RelationKeyRelationKey.String(), + bundle.RelationKeyApiId.String(), bundle.RelationKeyName.String(), bundle.RelationKeyRelationFormat.String(), }, diff --git a/core/api/service/type_test.go b/core/api/service/type_test.go index 1ef9a1b06..4334a0849 100644 --- a/core/api/service/type_test.go +++ b/core/api/service/type_test.go @@ -54,6 +54,7 @@ func TestObjectService_ListTypes(t *testing.T) { Keys: []string{ bundle.RelationKeyId.String(), bundle.RelationKeyRelationKey.String(), + bundle.RelationKeyApiId.String(), bundle.RelationKeyName.String(), bundle.RelationKeyRelationFormat.String(), }, @@ -110,6 +111,7 @@ func TestObjectService_ListTypes(t *testing.T) { Keys: []string{ bundle.RelationKeyId.String(), bundle.RelationKeyRelationKey.String(), + bundle.RelationKeyApiId.String(), bundle.RelationKeyName.String(), bundle.RelationKeyRelationFormat.String(), }, @@ -175,6 +177,7 @@ func TestObjectService_GetType(t *testing.T) { Keys: []string{ bundle.RelationKeyId.String(), bundle.RelationKeyRelationKey.String(), + bundle.RelationKeyApiId.String(), bundle.RelationKeyName.String(), bundle.RelationKeyRelationFormat.String(), },