Add vendor privacy page

Signed-off-by: gearnode <bryan@frimin.fr>
This commit is contained in:
gearnode
2025-02-18 11:39:21 +01:00
parent 00c2206e57
commit 1ef8468d0e
8 changed files with 108 additions and 8 deletions

View File

@@ -29,6 +29,7 @@ const vendorOverviewPageQuery = graphql`
riskTier riskTier
statusPageUrl statusPageUrl
termsOfServiceUrl termsOfServiceUrl
privacyPolicyUrl
createdAt createdAt
updatedAt updatedAt
} }
@@ -229,6 +230,24 @@ function VendorOverviewPageContent({
</a> </a>
</div> </div>
)} )}
{data.node.privacyPolicyUrl && (
<div className="space-y-2">
<div className="flex items-center gap-2">
<HelpCircle className="h-4 w-4 text-gray-400" />
<Label className="text-sm">Privacy Policy</Label>
</div>
<a
href={data.node.privacyPolicyUrl}
className="text-primary hover:underline inline-flex items-center gap-1"
target="_blank"
rel="noopener noreferrer"
>
View Privacy Policy
<ArrowUpRight className="h-4 w-4" />
</a>
</div>
)}
</div> </div>
</div> </div>
</Card> </Card>

View File

@@ -1,5 +1,5 @@
/** /**
* @generated SignedSource<<ae97673f2cbf067aad64913403bca210>> * @generated SignedSource<<7a271eaf4694d17694f97b2326dd865f>>
* @lightSyntaxTransform * @lightSyntaxTransform
* @nogrep * @nogrep
*/ */
@@ -20,6 +20,7 @@ export type VendorOverviewPageQuery$data = {
readonly description?: string; readonly description?: string;
readonly id?: string; readonly id?: string;
readonly name?: string; readonly name?: string;
readonly privacyPolicyUrl?: string | null | undefined;
readonly riskTier?: RiskTier; readonly riskTier?: RiskTier;
readonly serviceCriticality?: ServiceCriticality; readonly serviceCriticality?: ServiceCriticality;
readonly serviceStartDate?: any; readonly serviceStartDate?: any;
@@ -116,10 +117,17 @@ v11 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
"name": "createdAt", "name": "privacyPolicyUrl",
"storageKey": null "storageKey": null
}, },
v12 = { v12 = {
"alias": null,
"args": null,
"kind": "ScalarField",
"name": "createdAt",
"storageKey": null
},
v13 = {
"alias": null, "alias": null,
"args": null, "args": null,
"kind": "ScalarField", "kind": "ScalarField",
@@ -154,7 +162,8 @@ return {
(v9/*: any*/), (v9/*: any*/),
(v10/*: any*/), (v10/*: any*/),
(v11/*: any*/), (v11/*: any*/),
(v12/*: any*/) (v12/*: any*/),
(v13/*: any*/)
], ],
"type": "Vendor", "type": "Vendor",
"abstractKey": null "abstractKey": null
@@ -200,7 +209,8 @@ return {
(v9/*: any*/), (v9/*: any*/),
(v10/*: any*/), (v10/*: any*/),
(v11/*: any*/), (v11/*: any*/),
(v12/*: any*/) (v12/*: any*/),
(v13/*: any*/)
], ],
"type": "Vendor", "type": "Vendor",
"abstractKey": null "abstractKey": null
@@ -211,16 +221,16 @@ return {
] ]
}, },
"params": { "params": {
"cacheID": "37f7dba24b43c13a4e5467dd58fdfcd6", "cacheID": "ad3e9f79ffd96f45f653bc45311f162e",
"id": null, "id": null,
"metadata": {}, "metadata": {},
"name": "VendorOverviewPageQuery", "name": "VendorOverviewPageQuery",
"operationKind": "query", "operationKind": "query",
"text": "query VendorOverviewPageQuery(\n $vendorId: ID!\n) {\n node(id: $vendorId) {\n __typename\n ... on Vendor {\n id\n name\n description\n serviceStartDate\n serviceTerminationDate\n serviceCriticality\n riskTier\n statusPageUrl\n termsOfServiceUrl\n createdAt\n updatedAt\n }\n id\n }\n}\n" "text": "query VendorOverviewPageQuery(\n $vendorId: ID!\n) {\n node(id: $vendorId) {\n __typename\n ... on Vendor {\n id\n name\n description\n serviceStartDate\n serviceTerminationDate\n serviceCriticality\n riskTier\n statusPageUrl\n termsOfServiceUrl\n privacyPolicyUrl\n createdAt\n updatedAt\n }\n id\n }\n}\n"
} }
}; };
})(); })();
(node as any).hash = "86f10af28dac38699127a302a42aca12"; (node as any).hash = "8fe48d1033182deff812f17769927ef2";
export default node; export default node;

View File

@@ -124,6 +124,7 @@ type Vendor implements Node {
riskTier: RiskTier! riskTier: RiskTier!
statusPageUrl: String statusPageUrl: String
termsOfServiceUrl: String termsOfServiceUrl: String
privacyPolicyUrl: String
} }
type FrameworkConnection { type FrameworkConnection {
@@ -360,4 +361,5 @@ input UpdateVendorInput {
riskTier: RiskTier riskTier: RiskTier
statusPageUrl: String statusPageUrl: String
termsOfServiceUrl: String termsOfServiceUrl: String
privacyPolicyUrl: String
} }

View File

@@ -249,6 +249,7 @@ type ComplexityRoot struct {
Description func(childComplexity int) int Description func(childComplexity int) int
ID func(childComplexity int) int ID func(childComplexity int) int
Name func(childComplexity int) int Name func(childComplexity int) int
PrivacyPolicyURL func(childComplexity int) int
RiskTier func(childComplexity int) int RiskTier func(childComplexity int) int
ServiceCriticality func(childComplexity int) int ServiceCriticality func(childComplexity int) int
ServiceStartDate func(childComplexity int) int ServiceStartDate func(childComplexity int) int
@@ -1150,6 +1151,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
return e.complexity.Vendor.Name(childComplexity), true return e.complexity.Vendor.Name(childComplexity), true
case "Vendor.privacyPolicyUrl":
if e.complexity.Vendor.PrivacyPolicyURL == nil {
break
}
return e.complexity.Vendor.PrivacyPolicyURL(childComplexity), true
case "Vendor.riskTier": case "Vendor.riskTier":
if e.complexity.Vendor.RiskTier == nil { if e.complexity.Vendor.RiskTier == nil {
break break
@@ -1463,6 +1471,7 @@ type Vendor implements Node {
riskTier: RiskTier! riskTier: RiskTier!
statusPageUrl: String statusPageUrl: String
termsOfServiceUrl: String termsOfServiceUrl: String
privacyPolicyUrl: String
} }
type FrameworkConnection { type FrameworkConnection {
@@ -1699,6 +1708,7 @@ input UpdateVendorInput {
riskTier: RiskTier riskTier: RiskTier
statusPageUrl: String statusPageUrl: String
termsOfServiceUrl: String termsOfServiceUrl: String
privacyPolicyUrl: String
}`, BuiltIn: false}, }`, BuiltIn: false},
} }
var parsedSchema = gqlparser.MustLoadSchema(sources...) var parsedSchema = gqlparser.MustLoadSchema(sources...)
@@ -4929,6 +4939,8 @@ func (ec *executionContext) fieldContext_Mutation_createVendor(ctx context.Conte
return ec.fieldContext_Vendor_statusPageUrl(ctx, field) return ec.fieldContext_Vendor_statusPageUrl(ctx, field)
case "termsOfServiceUrl": case "termsOfServiceUrl":
return ec.fieldContext_Vendor_termsOfServiceUrl(ctx, field) return ec.fieldContext_Vendor_termsOfServiceUrl(ctx, field)
case "privacyPolicyUrl":
return ec.fieldContext_Vendor_privacyPolicyUrl(ctx, field)
} }
return nil, fmt.Errorf("no field named %q was found under type Vendor", field.Name) return nil, fmt.Errorf("no field named %q was found under type Vendor", field.Name)
}, },
@@ -7498,6 +7510,41 @@ func (ec *executionContext) fieldContext_Vendor_termsOfServiceUrl(_ context.Cont
return fc, nil return fc, nil
} }
func (ec *executionContext) _Vendor_privacyPolicyUrl(ctx context.Context, field graphql.CollectedField, obj *types.Vendor) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_Vendor_privacyPolicyUrl(ctx, field)
if err != nil {
return graphql.Null
}
ctx = graphql.WithFieldContext(ctx, fc)
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (any, error) {
ctx = rctx // use context from middleware stack in children
return obj.PrivacyPolicyURL, nil
})
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
if resTmp == nil {
return graphql.Null
}
res := resTmp.(*string)
fc.Result = res
return ec.marshalOString2ᚖstring(ctx, field.Selections, res)
}
func (ec *executionContext) fieldContext_Vendor_privacyPolicyUrl(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
fc = &graphql.FieldContext{
Object: "Vendor",
Field: field,
IsMethod: false,
IsResolver: false,
Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
return nil, errors.New("field of type String does not have child fields")
},
}
return fc, nil
}
func (ec *executionContext) _VendorConnection_edges(ctx context.Context, field graphql.CollectedField, obj *types.VendorConnection) (ret graphql.Marshaler) { func (ec *executionContext) _VendorConnection_edges(ctx context.Context, field graphql.CollectedField, obj *types.VendorConnection) (ret graphql.Marshaler) {
fc, err := ec.fieldContext_VendorConnection_edges(ctx, field) fc, err := ec.fieldContext_VendorConnection_edges(ctx, field)
if err != nil { if err != nil {
@@ -7683,6 +7730,8 @@ func (ec *executionContext) fieldContext_VendorEdge_node(_ context.Context, fiel
return ec.fieldContext_Vendor_statusPageUrl(ctx, field) return ec.fieldContext_Vendor_statusPageUrl(ctx, field)
case "termsOfServiceUrl": case "termsOfServiceUrl":
return ec.fieldContext_Vendor_termsOfServiceUrl(ctx, field) return ec.fieldContext_Vendor_termsOfServiceUrl(ctx, field)
case "privacyPolicyUrl":
return ec.fieldContext_Vendor_privacyPolicyUrl(ctx, field)
} }
return nil, fmt.Errorf("no field named %q was found under type Vendor", field.Name) return nil, fmt.Errorf("no field named %q was found under type Vendor", field.Name)
}, },
@@ -9391,7 +9440,7 @@ func (ec *executionContext) unmarshalInputUpdateVendorInput(ctx context.Context,
asMap[k] = v asMap[k] = v
} }
fieldsInOrder := [...]string{"id", "name", "description", "serviceStartDate", "serviceTerminationDate", "serviceCriticality", "riskTier", "statusPageUrl", "termsOfServiceUrl"} fieldsInOrder := [...]string{"id", "name", "description", "serviceStartDate", "serviceTerminationDate", "serviceCriticality", "riskTier", "statusPageUrl", "termsOfServiceUrl", "privacyPolicyUrl"}
for _, k := range fieldsInOrder { for _, k := range fieldsInOrder {
v, ok := asMap[k] v, ok := asMap[k]
if !ok { if !ok {
@@ -9461,6 +9510,13 @@ func (ec *executionContext) unmarshalInputUpdateVendorInput(ctx context.Context,
return it, err return it, err
} }
it.TermsOfServiceURL = data it.TermsOfServiceURL = data
case "privacyPolicyUrl":
ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("privacyPolicyUrl"))
data, err := ec.unmarshalOString2ᚖstring(ctx, v)
if err != nil {
return it, err
}
it.PrivacyPolicyURL = data
} }
} }
@@ -11321,6 +11377,8 @@ func (ec *executionContext) _Vendor(ctx context.Context, sel ast.SelectionSet, o
out.Values[i] = ec._Vendor_statusPageUrl(ctx, field, obj) out.Values[i] = ec._Vendor_statusPageUrl(ctx, field, obj)
case "termsOfServiceUrl": case "termsOfServiceUrl":
out.Values[i] = ec._Vendor_termsOfServiceUrl(ctx, field, obj) out.Values[i] = ec._Vendor_termsOfServiceUrl(ctx, field, obj)
case "privacyPolicyUrl":
out.Values[i] = ec._Vendor_privacyPolicyUrl(ctx, field, obj)
default: default:
panic("unknown field " + strconv.Quote(field.Name)) panic("unknown field " + strconv.Quote(field.Name))
} }

View File

@@ -248,6 +248,7 @@ type UpdateVendorInput struct {
RiskTier *coredata.RiskTier `json:"riskTier,omitempty"` RiskTier *coredata.RiskTier `json:"riskTier,omitempty"`
StatusPageURL *string `json:"statusPageUrl,omitempty"` StatusPageURL *string `json:"statusPageUrl,omitempty"`
TermsOfServiceURL *string `json:"termsOfServiceUrl,omitempty"` TermsOfServiceURL *string `json:"termsOfServiceUrl,omitempty"`
PrivacyPolicyURL *string `json:"privacyPolicyUrl,omitempty"`
} }
type Vendor struct { type Vendor struct {
@@ -262,6 +263,7 @@ type Vendor struct {
RiskTier coredata.RiskTier `json:"riskTier"` RiskTier coredata.RiskTier `json:"riskTier"`
StatusPageURL *string `json:"statusPageUrl,omitempty"` StatusPageURL *string `json:"statusPageUrl,omitempty"`
TermsOfServiceURL *string `json:"termsOfServiceUrl,omitempty"` TermsOfServiceURL *string `json:"termsOfServiceUrl,omitempty"`
PrivacyPolicyURL *string `json:"privacyPolicyUrl,omitempty"`
} }
func (Vendor) IsNode() {} func (Vendor) IsNode() {}

View File

@@ -52,5 +52,6 @@ func NewVendor(v *coredata.Vendor) *Vendor {
RiskTier: v.RiskTier, RiskTier: v.RiskTier,
StatusPageURL: v.StatusPageURL, StatusPageURL: v.StatusPageURL,
TermsOfServiceURL: v.TermsOfServiceURL, TermsOfServiceURL: v.TermsOfServiceURL,
PrivacyPolicyURL: v.PrivacyPolicyURL,
} }
} }

View File

@@ -0,0 +1 @@
ALTER TABLE vendors ADD COLUMN privacy_policy_url TEXT;

View File

@@ -38,6 +38,7 @@ type (
RiskTier RiskTier RiskTier RiskTier
StatusPageURL *string StatusPageURL *string
TermsOfServiceURL *string TermsOfServiceURL *string
PrivacyPolicyURL *string
CreatedAt time.Time CreatedAt time.Time
UpdatedAt time.Time UpdatedAt time.Time
} }
@@ -61,6 +62,7 @@ func (v *Vendor) scan(r pgx.Row) error {
&v.RiskTier, &v.RiskTier,
&v.StatusPageURL, &v.StatusPageURL,
&v.TermsOfServiceURL, &v.TermsOfServiceURL,
&v.PrivacyPolicyURL,
&v.CreatedAt, &v.CreatedAt,
&v.UpdatedAt, &v.UpdatedAt,
) )
@@ -84,6 +86,7 @@ SELECT
risk_tier, risk_tier,
status_page_url, status_page_url,
terms_of_service_url, terms_of_service_url,
privacy_policy_url,
created_at, created_at,
updated_at updated_at
FROM FROM
@@ -128,6 +131,7 @@ INSERT INTO
risk_tier, risk_tier,
status_page_url, status_page_url,
terms_of_service_url, terms_of_service_url,
privacy_policy_url,
created_at, created_at,
updated_at updated_at
) )
@@ -142,6 +146,7 @@ VALUES (
@risk_tier, @risk_tier,
@status_page_url, @status_page_url,
@terms_of_service_url, @terms_of_service_url,
@privacy_policy_url,
@created_at, @created_at,
@updated_at @updated_at
) )
@@ -158,6 +163,7 @@ VALUES (
"risk_tier": v.RiskTier, "risk_tier": v.RiskTier,
"status_page_url": v.StatusPageURL, "status_page_url": v.StatusPageURL,
"terms_of_service_url": v.TermsOfServiceURL, "terms_of_service_url": v.TermsOfServiceURL,
"privacy_policy_url": v.PrivacyPolicyURL,
"created_at": v.CreatedAt, "created_at": v.CreatedAt,
"updated_at": v.UpdatedAt, "updated_at": v.UpdatedAt,
} }
@@ -202,6 +208,7 @@ SELECT
risk_tier, risk_tier,
status_page_url, status_page_url,
terms_of_service_url, terms_of_service_url,
privacy_policy_url,
created_at, created_at,
updated_at updated_at
FROM FROM