feat: enable enterprise users to specify a custom logo (#5566)

* feat: enable enterprise users to specify a custom logo

This adds a field in deployment settings that allows users to specify
the URL to a custom logo that will display in the dashboard.

This also groups service banner into a new appearance settings page.
It adds a Fieldset component to allow for modular fields moving forward.

* Fix tests
This commit is contained in:
Kyle Carberry
2023-01-04 15:31:45 -06:00
committed by GitHub
parent 175be621cf
commit 0dba2defd1
35 changed files with 824 additions and 597 deletions

43
codersdk/appearance.go Normal file
View File

@ -0,0 +1,43 @@
package codersdk
import (
"context"
"encoding/json"
"net/http"
)
type AppearanceConfig struct {
LogoURL string `json:"logo_url"`
ServiceBanner ServiceBannerConfig `json:"service_banner"`
}
type ServiceBannerConfig struct {
Enabled bool `json:"enabled"`
Message string `json:"message,omitempty"`
BackgroundColor string `json:"background_color,omitempty"`
}
func (c *Client) Appearance(ctx context.Context) (AppearanceConfig, error) {
res, err := c.Request(ctx, http.MethodGet, "/api/v2/appearance", nil)
if err != nil {
return AppearanceConfig{}, err
}
defer res.Body.Close()
if res.StatusCode != http.StatusOK {
return AppearanceConfig{}, readBodyAsError(res)
}
var cfg AppearanceConfig
return cfg, json.NewDecoder(res.Body).Decode(&cfg)
}
func (c *Client) UpdateAppearance(ctx context.Context, appearance AppearanceConfig) error {
res, err := c.Request(ctx, http.MethodPut, "/api/v2/appearance", appearance)
if err != nil {
return err
}
defer res.Body.Close()
if res.StatusCode != http.StatusOK {
return readBodyAsError(res)
}
return nil
}

23
codersdk/branding.go Normal file
View File

@ -0,0 +1,23 @@
package codersdk
import (
"context"
"net/http"
)
type UpdateBrandingRequest struct {
LogoURL string `json:"logo_url"`
}
// UpdateBranding applies customization settings available to Enterprise customers.
func (c *Client) UpdateBranding(ctx context.Context, req UpdateBrandingRequest) error {
res, err := c.Request(ctx, http.MethodPut, "/api/v2/branding", req)
if err != nil {
return err
}
defer res.Body.Close()
if res.StatusCode != http.StatusOK {
return readBodyAsError(res)
}
return nil
}

View File

@ -23,7 +23,7 @@ const (
FeatureHighAvailability = "high_availability"
FeatureMultipleGitAuth = "multiple_git_auth"
FeatureExternalProvisionerDaemons = "external_provisioner_daemons"
FeatureServiceBanners = "service_banners"
FeatureAppearance = "appearance"
)
var FeatureNames = []string{
@ -35,7 +35,7 @@ var FeatureNames = []string{
FeatureHighAvailability,
FeatureMultipleGitAuth,
FeatureExternalProvisionerDaemons,
FeatureServiceBanners,
FeatureAppearance,
}
type Feature struct {

View File

@ -1,38 +0,0 @@
package codersdk
import (
"context"
"encoding/json"
"net/http"
)
type ServiceBanner struct {
Enabled bool `json:"enabled"`
Message string `json:"message,omitempty"`
BackgroundColor string `json:"background_color,omitempty"`
}
func (c *Client) ServiceBanner(ctx context.Context) (*ServiceBanner, error) {
res, err := c.Request(ctx, http.MethodGet, "/api/v2/service-banner", nil)
if err != nil {
return nil, err
}
defer res.Body.Close()
if res.StatusCode != http.StatusOK {
return nil, readBodyAsError(res)
}
var b ServiceBanner
return &b, json.NewDecoder(res.Body).Decode(&b)
}
func (c *Client) SetServiceBanner(ctx context.Context, s *ServiceBanner) error {
res, err := c.Request(ctx, http.MethodPut, "/api/v2/service-banner", s)
if err != nil {
return err
}
defer res.Body.Close()
if res.StatusCode != http.StatusOK {
return readBodyAsError(res)
}
return nil
}