Add UX for cookie banner management
Signed-off-by: Émile Ré <emile@getprobo.com>
This commit is contained in:
@@ -332,6 +332,42 @@ func (r *queryResolver) Node(ctx context.Context, id gid.GID) (types.Node, error
|
||||
}
|
||||
return types.NewAccessEntry(entry), nil
|
||||
}
|
||||
case coredata.CookieBannerEntityType:
|
||||
action = probo.ActionCookieBannerGet
|
||||
loadNode = func(ctx context.Context, id gid.GID) (types.Node, error) {
|
||||
scope := coredata.NewScopeFromObjectID(id)
|
||||
banner, err := r.cookieBanner.GetCookieBanner(ctx, scope, id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return types.NewCookieBanner(banner), nil
|
||||
}
|
||||
case coredata.CookieCategoryEntityType:
|
||||
action = probo.ActionCookieCategoryGet
|
||||
loadNode = func(ctx context.Context, id gid.GID) (types.Node, error) {
|
||||
scope := coredata.NewScopeFromObjectID(id)
|
||||
category, err := r.cookieBanner.GetCookieCategory(ctx, scope, id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return types.NewCookieCategory(category), nil
|
||||
}
|
||||
case coredata.CookieBannerVersionEntityType:
|
||||
action = probo.ActionCookieBannerVersionGet
|
||||
loadNode = func(ctx context.Context, id gid.GID) (types.Node, error) {
|
||||
scope := coredata.NewScopeFromObjectID(id)
|
||||
version, err := r.cookieBanner.GetCookieBannerVersion(ctx, scope, id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &types.CookieBannerVersion{
|
||||
ID: version.ID,
|
||||
Version: version.Version,
|
||||
State: string(version.State),
|
||||
CreatedAt: version.CreatedAt,
|
||||
UpdatedAt: version.UpdatedAt,
|
||||
}, nil
|
||||
}
|
||||
default:
|
||||
}
|
||||
|
||||
|
||||
463
pkg/server/api/console/v1/cookie_banner_resolvers.go
Normal file
463
pkg/server/api/console/v1/cookie_banner_resolvers.go
Normal file
@@ -0,0 +1,463 @@
|
||||
package console_v1
|
||||
|
||||
// This file will be automatically regenerated based on the schema, any resolver
|
||||
// implementations
|
||||
// will be copied through when generating and any unknown code will be moved to the end.
|
||||
// Code generated by github.com/99designs/gqlgen version v0.17.87
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
"go.gearno.de/kit/log"
|
||||
"go.probo.inc/probo/pkg/cookiebanner"
|
||||
"go.probo.inc/probo/pkg/coredata"
|
||||
"go.probo.inc/probo/pkg/page"
|
||||
"go.probo.inc/probo/pkg/probo"
|
||||
"go.probo.inc/probo/pkg/server/api/console/v1/schema"
|
||||
"go.probo.inc/probo/pkg/server/api/console/v1/types"
|
||||
"go.probo.inc/probo/pkg/server/gqlutils"
|
||||
"go.probo.inc/probo/pkg/validator"
|
||||
)
|
||||
|
||||
// Organization is the resolver for the organization field.
|
||||
func (r *cookieBannerResolver) Organization(ctx context.Context, obj *types.CookieBanner) (*types.Organization, error) {
|
||||
return obj.Organization, nil
|
||||
}
|
||||
|
||||
// Categories is the resolver for the categories field.
|
||||
func (r *cookieBannerResolver) Categories(ctx context.Context, obj *types.CookieBanner, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.CookieCategoryOrderBy) (*types.CookieCategoryConnection, error) {
|
||||
if err := r.authorize(ctx, obj.ID, probo.ActionCookieCategoryList); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
pageOrderBy := page.OrderBy[coredata.CookieCategoryOrderField]{
|
||||
Field: coredata.CookieCategoryOrderFieldRank,
|
||||
Direction: page.OrderDirectionAsc,
|
||||
}
|
||||
if orderBy != nil {
|
||||
pageOrderBy = page.OrderBy[coredata.CookieCategoryOrderField]{
|
||||
Field: orderBy.Field,
|
||||
Direction: orderBy.Direction,
|
||||
}
|
||||
}
|
||||
|
||||
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
|
||||
scope := coredata.NewScopeFromObjectID(obj.ID)
|
||||
|
||||
categories, err := r.cookieBanner.ListCookieCategoriesForBanner(ctx, scope, obj.ID, cursor)
|
||||
if err != nil {
|
||||
r.logger.ErrorCtx(ctx, "cannot list cookie categories", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
p := page.NewPage(categories, cursor)
|
||||
|
||||
return types.NewCookieCategoryConnection(p, r, obj.ID), nil
|
||||
}
|
||||
|
||||
// LatestVersion is the resolver for the latestVersion field.
|
||||
func (r *cookieBannerResolver) LatestVersion(ctx context.Context, obj *types.CookieBanner) (*types.CookieBannerVersion, error) {
|
||||
if err := r.authorize(ctx, obj.ID, probo.ActionCookieBannerVersionList); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
scope := coredata.NewScopeFromObjectID(obj.ID)
|
||||
|
||||
cursor := &page.Cursor[coredata.CookieBannerVersionOrderField]{
|
||||
Size: 1,
|
||||
Position: page.Head,
|
||||
OrderBy: page.OrderBy[coredata.CookieBannerVersionOrderField]{
|
||||
Field: coredata.CookieBannerVersionOrderFieldCreatedAt,
|
||||
Direction: page.OrderDirectionDesc,
|
||||
},
|
||||
}
|
||||
|
||||
versions, err := r.cookieBanner.ListCookieBannerVersionsForBanner(ctx, scope, obj.ID, cursor)
|
||||
if err != nil {
|
||||
r.logger.ErrorCtx(ctx, "cannot load latest cookie banner version", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
if len(versions) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
v := versions[0]
|
||||
return &types.CookieBannerVersion{
|
||||
ID: v.ID,
|
||||
Version: v.Version,
|
||||
State: string(v.State),
|
||||
CreatedAt: v.CreatedAt,
|
||||
UpdatedAt: v.UpdatedAt,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Permission is the resolver for the permission field.
|
||||
func (r *cookieBannerResolver) Permission(ctx context.Context, obj *types.CookieBanner, action string) (bool, error) {
|
||||
return r.Resolver.Permission(ctx, obj, action)
|
||||
}
|
||||
|
||||
// TotalCount is the resolver for the totalCount field.
|
||||
func (r *cookieBannerConnectionResolver) TotalCount(ctx context.Context, obj *types.CookieBannerConnection) (int, error) {
|
||||
if err := r.authorize(ctx, obj.ParentID, probo.ActionCookieBannerList); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
scope := coredata.NewScopeFromObjectID(obj.ParentID)
|
||||
|
||||
count, err := r.cookieBanner.CountCookieBannersForOrganization(ctx, scope, obj.ParentID, coredata.NewCookieBannerFilter(nil))
|
||||
if err != nil {
|
||||
r.logger.ErrorCtx(ctx, "cannot count cookie banners", log.Error(err))
|
||||
return 0, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return count, nil
|
||||
}
|
||||
|
||||
// CookieBanner is the resolver for the cookieBanner field.
|
||||
func (r *cookieCategoryResolver) CookieBanner(ctx context.Context, obj *types.CookieCategory) (*types.CookieBanner, error) {
|
||||
return obj.CookieBanner, nil
|
||||
}
|
||||
|
||||
// Permission is the resolver for the permission field.
|
||||
func (r *cookieCategoryResolver) Permission(ctx context.Context, obj *types.CookieCategory, action string) (bool, error) {
|
||||
return r.Resolver.Permission(ctx, obj, action)
|
||||
}
|
||||
|
||||
// TotalCount is the resolver for the totalCount field.
|
||||
func (r *cookieCategoryConnectionResolver) TotalCount(ctx context.Context, obj *types.CookieCategoryConnection) (int, error) {
|
||||
if err := r.authorize(ctx, obj.ParentID, probo.ActionCookieCategoryList); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
scope := coredata.NewScopeFromObjectID(obj.ParentID)
|
||||
|
||||
count, err := r.cookieBanner.CountCookieCategoriesForBanner(ctx, scope, obj.ParentID)
|
||||
if err != nil {
|
||||
r.logger.ErrorCtx(ctx, "cannot count cookie categories", log.Error(err))
|
||||
return 0, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return count, nil
|
||||
}
|
||||
|
||||
// CreateCookieBanner is the resolver for the createCookieBanner field.
|
||||
func (r *mutationResolver) CreateCookieBanner(ctx context.Context, input types.CreateCookieBannerInput) (*types.CreateCookieBannerPayload, error) {
|
||||
if err := r.authorize(ctx, input.OrganizationID, probo.ActionCookieBannerCreate); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
scope := coredata.NewScopeFromObjectID(input.OrganizationID)
|
||||
|
||||
banner, err := r.cookieBanner.CreateCookieBanner(
|
||||
ctx,
|
||||
scope,
|
||||
cookiebanner.CreateCookieBannerRequest{
|
||||
OrganizationID: input.OrganizationID,
|
||||
Name: input.Name,
|
||||
Origin: input.Origin,
|
||||
PrivacyPolicyURL: input.PrivacyPolicyURL,
|
||||
ConsentExpiryDays: input.ConsentExpiryDays,
|
||||
ConsentMode: input.ConsentMode,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
if errors.Is(err, cookiebanner.ErrOriginAlreadyInUse) {
|
||||
return nil, gqlutils.Conflict(ctx, err)
|
||||
}
|
||||
if validationErrors, ok := errors.AsType[validator.ValidationErrors](err); ok {
|
||||
return nil, gqlutils.InvalidValidationErrors(ctx, validationErrors)
|
||||
}
|
||||
r.logger.ErrorCtx(ctx, "cannot create cookie banner", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return &types.CreateCookieBannerPayload{
|
||||
CookieBannerEdge: types.NewCookieBannerEdge(banner, coredata.CookieBannerOrderFieldCreatedAt),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// UpdateCookieBanner is the resolver for the updateCookieBanner field.
|
||||
func (r *mutationResolver) UpdateCookieBanner(ctx context.Context, input types.UpdateCookieBannerInput) (*types.UpdateCookieBannerPayload, error) {
|
||||
if err := r.authorize(ctx, input.CookieBannerID, probo.ActionCookieBannerUpdate); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
scope := coredata.NewScopeFromObjectID(input.CookieBannerID)
|
||||
|
||||
banner, err := r.cookieBanner.UpdateCookieBanner(
|
||||
ctx,
|
||||
scope,
|
||||
cookiebanner.UpdateCookieBannerRequest{
|
||||
CookieBannerID: input.CookieBannerID,
|
||||
Name: input.Name,
|
||||
Origin: input.Origin,
|
||||
PrivacyPolicyURL: input.PrivacyPolicyURL,
|
||||
ConsentExpiryDays: input.ConsentExpiryDays,
|
||||
ConsentMode: input.ConsentMode,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
if errors.Is(err, cookiebanner.ErrBannerNotFound) {
|
||||
return nil, gqlutils.NotFound(ctx, err)
|
||||
}
|
||||
if errors.Is(err, cookiebanner.ErrOriginAlreadyInUse) {
|
||||
return nil, gqlutils.Conflict(ctx, err)
|
||||
}
|
||||
if validationErrors, ok := errors.AsType[validator.ValidationErrors](err); ok {
|
||||
return nil, gqlutils.InvalidValidationErrors(ctx, validationErrors)
|
||||
}
|
||||
r.logger.ErrorCtx(ctx, "cannot update cookie banner", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return &types.UpdateCookieBannerPayload{
|
||||
CookieBanner: types.NewCookieBanner(banner),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// DeleteCookieBanner is the resolver for the deleteCookieBanner field.
|
||||
func (r *mutationResolver) DeleteCookieBanner(ctx context.Context, input types.DeleteCookieBannerInput) (*types.DeleteCookieBannerPayload, error) {
|
||||
if err := r.authorize(ctx, input.CookieBannerID, probo.ActionCookieBannerDelete); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
scope := coredata.NewScopeFromObjectID(input.CookieBannerID)
|
||||
|
||||
err := r.cookieBanner.DeleteCookieBanner(ctx, scope, input.CookieBannerID)
|
||||
if err != nil {
|
||||
if errors.Is(err, cookiebanner.ErrBannerNotFound) {
|
||||
return nil, gqlutils.NotFound(ctx, err)
|
||||
}
|
||||
r.logger.ErrorCtx(ctx, "cannot delete cookie banner", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return &types.DeleteCookieBannerPayload{
|
||||
DeletedCookieBannerID: input.CookieBannerID,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// ActivateCookieBanner is the resolver for the activateCookieBanner field.
|
||||
func (r *mutationResolver) ActivateCookieBanner(ctx context.Context, input types.ActivateCookieBannerInput) (*types.ActivateCookieBannerPayload, error) {
|
||||
if err := r.authorize(ctx, input.CookieBannerID, probo.ActionCookieBannerActivate); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
scope := coredata.NewScopeFromObjectID(input.CookieBannerID)
|
||||
|
||||
banner, err := r.cookieBanner.ActivateCookieBanner(ctx, scope, input.CookieBannerID)
|
||||
if err != nil {
|
||||
if errors.Is(err, cookiebanner.ErrBannerNotFound) {
|
||||
return nil, gqlutils.NotFound(ctx, err)
|
||||
}
|
||||
if errors.Is(err, cookiebanner.ErrBannerAlreadyActive) {
|
||||
return nil, gqlutils.Conflict(ctx, err)
|
||||
}
|
||||
if errors.Is(err, cookiebanner.ErrOriginAlreadyInUse) {
|
||||
return nil, gqlutils.Conflict(ctx, err)
|
||||
}
|
||||
r.logger.ErrorCtx(ctx, "cannot activate cookie banner", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return &types.ActivateCookieBannerPayload{
|
||||
CookieBanner: types.NewCookieBanner(banner),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// DeactivateCookieBanner is the resolver for the deactivateCookieBanner field.
|
||||
func (r *mutationResolver) DeactivateCookieBanner(ctx context.Context, input types.DeactivateCookieBannerInput) (*types.DeactivateCookieBannerPayload, error) {
|
||||
if err := r.authorize(ctx, input.CookieBannerID, probo.ActionCookieBannerDeactivate); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
scope := coredata.NewScopeFromObjectID(input.CookieBannerID)
|
||||
|
||||
banner, err := r.cookieBanner.DeactivateCookieBanner(ctx, scope, input.CookieBannerID)
|
||||
if err != nil {
|
||||
if errors.Is(err, cookiebanner.ErrBannerNotFound) {
|
||||
return nil, gqlutils.NotFound(ctx, err)
|
||||
}
|
||||
if errors.Is(err, cookiebanner.ErrBannerAlreadyInactive) {
|
||||
return nil, gqlutils.Conflict(ctx, err)
|
||||
}
|
||||
r.logger.ErrorCtx(ctx, "cannot deactivate cookie banner", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return &types.DeactivateCookieBannerPayload{
|
||||
CookieBanner: types.NewCookieBanner(banner),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// PublishCookieBannerVersion is the resolver for the publishCookieBannerVersion field.
|
||||
func (r *mutationResolver) PublishCookieBannerVersion(ctx context.Context, input types.PublishCookieBannerVersionInput) (*types.PublishCookieBannerVersionPayload, error) {
|
||||
if err := r.authorize(ctx, input.CookieBannerID, probo.ActionCookieBannerVersionPublish); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
scope := coredata.NewScopeFromObjectID(input.CookieBannerID)
|
||||
|
||||
version, err := r.cookieBanner.PublishCookieBannerVersion(ctx, scope, input.CookieBannerID)
|
||||
if err != nil {
|
||||
if errors.Is(err, cookiebanner.ErrNoDraftVersion) {
|
||||
return nil, gqlutils.Conflict(ctx, err)
|
||||
}
|
||||
r.logger.ErrorCtx(ctx, "cannot publish cookie banner version", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return &types.PublishCookieBannerVersionPayload{
|
||||
CookieBannerVersion: &types.CookieBannerVersion{
|
||||
ID: version.ID,
|
||||
Version: version.Version,
|
||||
State: string(version.State),
|
||||
CreatedAt: version.CreatedAt,
|
||||
UpdatedAt: version.UpdatedAt,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
// CreateCookieCategory is the resolver for the createCookieCategory field.
|
||||
func (r *mutationResolver) CreateCookieCategory(ctx context.Context, input types.CreateCookieCategoryInput) (*types.CreateCookieCategoryPayload, error) {
|
||||
if err := r.authorize(ctx, input.CookieBannerID, probo.ActionCookieCategoryCreate); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
scope := coredata.NewScopeFromObjectID(input.CookieBannerID)
|
||||
|
||||
var cookies coredata.CookieItems
|
||||
if input.Cookies != nil {
|
||||
cookies = make(coredata.CookieItems, len(input.Cookies))
|
||||
for i, c := range input.Cookies {
|
||||
cookies[i] = coredata.CookieItem{
|
||||
Name: c.Name,
|
||||
Duration: c.Duration,
|
||||
Description: c.Description,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
category, err := r.cookieBanner.CreateCookieCategory(
|
||||
ctx,
|
||||
scope,
|
||||
cookiebanner.CreateCookieCategoryRequest{
|
||||
CookieBannerID: input.CookieBannerID,
|
||||
Name: input.Name,
|
||||
Description: input.Description,
|
||||
Required: input.Required,
|
||||
Rank: input.Rank,
|
||||
Cookies: cookies,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
if errors.Is(err, cookiebanner.ErrBannerNotFound) {
|
||||
return nil, gqlutils.NotFound(ctx, err)
|
||||
}
|
||||
if validationErrors, ok := errors.AsType[validator.ValidationErrors](err); ok {
|
||||
return nil, gqlutils.InvalidValidationErrors(ctx, validationErrors)
|
||||
}
|
||||
r.logger.ErrorCtx(ctx, "cannot create cookie category", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return &types.CreateCookieCategoryPayload{
|
||||
CookieCategoryEdge: types.NewCookieCategoryEdge(category, coredata.CookieCategoryOrderFieldRank),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// UpdateCookieCategory is the resolver for the updateCookieCategory field.
|
||||
func (r *mutationResolver) UpdateCookieCategory(ctx context.Context, input types.UpdateCookieCategoryInput) (*types.UpdateCookieCategoryPayload, error) {
|
||||
if err := r.authorize(ctx, input.CookieCategoryID, probo.ActionCookieCategoryUpdate); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
scope := coredata.NewScopeFromObjectID(input.CookieCategoryID)
|
||||
|
||||
var cookies *coredata.CookieItems
|
||||
if input.Cookies != nil {
|
||||
items := make(coredata.CookieItems, len(input.Cookies))
|
||||
for i, c := range input.Cookies {
|
||||
items[i] = coredata.CookieItem{
|
||||
Name: c.Name,
|
||||
Duration: c.Duration,
|
||||
Description: c.Description,
|
||||
}
|
||||
}
|
||||
cookies = &items
|
||||
}
|
||||
|
||||
category, err := r.cookieBanner.UpdateCookieCategory(
|
||||
ctx,
|
||||
scope,
|
||||
cookiebanner.UpdateCookieCategoryRequest{
|
||||
CookieCategoryID: input.CookieCategoryID,
|
||||
Name: input.Name,
|
||||
Description: input.Description,
|
||||
Rank: input.Rank,
|
||||
Cookies: cookies,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
if errors.Is(err, cookiebanner.ErrCategoryNotFound) {
|
||||
return nil, gqlutils.NotFound(ctx, err)
|
||||
}
|
||||
if validationErrors, ok := errors.AsType[validator.ValidationErrors](err); ok {
|
||||
return nil, gqlutils.InvalidValidationErrors(ctx, validationErrors)
|
||||
}
|
||||
r.logger.ErrorCtx(ctx, "cannot update cookie category", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return &types.UpdateCookieCategoryPayload{
|
||||
CookieCategory: types.NewCookieCategory(category),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// DeleteCookieCategory is the resolver for the deleteCookieCategory field.
|
||||
func (r *mutationResolver) DeleteCookieCategory(ctx context.Context, input types.DeleteCookieCategoryInput) (*types.DeleteCookieCategoryPayload, error) {
|
||||
if err := r.authorize(ctx, input.CookieCategoryID, probo.ActionCookieCategoryDelete); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
scope := coredata.NewScopeFromObjectID(input.CookieCategoryID)
|
||||
|
||||
err := r.cookieBanner.DeleteCookieCategory(ctx, scope, input.CookieCategoryID)
|
||||
if err != nil {
|
||||
if errors.Is(err, cookiebanner.ErrCategoryNotFound) {
|
||||
return nil, gqlutils.NotFound(ctx, err)
|
||||
}
|
||||
if errors.Is(err, cookiebanner.ErrCannotDeleteRequiredCategory) {
|
||||
return nil, gqlutils.Conflict(ctx, err)
|
||||
}
|
||||
r.logger.ErrorCtx(ctx, "cannot delete cookie category", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return &types.DeleteCookieCategoryPayload{
|
||||
DeletedCookieCategoryID: input.CookieCategoryID,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// CookieBanner returns schema.CookieBannerResolver implementation.
|
||||
func (r *Resolver) CookieBanner() schema.CookieBannerResolver { return &cookieBannerResolver{r} }
|
||||
|
||||
// CookieBannerConnection returns schema.CookieBannerConnectionResolver implementation.
|
||||
func (r *Resolver) CookieBannerConnection() schema.CookieBannerConnectionResolver {
|
||||
return &cookieBannerConnectionResolver{r}
|
||||
}
|
||||
|
||||
// CookieCategory returns schema.CookieCategoryResolver implementation.
|
||||
func (r *Resolver) CookieCategory() schema.CookieCategoryResolver { return &cookieCategoryResolver{r} }
|
||||
|
||||
// CookieCategoryConnection returns schema.CookieCategoryConnectionResolver implementation.
|
||||
func (r *Resolver) CookieCategoryConnection() schema.CookieCategoryConnectionResolver {
|
||||
return &cookieCategoryConnectionResolver{r}
|
||||
}
|
||||
|
||||
type cookieBannerResolver struct{ *Resolver }
|
||||
type cookieBannerConnectionResolver struct{ *Resolver }
|
||||
type cookieCategoryResolver struct{ *Resolver }
|
||||
type cookieCategoryConnectionResolver struct{ *Resolver }
|
||||
269
pkg/server/api/console/v1/graphql/cookie_banner.graphql
Normal file
269
pkg/server/api/console/v1/graphql/cookie_banner.graphql
Normal file
@@ -0,0 +1,269 @@
|
||||
enum CookieBannerState
|
||||
@goModel(model: "go.probo.inc/probo/pkg/coredata.CookieBannerState") {
|
||||
ACTIVE
|
||||
@goEnum(
|
||||
value: "go.probo.inc/probo/pkg/coredata.CookieBannerStateActive"
|
||||
)
|
||||
INACTIVE
|
||||
@goEnum(
|
||||
value: "go.probo.inc/probo/pkg/coredata.CookieBannerStateInactive"
|
||||
)
|
||||
}
|
||||
|
||||
enum CookieConsentMode
|
||||
@goModel(model: "go.probo.inc/probo/pkg/coredata.CookieConsentMode") {
|
||||
OPT_IN
|
||||
@goEnum(
|
||||
value: "go.probo.inc/probo/pkg/coredata.CookieConsentModeOptIn"
|
||||
)
|
||||
OPT_OUT
|
||||
@goEnum(
|
||||
value: "go.probo.inc/probo/pkg/coredata.CookieConsentModeOptOut"
|
||||
)
|
||||
}
|
||||
|
||||
enum CookieBannerOrderField
|
||||
@goModel(
|
||||
model: "go.probo.inc/probo/pkg/coredata.CookieBannerOrderField"
|
||||
) {
|
||||
CREATED_AT
|
||||
@goEnum(
|
||||
value: "go.probo.inc/probo/pkg/coredata.CookieBannerOrderFieldCreatedAt"
|
||||
)
|
||||
}
|
||||
|
||||
enum CookieCategoryOrderField
|
||||
@goModel(
|
||||
model: "go.probo.inc/probo/pkg/coredata.CookieCategoryOrderField"
|
||||
) {
|
||||
RANK
|
||||
@goEnum(
|
||||
value: "go.probo.inc/probo/pkg/coredata.CookieCategoryOrderFieldRank"
|
||||
)
|
||||
}
|
||||
|
||||
input CookieBannerOrder
|
||||
@goModel(
|
||||
model: "go.probo.inc/probo/pkg/server/api/console/v1/types.CookieBannerOrderBy"
|
||||
) {
|
||||
direction: OrderDirection!
|
||||
field: CookieBannerOrderField!
|
||||
}
|
||||
|
||||
input CookieCategoryOrder
|
||||
@goModel(
|
||||
model: "go.probo.inc/probo/pkg/server/api/console/v1/types.CookieCategoryOrderBy"
|
||||
) {
|
||||
direction: OrderDirection!
|
||||
field: CookieCategoryOrderField!
|
||||
}
|
||||
|
||||
type CookieBanner implements Node {
|
||||
id: ID!
|
||||
name: String!
|
||||
origin: String!
|
||||
state: CookieBannerState!
|
||||
privacyPolicyUrl: String!
|
||||
consentExpiryDays: Int!
|
||||
consentMode: CookieConsentMode!
|
||||
|
||||
organization: Organization! @goField(forceResolver: true)
|
||||
|
||||
categories(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
orderBy: CookieCategoryOrder
|
||||
): CookieCategoryConnection! @goField(forceResolver: true)
|
||||
|
||||
latestVersion: CookieBannerVersion @goField(forceResolver: true)
|
||||
|
||||
createdAt: Datetime!
|
||||
updatedAt: Datetime!
|
||||
|
||||
permission(action: String!): Boolean! @goField(forceResolver: true)
|
||||
}
|
||||
|
||||
type CookieCategory implements Node {
|
||||
id: ID!
|
||||
cookieBanner: CookieBanner! @goField(forceResolver: true)
|
||||
name: String!
|
||||
description: String!
|
||||
required: Boolean!
|
||||
rank: Int!
|
||||
cookies: [CookieItem!]!
|
||||
createdAt: Datetime!
|
||||
updatedAt: Datetime!
|
||||
|
||||
permission(action: String!): Boolean! @goField(forceResolver: true)
|
||||
}
|
||||
|
||||
type CookieItem {
|
||||
name: String!
|
||||
duration: String!
|
||||
description: String!
|
||||
}
|
||||
|
||||
type CookieBannerVersion implements Node {
|
||||
id: ID!
|
||||
version: Int!
|
||||
state: String!
|
||||
createdAt: Datetime!
|
||||
updatedAt: Datetime!
|
||||
}
|
||||
|
||||
type CookieBannerConnection
|
||||
@goModel(
|
||||
model: "go.probo.inc/probo/pkg/server/api/console/v1/types.CookieBannerConnection"
|
||||
) {
|
||||
totalCount: Int! @goField(forceResolver: true)
|
||||
edges: [CookieBannerEdge!]!
|
||||
pageInfo: PageInfo!
|
||||
}
|
||||
|
||||
type CookieBannerEdge {
|
||||
cursor: CursorKey!
|
||||
node: CookieBanner!
|
||||
}
|
||||
|
||||
type CookieCategoryConnection
|
||||
@goModel(
|
||||
model: "go.probo.inc/probo/pkg/server/api/console/v1/types.CookieCategoryConnection"
|
||||
) {
|
||||
totalCount: Int! @goField(forceResolver: true)
|
||||
edges: [CookieCategoryEdge!]!
|
||||
pageInfo: PageInfo!
|
||||
}
|
||||
|
||||
type CookieCategoryEdge {
|
||||
cursor: CursorKey!
|
||||
node: CookieCategory!
|
||||
}
|
||||
|
||||
extend type Mutation {
|
||||
createCookieBanner(
|
||||
input: CreateCookieBannerInput!
|
||||
): CreateCookieBannerPayload!
|
||||
updateCookieBanner(
|
||||
input: UpdateCookieBannerInput!
|
||||
): UpdateCookieBannerPayload!
|
||||
deleteCookieBanner(
|
||||
input: DeleteCookieBannerInput!
|
||||
): DeleteCookieBannerPayload!
|
||||
activateCookieBanner(
|
||||
input: ActivateCookieBannerInput!
|
||||
): ActivateCookieBannerPayload!
|
||||
deactivateCookieBanner(
|
||||
input: DeactivateCookieBannerInput!
|
||||
): DeactivateCookieBannerPayload!
|
||||
publishCookieBannerVersion(
|
||||
input: PublishCookieBannerVersionInput!
|
||||
): PublishCookieBannerVersionPayload!
|
||||
createCookieCategory(
|
||||
input: CreateCookieCategoryInput!
|
||||
): CreateCookieCategoryPayload!
|
||||
updateCookieCategory(
|
||||
input: UpdateCookieCategoryInput!
|
||||
): UpdateCookieCategoryPayload!
|
||||
deleteCookieCategory(
|
||||
input: DeleteCookieCategoryInput!
|
||||
): DeleteCookieCategoryPayload!
|
||||
}
|
||||
|
||||
input CreateCookieBannerInput {
|
||||
organizationId: ID!
|
||||
name: String!
|
||||
origin: String!
|
||||
privacyPolicyUrl: String!
|
||||
consentExpiryDays: Int!
|
||||
consentMode: CookieConsentMode!
|
||||
}
|
||||
|
||||
input UpdateCookieBannerInput {
|
||||
cookieBannerId: ID!
|
||||
name: String
|
||||
origin: String
|
||||
privacyPolicyUrl: String
|
||||
consentExpiryDays: Int
|
||||
consentMode: CookieConsentMode
|
||||
}
|
||||
|
||||
input DeleteCookieBannerInput {
|
||||
cookieBannerId: ID!
|
||||
}
|
||||
|
||||
input ActivateCookieBannerInput {
|
||||
cookieBannerId: ID!
|
||||
}
|
||||
|
||||
input DeactivateCookieBannerInput {
|
||||
cookieBannerId: ID!
|
||||
}
|
||||
|
||||
input PublishCookieBannerVersionInput {
|
||||
cookieBannerId: ID!
|
||||
}
|
||||
|
||||
input CreateCookieCategoryInput {
|
||||
cookieBannerId: ID!
|
||||
name: String!
|
||||
description: String!
|
||||
required: Boolean!
|
||||
rank: Int!
|
||||
cookies: [CookieItemInput!]
|
||||
}
|
||||
|
||||
input UpdateCookieCategoryInput {
|
||||
cookieCategoryId: ID!
|
||||
name: String
|
||||
description: String
|
||||
rank: Int
|
||||
cookies: [CookieItemInput!]
|
||||
}
|
||||
|
||||
input DeleteCookieCategoryInput {
|
||||
cookieCategoryId: ID!
|
||||
}
|
||||
|
||||
input CookieItemInput {
|
||||
name: String!
|
||||
duration: String!
|
||||
description: String!
|
||||
}
|
||||
|
||||
type CreateCookieBannerPayload {
|
||||
cookieBannerEdge: CookieBannerEdge!
|
||||
}
|
||||
|
||||
type UpdateCookieBannerPayload {
|
||||
cookieBanner: CookieBanner!
|
||||
}
|
||||
|
||||
type DeleteCookieBannerPayload {
|
||||
deletedCookieBannerId: ID!
|
||||
}
|
||||
|
||||
type ActivateCookieBannerPayload {
|
||||
cookieBanner: CookieBanner!
|
||||
}
|
||||
|
||||
type DeactivateCookieBannerPayload {
|
||||
cookieBanner: CookieBanner!
|
||||
}
|
||||
|
||||
type PublishCookieBannerVersionPayload {
|
||||
cookieBannerVersion: CookieBannerVersion!
|
||||
}
|
||||
|
||||
type CreateCookieCategoryPayload {
|
||||
cookieCategoryEdge: CookieCategoryEdge!
|
||||
}
|
||||
|
||||
type UpdateCookieCategoryPayload {
|
||||
cookieCategory: CookieCategory!
|
||||
}
|
||||
|
||||
type DeleteCookieCategoryPayload {
|
||||
deletedCookieCategoryId: ID!
|
||||
}
|
||||
@@ -306,6 +306,14 @@ type Organization implements Node {
|
||||
orderBy: TrustCenterFileOrder
|
||||
): TrustCenterFileConnection! @goField(forceResolver: true)
|
||||
|
||||
cookieBanners(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
last: Int
|
||||
before: CursorKey
|
||||
orderBy: CookieBannerOrder
|
||||
): CookieBannerConnection! @goField(forceResolver: true)
|
||||
|
||||
vendors(
|
||||
first: Int
|
||||
after: CursorKey
|
||||
|
||||
@@ -20,6 +20,7 @@ import (
|
||||
"go.gearno.de/kit/log"
|
||||
"go.probo.inc/probo/pkg/accessreview"
|
||||
"go.probo.inc/probo/pkg/connector"
|
||||
"go.probo.inc/probo/pkg/cookiebanner"
|
||||
"go.probo.inc/probo/pkg/esign"
|
||||
"go.probo.inc/probo/pkg/iam"
|
||||
"go.probo.inc/probo/pkg/mailman"
|
||||
@@ -29,7 +30,7 @@ import (
|
||||
"go.probo.inc/probo/pkg/server/gqlutils"
|
||||
)
|
||||
|
||||
func NewGraphQLHandler(iamSvc *iam.Service, proboSvc *probo.Service, esignSvc *esign.Service, accessReviewSvc *accessreview.Service, mailmanSvc *mailman.Service, connectorRegistry *connector.ConnectorRegistry, customDomainCname string, logger *log.Logger) http.Handler {
|
||||
func NewGraphQLHandler(iamSvc *iam.Service, proboSvc *probo.Service, esignSvc *esign.Service, accessReviewSvc *accessreview.Service, mailmanSvc *mailman.Service, cookieBannerSvc *cookiebanner.Service, connectorRegistry *connector.ConnectorRegistry, customDomainCname string, logger *log.Logger) http.Handler {
|
||||
config := schema.Config{
|
||||
Resolvers: &Resolver{
|
||||
authorize: authz.NewAuthorizeFunc(iamSvc, logger),
|
||||
@@ -38,6 +39,7 @@ func NewGraphQLHandler(iamSvc *iam.Service, proboSvc *probo.Service, esignSvc *e
|
||||
esign: esignSvc,
|
||||
accessReview: accessReviewSvc,
|
||||
mailman: mailmanSvc,
|
||||
cookieBanner: cookieBannerSvc,
|
||||
connectorRegistry: connectorRegistry,
|
||||
customDomainCname: customDomainCname,
|
||||
logger: logger,
|
||||
|
||||
@@ -1044,6 +1044,37 @@ func (r *organizationResolver) TrustCenterFiles(ctx context.Context, obj *types.
|
||||
return types.NewTrustCenterFileConnection(pageResult, obj.ID), nil
|
||||
}
|
||||
|
||||
// CookieBanners is the resolver for the cookieBanners field.
|
||||
func (r *organizationResolver) CookieBanners(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.CookieBannerOrderBy) (*types.CookieBannerConnection, error) {
|
||||
if err := r.authorize(ctx, obj.ID, probo.ActionCookieBannerList); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
pageOrderBy := page.OrderBy[coredata.CookieBannerOrderField]{
|
||||
Field: coredata.CookieBannerOrderFieldCreatedAt,
|
||||
Direction: page.OrderDirectionDesc,
|
||||
}
|
||||
if orderBy != nil {
|
||||
pageOrderBy = page.OrderBy[coredata.CookieBannerOrderField]{
|
||||
Field: orderBy.Field,
|
||||
Direction: orderBy.Direction,
|
||||
}
|
||||
}
|
||||
|
||||
cursor := types.NewCursor(first, after, last, before, pageOrderBy)
|
||||
scope := coredata.NewScopeFromObjectID(obj.ID)
|
||||
|
||||
banners, err := r.cookieBanner.ListCookieBannersForOrganization(ctx, scope, obj.ID, cursor, coredata.NewCookieBannerFilter(nil))
|
||||
if err != nil {
|
||||
r.logger.ErrorCtx(ctx, "cannot list cookie banners", log.Error(err))
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
p := page.NewPage(banners, cursor)
|
||||
|
||||
return types.NewCookieBannerConnection(p, r, obj.ID), nil
|
||||
}
|
||||
|
||||
// Vendors is the resolver for the vendors field.
|
||||
func (r *organizationResolver) Vendors(ctx context.Context, obj *types.Organization, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.VendorOrderBy, filter *types.VendorFilter) (*types.VendorConnection, error) {
|
||||
if err := r.authorize(ctx, obj.ID, probo.ActionVendorList); err != nil {
|
||||
|
||||
@@ -42,6 +42,7 @@ import (
|
||||
"go.probo.inc/probo/pkg/accessreview"
|
||||
"go.probo.inc/probo/pkg/baseurl"
|
||||
"go.probo.inc/probo/pkg/connector"
|
||||
"go.probo.inc/probo/pkg/cookiebanner"
|
||||
"go.probo.inc/probo/pkg/coredata"
|
||||
"go.probo.inc/probo/pkg/esign"
|
||||
"go.probo.inc/probo/pkg/gid"
|
||||
@@ -64,6 +65,7 @@ type (
|
||||
esign *esign.Service
|
||||
accessReview *accessreview.Service
|
||||
mailman *mailman.Service
|
||||
cookieBanner *cookiebanner.Service
|
||||
connectorRegistry *connector.ConnectorRegistry
|
||||
logger *log.Logger
|
||||
customDomainCname string
|
||||
@@ -77,6 +79,7 @@ func NewMux(
|
||||
esignSvc *esign.Service,
|
||||
accessReviewSvc *accessreview.Service,
|
||||
mailmanSvc *mailman.Service,
|
||||
cookieBannerSvc *cookiebanner.Service,
|
||||
cookieConfig securecookie.Config,
|
||||
tokenSecret string,
|
||||
connectorRegistry *connector.ConnectorRegistry,
|
||||
@@ -87,7 +90,17 @@ func NewMux(
|
||||
|
||||
safeRedirect := saferedirect.New(saferedirect.StaticHosts(baseURL.Host()))
|
||||
|
||||
graphqlHandler := NewGraphQLHandler(iamSvc, proboSvc, esignSvc, accessReviewSvc, mailmanSvc, connectorRegistry, customDomainCname, logger)
|
||||
graphqlHandler := NewGraphQLHandler(
|
||||
iamSvc,
|
||||
proboSvc,
|
||||
esignSvc,
|
||||
accessReviewSvc,
|
||||
mailmanSvc,
|
||||
cookieBannerSvc,
|
||||
connectorRegistry,
|
||||
customDomainCname,
|
||||
logger,
|
||||
)
|
||||
|
||||
r.Group(func(r chi.Router) {
|
||||
r.Use(authn.NewSessionMiddleware(iamSvc, cookieConfig))
|
||||
|
||||
78
pkg/server/api/console/v1/types/cookie_banner.go
Normal file
78
pkg/server/api/console/v1/types/cookie_banner.go
Normal file
@@ -0,0 +1,78 @@
|
||||
// Copyright (c) 2026 Probo Inc <hello@getprobo.com>.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
// PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
package types
|
||||
|
||||
import (
|
||||
"go.probo.inc/probo/pkg/coredata"
|
||||
"go.probo.inc/probo/pkg/gid"
|
||||
"go.probo.inc/probo/pkg/page"
|
||||
)
|
||||
|
||||
type (
|
||||
CookieBannerOrderBy OrderBy[coredata.CookieBannerOrderField]
|
||||
|
||||
CookieBannerConnection struct {
|
||||
TotalCount int
|
||||
Edges []*CookieBannerEdge
|
||||
PageInfo PageInfo
|
||||
|
||||
Resolver any
|
||||
ParentID gid.GID
|
||||
}
|
||||
)
|
||||
|
||||
func NewCookieBannerConnection(
|
||||
p *page.Page[*coredata.CookieBanner, coredata.CookieBannerOrderField],
|
||||
parentType any,
|
||||
parentID gid.GID,
|
||||
) *CookieBannerConnection {
|
||||
var edges = make([]*CookieBannerEdge, len(p.Data))
|
||||
|
||||
for i := range edges {
|
||||
edges[i] = NewCookieBannerEdge(p.Data[i], p.Cursor.OrderBy.Field)
|
||||
}
|
||||
|
||||
return &CookieBannerConnection{
|
||||
Edges: edges,
|
||||
PageInfo: *NewPageInfo(p),
|
||||
|
||||
Resolver: parentType,
|
||||
ParentID: parentID,
|
||||
}
|
||||
}
|
||||
|
||||
func NewCookieBannerEdge(b *coredata.CookieBanner, orderBy coredata.CookieBannerOrderField) *CookieBannerEdge {
|
||||
return &CookieBannerEdge{
|
||||
Cursor: b.CursorKey(orderBy),
|
||||
Node: NewCookieBanner(b),
|
||||
}
|
||||
}
|
||||
|
||||
func NewCookieBanner(b *coredata.CookieBanner) *CookieBanner {
|
||||
return &CookieBanner{
|
||||
ID: b.ID,
|
||||
Organization: &Organization{
|
||||
ID: b.OrganizationID,
|
||||
},
|
||||
Name: b.Name,
|
||||
Origin: b.Origin,
|
||||
State: b.State,
|
||||
PrivacyPolicyURL: b.PrivacyPolicyURL,
|
||||
ConsentExpiryDays: b.ConsentExpiryDays,
|
||||
ConsentMode: b.ConsentMode,
|
||||
CreatedAt: b.CreatedAt,
|
||||
UpdatedAt: b.UpdatedAt,
|
||||
}
|
||||
}
|
||||
86
pkg/server/api/console/v1/types/cookie_category.go
Normal file
86
pkg/server/api/console/v1/types/cookie_category.go
Normal file
@@ -0,0 +1,86 @@
|
||||
// Copyright (c) 2026 Probo Inc <hello@getprobo.com>.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
// PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
package types
|
||||
|
||||
import (
|
||||
"go.probo.inc/probo/pkg/coredata"
|
||||
"go.probo.inc/probo/pkg/gid"
|
||||
"go.probo.inc/probo/pkg/page"
|
||||
)
|
||||
|
||||
type (
|
||||
CookieCategoryOrderBy OrderBy[coredata.CookieCategoryOrderField]
|
||||
|
||||
CookieCategoryConnection struct {
|
||||
TotalCount int
|
||||
Edges []*CookieCategoryEdge
|
||||
PageInfo PageInfo
|
||||
|
||||
Resolver any
|
||||
ParentID gid.GID
|
||||
}
|
||||
)
|
||||
|
||||
func NewCookieCategoryConnection(
|
||||
p *page.Page[*coredata.CookieCategory, coredata.CookieCategoryOrderField],
|
||||
parentType any,
|
||||
parentID gid.GID,
|
||||
) *CookieCategoryConnection {
|
||||
var edges = make([]*CookieCategoryEdge, len(p.Data))
|
||||
|
||||
for i := range edges {
|
||||
edges[i] = NewCookieCategoryEdge(p.Data[i], p.Cursor.OrderBy.Field)
|
||||
}
|
||||
|
||||
return &CookieCategoryConnection{
|
||||
Edges: edges,
|
||||
PageInfo: *NewPageInfo(p),
|
||||
|
||||
Resolver: parentType,
|
||||
ParentID: parentID,
|
||||
}
|
||||
}
|
||||
|
||||
func NewCookieCategoryEdge(c *coredata.CookieCategory, orderBy coredata.CookieCategoryOrderField) *CookieCategoryEdge {
|
||||
return &CookieCategoryEdge{
|
||||
Cursor: c.CursorKey(orderBy),
|
||||
Node: NewCookieCategory(c),
|
||||
}
|
||||
}
|
||||
|
||||
func NewCookieCategory(c *coredata.CookieCategory) *CookieCategory {
|
||||
cookies := make([]*CookieItem, len(c.Cookies))
|
||||
for i, cookie := range c.Cookies {
|
||||
cookies[i] = &CookieItem{
|
||||
Name: cookie.Name,
|
||||
Duration: cookie.Duration,
|
||||
Description: cookie.Description,
|
||||
}
|
||||
}
|
||||
|
||||
return &CookieCategory{
|
||||
ID: c.ID,
|
||||
CookieBanner: &CookieBanner{
|
||||
ID: c.CookieBannerID,
|
||||
},
|
||||
Name: c.Name,
|
||||
Description: c.Description,
|
||||
Required: c.Required,
|
||||
Rank: c.Rank,
|
||||
Cookies: cookies,
|
||||
CreatedAt: c.CreatedAt,
|
||||
UpdatedAt: c.UpdatedAt,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user