mirror of
https://github.com/coder/coder.git
synced 2026-06-02 20:48:20 +00:00
chore: rename notification banners to announcement banners (#13419)
This commit is contained in:
committed by
GitHub
parent
de8149fbfd
commit
b248f125e1
+14
-14
@@ -176,7 +176,7 @@ func New(options Options) Agent {
|
||||
ignorePorts: options.IgnorePorts,
|
||||
portCacheDuration: options.PortCacheDuration,
|
||||
reportMetadataInterval: options.ReportMetadataInterval,
|
||||
notificationBannersRefreshInterval: options.ServiceBannerRefreshInterval,
|
||||
announcementBannersRefreshInterval: options.ServiceBannerRefreshInterval,
|
||||
sshMaxTimeout: options.SSHMaxTimeout,
|
||||
subsystems: options.Subsystems,
|
||||
addresses: options.Addresses,
|
||||
@@ -193,7 +193,7 @@ func New(options Options) Agent {
|
||||
// that gets closed on disconnection. This is used to wait for graceful disconnection from the
|
||||
// coordinator during shut down.
|
||||
close(a.coordDisconnected)
|
||||
a.notificationBanners.Store(new([]codersdk.BannerConfig))
|
||||
a.announcementBanners.Store(new([]codersdk.BannerConfig))
|
||||
a.sessionToken.Store(new(string))
|
||||
a.init()
|
||||
return a
|
||||
@@ -234,8 +234,8 @@ type agent struct {
|
||||
manifest atomic.Pointer[agentsdk.Manifest] // manifest is atomic because values can change after reconnection.
|
||||
reportMetadataInterval time.Duration
|
||||
scriptRunner *agentscripts.Runner
|
||||
notificationBanners atomic.Pointer[[]codersdk.BannerConfig] // notificationBanners is atomic because it is periodically updated.
|
||||
notificationBannersRefreshInterval time.Duration
|
||||
announcementBanners atomic.Pointer[[]codersdk.BannerConfig] // announcementBanners is atomic because it is periodically updated.
|
||||
announcementBannersRefreshInterval time.Duration
|
||||
sessionToken atomic.Pointer[string]
|
||||
sshServer *agentssh.Server
|
||||
sshMaxTimeout time.Duration
|
||||
@@ -274,7 +274,7 @@ func (a *agent) init() {
|
||||
sshSrv, err := agentssh.NewServer(a.hardCtx, a.logger.Named("ssh-server"), a.prometheusRegistry, a.filesystem, &agentssh.Config{
|
||||
MaxTimeout: a.sshMaxTimeout,
|
||||
MOTDFile: func() string { return a.manifest.Load().MOTDFile },
|
||||
NotificationBanners: func() *[]codersdk.BannerConfig { return a.notificationBanners.Load() },
|
||||
AnnouncementBanners: func() *[]codersdk.BannerConfig { return a.announcementBanners.Load() },
|
||||
UpdateEnv: a.updateCommandEnv,
|
||||
WorkingDirectory: func() string { return a.manifest.Load().Directory },
|
||||
})
|
||||
@@ -709,14 +709,14 @@ func (a *agent) setLifecycle(state codersdk.WorkspaceAgentLifecycle) {
|
||||
// (and must be done before the session actually starts).
|
||||
func (a *agent) fetchServiceBannerLoop(ctx context.Context, conn drpc.Conn) error {
|
||||
aAPI := proto.NewDRPCAgentClient(conn)
|
||||
ticker := time.NewTicker(a.notificationBannersRefreshInterval)
|
||||
ticker := time.NewTicker(a.announcementBannersRefreshInterval)
|
||||
defer ticker.Stop()
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
case <-ticker.C:
|
||||
bannersProto, err := aAPI.GetNotificationBanners(ctx, &proto.GetNotificationBannersRequest{})
|
||||
bannersProto, err := aAPI.GetAnnouncementBanners(ctx, &proto.GetAnnouncementBannersRequest{})
|
||||
if err != nil {
|
||||
if ctx.Err() != nil {
|
||||
return ctx.Err()
|
||||
@@ -724,11 +724,11 @@ func (a *agent) fetchServiceBannerLoop(ctx context.Context, conn drpc.Conn) erro
|
||||
a.logger.Error(ctx, "failed to update notification banners", slog.Error(err))
|
||||
return err
|
||||
}
|
||||
banners := make([]codersdk.BannerConfig, 0, len(bannersProto.NotificationBanners))
|
||||
for _, bannerProto := range bannersProto.NotificationBanners {
|
||||
banners := make([]codersdk.BannerConfig, 0, len(bannersProto.AnnouncementBanners))
|
||||
for _, bannerProto := range bannersProto.AnnouncementBanners {
|
||||
banners = append(banners, agentsdk.BannerConfigFromProto(bannerProto))
|
||||
}
|
||||
a.notificationBanners.Store(&banners)
|
||||
a.announcementBanners.Store(&banners)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -763,15 +763,15 @@ func (a *agent) run() (retErr error) {
|
||||
connMan.start("init notification banners", gracefulShutdownBehaviorStop,
|
||||
func(ctx context.Context, conn drpc.Conn) error {
|
||||
aAPI := proto.NewDRPCAgentClient(conn)
|
||||
bannersProto, err := aAPI.GetNotificationBanners(ctx, &proto.GetNotificationBannersRequest{})
|
||||
bannersProto, err := aAPI.GetAnnouncementBanners(ctx, &proto.GetAnnouncementBannersRequest{})
|
||||
if err != nil {
|
||||
return xerrors.Errorf("fetch service banner: %w", err)
|
||||
}
|
||||
banners := make([]codersdk.BannerConfig, 0, len(bannersProto.NotificationBanners))
|
||||
for _, bannerProto := range bannersProto.NotificationBanners {
|
||||
banners := make([]codersdk.BannerConfig, 0, len(bannersProto.AnnouncementBanners))
|
||||
for _, bannerProto := range bannersProto.AnnouncementBanners {
|
||||
banners = append(banners, agentsdk.BannerConfigFromProto(bannerProto))
|
||||
}
|
||||
a.notificationBanners.Store(&banners)
|
||||
a.announcementBanners.Store(&banners)
|
||||
return nil
|
||||
},
|
||||
)
|
||||
|
||||
+2
-2
@@ -614,7 +614,7 @@ func TestAgent_Session_TTY_MOTD_Update(t *testing.T) {
|
||||
// Set new banner func and wait for the agent to call it to update the
|
||||
// banner.
|
||||
ready := make(chan struct{}, 2)
|
||||
client.SetNotificationBannersFunc(func() ([]codersdk.BannerConfig, error) {
|
||||
client.SetAnnouncementBannersFunc(func() ([]codersdk.BannerConfig, error) {
|
||||
select {
|
||||
case ready <- struct{}{}:
|
||||
default:
|
||||
@@ -2200,7 +2200,7 @@ func setupSSHSession(
|
||||
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
|
||||
defer cancel()
|
||||
opts = append(opts, func(c *agenttest.Client, o *agent.Options) {
|
||||
c.SetNotificationBannersFunc(func() ([]codersdk.BannerConfig, error) {
|
||||
c.SetAnnouncementBannersFunc(func() ([]codersdk.BannerConfig, error) {
|
||||
return []codersdk.BannerConfig{banner}, nil
|
||||
})
|
||||
})
|
||||
|
||||
@@ -63,7 +63,7 @@ type Config struct {
|
||||
// file will be displayed to the user upon login.
|
||||
MOTDFile func() string
|
||||
// ServiceBanner returns the configuration for the Coder service banner.
|
||||
NotificationBanners func() *[]codersdk.BannerConfig
|
||||
AnnouncementBanners func() *[]codersdk.BannerConfig
|
||||
// UpdateEnv updates the environment variables for the command to be
|
||||
// executed. It can be used to add, modify or replace environment variables.
|
||||
UpdateEnv func(current []string) (updated []string, err error)
|
||||
@@ -123,8 +123,8 @@ func NewServer(ctx context.Context, logger slog.Logger, prometheusRegistry *prom
|
||||
if config.MOTDFile == nil {
|
||||
config.MOTDFile = func() string { return "" }
|
||||
}
|
||||
if config.NotificationBanners == nil {
|
||||
config.NotificationBanners = func() *[]codersdk.BannerConfig { return &[]codersdk.BannerConfig{} }
|
||||
if config.AnnouncementBanners == nil {
|
||||
config.AnnouncementBanners = func() *[]codersdk.BannerConfig { return &[]codersdk.BannerConfig{} }
|
||||
}
|
||||
if config.WorkingDirectory == nil {
|
||||
config.WorkingDirectory = func() string {
|
||||
@@ -441,13 +441,13 @@ func (s *Server) startPTYSession(logger slog.Logger, session ptySession, magicTy
|
||||
session.DisablePTYEmulation()
|
||||
|
||||
if isLoginShell(session.RawCommand()) {
|
||||
banners := s.config.NotificationBanners()
|
||||
banners := s.config.AnnouncementBanners()
|
||||
if banners != nil {
|
||||
for _, banner := range *banners {
|
||||
err := showNotificationBanner(session, banner)
|
||||
err := showAnnouncementBanner(session, banner)
|
||||
if err != nil {
|
||||
logger.Error(ctx, "agent failed to show service banner", slog.Error(err))
|
||||
s.metrics.sessionErrors.WithLabelValues(magicTypeLabel, "yes", "notification_banner").Add(1)
|
||||
logger.Error(ctx, "agent failed to show announcement banner", slog.Error(err))
|
||||
s.metrics.sessionErrors.WithLabelValues(magicTypeLabel, "yes", "announcement_banner").Add(1)
|
||||
break
|
||||
}
|
||||
}
|
||||
@@ -894,9 +894,9 @@ func isQuietLogin(fs afero.Fs, rawCommand string) bool {
|
||||
return err == nil
|
||||
}
|
||||
|
||||
// showNotificationBanner will write the service banner if enabled and not blank
|
||||
// showAnnouncementBanner will write the service banner if enabled and not blank
|
||||
// along with a blank line for spacing.
|
||||
func showNotificationBanner(session io.Writer, banner codersdk.BannerConfig) error {
|
||||
func showAnnouncementBanner(session io.Writer, banner codersdk.BannerConfig) error {
|
||||
if banner.Enabled && banner.Message != "" {
|
||||
// The banner supports Markdown so we might want to parse it but Markdown is
|
||||
// still fairly readable in its raw form.
|
||||
|
||||
+10
-10
@@ -138,8 +138,8 @@ func (c *Client) GetStartupLogs() []agentsdk.Log {
|
||||
return c.logs
|
||||
}
|
||||
|
||||
func (c *Client) SetNotificationBannersFunc(f func() ([]codersdk.ServiceBannerConfig, error)) {
|
||||
c.fakeAgentAPI.SetNotificationBannersFunc(f)
|
||||
func (c *Client) SetAnnouncementBannersFunc(f func() ([]codersdk.BannerConfig, error)) {
|
||||
c.fakeAgentAPI.SetAnnouncementBannersFunc(f)
|
||||
}
|
||||
|
||||
func (c *Client) PushDERPMapUpdate(update *tailcfg.DERPMap) error {
|
||||
@@ -171,7 +171,7 @@ type FakeAgentAPI struct {
|
||||
lifecycleStates []codersdk.WorkspaceAgentLifecycle
|
||||
metadata map[string]agentsdk.Metadata
|
||||
|
||||
getNotificationBannersFunc func() ([]codersdk.BannerConfig, error)
|
||||
getAnnouncementBannersFunc func() ([]codersdk.BannerConfig, error)
|
||||
}
|
||||
|
||||
func (f *FakeAgentAPI) GetManifest(context.Context, *agentproto.GetManifestRequest) (*agentproto.Manifest, error) {
|
||||
@@ -182,20 +182,20 @@ func (*FakeAgentAPI) GetServiceBanner(context.Context, *agentproto.GetServiceBan
|
||||
return &agentproto.ServiceBanner{}, nil
|
||||
}
|
||||
|
||||
func (f *FakeAgentAPI) SetNotificationBannersFunc(fn func() ([]codersdk.BannerConfig, error)) {
|
||||
func (f *FakeAgentAPI) SetAnnouncementBannersFunc(fn func() ([]codersdk.BannerConfig, error)) {
|
||||
f.Lock()
|
||||
defer f.Unlock()
|
||||
f.getNotificationBannersFunc = fn
|
||||
f.getAnnouncementBannersFunc = fn
|
||||
f.logger.Info(context.Background(), "updated notification banners")
|
||||
}
|
||||
|
||||
func (f *FakeAgentAPI) GetNotificationBanners(context.Context, *agentproto.GetNotificationBannersRequest) (*agentproto.GetNotificationBannersResponse, error) {
|
||||
func (f *FakeAgentAPI) GetAnnouncementBanners(context.Context, *agentproto.GetAnnouncementBannersRequest) (*agentproto.GetAnnouncementBannersResponse, error) {
|
||||
f.Lock()
|
||||
defer f.Unlock()
|
||||
if f.getNotificationBannersFunc == nil {
|
||||
return &agentproto.GetNotificationBannersResponse{NotificationBanners: []*agentproto.BannerConfig{}}, nil
|
||||
if f.getAnnouncementBannersFunc == nil {
|
||||
return &agentproto.GetAnnouncementBannersResponse{AnnouncementBanners: []*agentproto.BannerConfig{}}, nil
|
||||
}
|
||||
banners, err := f.getNotificationBannersFunc()
|
||||
banners, err := f.getAnnouncementBannersFunc()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -203,7 +203,7 @@ func (f *FakeAgentAPI) GetNotificationBanners(context.Context, *agentproto.GetNo
|
||||
for _, banner := range banners {
|
||||
bannersProto = append(bannersProto, agentsdk.ProtoFromBannerConfig(banner))
|
||||
}
|
||||
return &agentproto.GetNotificationBannersResponse{NotificationBanners: bannersProto}, nil
|
||||
return &agentproto.GetAnnouncementBannersResponse{AnnouncementBanners: bannersProto}, nil
|
||||
}
|
||||
|
||||
func (f *FakeAgentAPI) UpdateStats(ctx context.Context, req *agentproto.UpdateStatsRequest) (*agentproto.UpdateStatsResponse, error) {
|
||||
|
||||
+38
-38
@@ -1859,14 +1859,14 @@ func (x *BatchCreateLogsResponse) GetLogLimitExceeded() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
type GetNotificationBannersRequest struct {
|
||||
type GetAnnouncementBannersRequest struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
}
|
||||
|
||||
func (x *GetNotificationBannersRequest) Reset() {
|
||||
*x = GetNotificationBannersRequest{}
|
||||
func (x *GetAnnouncementBannersRequest) Reset() {
|
||||
*x = GetAnnouncementBannersRequest{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_agent_proto_agent_proto_msgTypes[22]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
@@ -1874,13 +1874,13 @@ func (x *GetNotificationBannersRequest) Reset() {
|
||||
}
|
||||
}
|
||||
|
||||
func (x *GetNotificationBannersRequest) String() string {
|
||||
func (x *GetAnnouncementBannersRequest) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*GetNotificationBannersRequest) ProtoMessage() {}
|
||||
func (*GetAnnouncementBannersRequest) ProtoMessage() {}
|
||||
|
||||
func (x *GetNotificationBannersRequest) ProtoReflect() protoreflect.Message {
|
||||
func (x *GetAnnouncementBannersRequest) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_agent_proto_agent_proto_msgTypes[22]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
@@ -1892,21 +1892,21 @@ func (x *GetNotificationBannersRequest) ProtoReflect() protoreflect.Message {
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use GetNotificationBannersRequest.ProtoReflect.Descriptor instead.
|
||||
func (*GetNotificationBannersRequest) Descriptor() ([]byte, []int) {
|
||||
// Deprecated: Use GetAnnouncementBannersRequest.ProtoReflect.Descriptor instead.
|
||||
func (*GetAnnouncementBannersRequest) Descriptor() ([]byte, []int) {
|
||||
return file_agent_proto_agent_proto_rawDescGZIP(), []int{22}
|
||||
}
|
||||
|
||||
type GetNotificationBannersResponse struct {
|
||||
type GetAnnouncementBannersResponse struct {
|
||||
state protoimpl.MessageState
|
||||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
NotificationBanners []*BannerConfig `protobuf:"bytes,1,rep,name=notification_banners,json=notificationBanners,proto3" json:"notification_banners,omitempty"`
|
||||
AnnouncementBanners []*BannerConfig `protobuf:"bytes,1,rep,name=announcement_banners,json=announcementBanners,proto3" json:"announcement_banners,omitempty"`
|
||||
}
|
||||
|
||||
func (x *GetNotificationBannersResponse) Reset() {
|
||||
*x = GetNotificationBannersResponse{}
|
||||
func (x *GetAnnouncementBannersResponse) Reset() {
|
||||
*x = GetAnnouncementBannersResponse{}
|
||||
if protoimpl.UnsafeEnabled {
|
||||
mi := &file_agent_proto_agent_proto_msgTypes[23]
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
@@ -1914,13 +1914,13 @@ func (x *GetNotificationBannersResponse) Reset() {
|
||||
}
|
||||
}
|
||||
|
||||
func (x *GetNotificationBannersResponse) String() string {
|
||||
func (x *GetAnnouncementBannersResponse) String() string {
|
||||
return protoimpl.X.MessageStringOf(x)
|
||||
}
|
||||
|
||||
func (*GetNotificationBannersResponse) ProtoMessage() {}
|
||||
func (*GetAnnouncementBannersResponse) ProtoMessage() {}
|
||||
|
||||
func (x *GetNotificationBannersResponse) ProtoReflect() protoreflect.Message {
|
||||
func (x *GetAnnouncementBannersResponse) ProtoReflect() protoreflect.Message {
|
||||
mi := &file_agent_proto_agent_proto_msgTypes[23]
|
||||
if protoimpl.UnsafeEnabled && x != nil {
|
||||
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
|
||||
@@ -1932,14 +1932,14 @@ func (x *GetNotificationBannersResponse) ProtoReflect() protoreflect.Message {
|
||||
return mi.MessageOf(x)
|
||||
}
|
||||
|
||||
// Deprecated: Use GetNotificationBannersResponse.ProtoReflect.Descriptor instead.
|
||||
func (*GetNotificationBannersResponse) Descriptor() ([]byte, []int) {
|
||||
// Deprecated: Use GetAnnouncementBannersResponse.ProtoReflect.Descriptor instead.
|
||||
func (*GetAnnouncementBannersResponse) Descriptor() ([]byte, []int) {
|
||||
return file_agent_proto_agent_proto_rawDescGZIP(), []int{23}
|
||||
}
|
||||
|
||||
func (x *GetNotificationBannersResponse) GetNotificationBanners() []*BannerConfig {
|
||||
func (x *GetAnnouncementBannersResponse) GetAnnouncementBanners() []*BannerConfig {
|
||||
if x != nil {
|
||||
return x.NotificationBanners
|
||||
return x.AnnouncementBanners
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -2742,16 +2742,16 @@ var file_agent_proto_agent_proto_rawDesc = []byte{
|
||||
0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2c, 0x0a, 0x12, 0x6c, 0x6f, 0x67, 0x5f, 0x6c, 0x69,
|
||||
0x6d, 0x69, 0x74, 0x5f, 0x65, 0x78, 0x63, 0x65, 0x65, 0x64, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01,
|
||||
0x28, 0x08, 0x52, 0x10, 0x6c, 0x6f, 0x67, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x45, 0x78, 0x63, 0x65,
|
||||
0x65, 0x64, 0x65, 0x64, 0x22, 0x1f, 0x0a, 0x1d, 0x47, 0x65, 0x74, 0x4e, 0x6f, 0x74, 0x69, 0x66,
|
||||
0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x73, 0x52, 0x65,
|
||||
0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x71, 0x0a, 0x1e, 0x47, 0x65, 0x74, 0x4e, 0x6f, 0x74, 0x69,
|
||||
0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x73, 0x52,
|
||||
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4f, 0x0a, 0x14, 0x6e, 0x6f, 0x74, 0x69, 0x66,
|
||||
0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x62, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x73, 0x18,
|
||||
0x65, 0x64, 0x65, 0x64, 0x22, 0x1f, 0x0a, 0x1d, 0x47, 0x65, 0x74, 0x41, 0x6e, 0x6e, 0x6f, 0x75,
|
||||
0x6e, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x73, 0x52, 0x65,
|
||||
0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x71, 0x0a, 0x1e, 0x47, 0x65, 0x74, 0x41, 0x6e, 0x6e, 0x6f,
|
||||
0x75, 0x6e, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x73, 0x52,
|
||||
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4f, 0x0a, 0x14, 0x61, 0x6e, 0x6e, 0x6f, 0x75,
|
||||
0x6e, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x5f, 0x62, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x73, 0x18,
|
||||
0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67,
|
||||
0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x43, 0x6f, 0x6e,
|
||||
0x66, 0x69, 0x67, 0x52, 0x13, 0x6e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
|
||||
0x6e, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x73, 0x22, 0x6d, 0x0a, 0x0c, 0x42, 0x61, 0x6e, 0x6e,
|
||||
0x66, 0x69, 0x67, 0x52, 0x13, 0x61, 0x6e, 0x6e, 0x6f, 0x75, 0x6e, 0x63, 0x65, 0x6d, 0x65, 0x6e,
|
||||
0x74, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x73, 0x22, 0x6d, 0x0a, 0x0c, 0x42, 0x61, 0x6e, 0x6e,
|
||||
0x65, 0x72, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x12, 0x18, 0x0a, 0x07, 0x65, 0x6e, 0x61, 0x62,
|
||||
0x6c, 0x65, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x65, 0x6e, 0x61, 0x62, 0x6c,
|
||||
0x65, 0x64, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x02, 0x20,
|
||||
@@ -2812,13 +2812,13 @@ var file_agent_proto_agent_proto_rawDesc = []byte{
|
||||
0x65, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x27, 0x2e, 0x63,
|
||||
0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e, 0x42, 0x61,
|
||||
0x74, 0x63, 0x68, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x4c, 0x6f, 0x67, 0x73, 0x52, 0x65, 0x73,
|
||||
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x77, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x4e, 0x6f, 0x74, 0x69,
|
||||
0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x73, 0x12,
|
||||
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x77, 0x0a, 0x16, 0x47, 0x65, 0x74, 0x41, 0x6e, 0x6e, 0x6f,
|
||||
0x75, 0x6e, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x73, 0x12,
|
||||
0x2d, 0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32,
|
||||
0x2e, 0x47, 0x65, 0x74, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
|
||||
0x2e, 0x47, 0x65, 0x74, 0x41, 0x6e, 0x6e, 0x6f, 0x75, 0x6e, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74,
|
||||
0x42, 0x61, 0x6e, 0x6e, 0x65, 0x72, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e,
|
||||
0x2e, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2e, 0x61, 0x67, 0x65, 0x6e, 0x74, 0x2e, 0x76, 0x32, 0x2e,
|
||||
0x47, 0x65, 0x74, 0x4e, 0x6f, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42,
|
||||
0x47, 0x65, 0x74, 0x41, 0x6e, 0x6e, 0x6f, 0x75, 0x6e, 0x63, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x42,
|
||||
0x61, 0x6e, 0x6e, 0x65, 0x72, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x27,
|
||||
0x5a, 0x25, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x63, 0x6f, 0x64,
|
||||
0x65, 0x72, 0x2f, 0x63, 0x6f, 0x64, 0x65, 0x72, 0x2f, 0x76, 0x32, 0x2f, 0x61, 0x67, 0x65, 0x6e,
|
||||
@@ -2869,8 +2869,8 @@ var file_agent_proto_agent_proto_goTypes = []interface{}{
|
||||
(*Log)(nil), // 26: coder.agent.v2.Log
|
||||
(*BatchCreateLogsRequest)(nil), // 27: coder.agent.v2.BatchCreateLogsRequest
|
||||
(*BatchCreateLogsResponse)(nil), // 28: coder.agent.v2.BatchCreateLogsResponse
|
||||
(*GetNotificationBannersRequest)(nil), // 29: coder.agent.v2.GetNotificationBannersRequest
|
||||
(*GetNotificationBannersResponse)(nil), // 30: coder.agent.v2.GetNotificationBannersResponse
|
||||
(*GetAnnouncementBannersRequest)(nil), // 29: coder.agent.v2.GetAnnouncementBannersRequest
|
||||
(*GetAnnouncementBannersResponse)(nil), // 30: coder.agent.v2.GetAnnouncementBannersResponse
|
||||
(*BannerConfig)(nil), // 31: coder.agent.v2.BannerConfig
|
||||
(*WorkspaceApp_Healthcheck)(nil), // 32: coder.agent.v2.WorkspaceApp.Healthcheck
|
||||
(*WorkspaceAgentMetadata_Result)(nil), // 33: coder.agent.v2.WorkspaceAgentMetadata.Result
|
||||
@@ -2911,7 +2911,7 @@ var file_agent_proto_agent_proto_depIdxs = []int32{
|
||||
42, // 23: coder.agent.v2.Log.created_at:type_name -> google.protobuf.Timestamp
|
||||
6, // 24: coder.agent.v2.Log.level:type_name -> coder.agent.v2.Log.Level
|
||||
26, // 25: coder.agent.v2.BatchCreateLogsRequest.logs:type_name -> coder.agent.v2.Log
|
||||
31, // 26: coder.agent.v2.GetNotificationBannersResponse.notification_banners:type_name -> coder.agent.v2.BannerConfig
|
||||
31, // 26: coder.agent.v2.GetAnnouncementBannersResponse.announcement_banners:type_name -> coder.agent.v2.BannerConfig
|
||||
40, // 27: coder.agent.v2.WorkspaceApp.Healthcheck.interval:type_name -> google.protobuf.Duration
|
||||
42, // 28: coder.agent.v2.WorkspaceAgentMetadata.Result.collected_at:type_name -> google.protobuf.Timestamp
|
||||
40, // 29: coder.agent.v2.WorkspaceAgentMetadata.Description.interval:type_name -> google.protobuf.Duration
|
||||
@@ -2927,7 +2927,7 @@ var file_agent_proto_agent_proto_depIdxs = []int32{
|
||||
22, // 39: coder.agent.v2.Agent.UpdateStartup:input_type -> coder.agent.v2.UpdateStartupRequest
|
||||
24, // 40: coder.agent.v2.Agent.BatchUpdateMetadata:input_type -> coder.agent.v2.BatchUpdateMetadataRequest
|
||||
27, // 41: coder.agent.v2.Agent.BatchCreateLogs:input_type -> coder.agent.v2.BatchCreateLogsRequest
|
||||
29, // 42: coder.agent.v2.Agent.GetNotificationBanners:input_type -> coder.agent.v2.GetNotificationBannersRequest
|
||||
29, // 42: coder.agent.v2.Agent.GetAnnouncementBanners:input_type -> coder.agent.v2.GetAnnouncementBannersRequest
|
||||
10, // 43: coder.agent.v2.Agent.GetManifest:output_type -> coder.agent.v2.Manifest
|
||||
12, // 44: coder.agent.v2.Agent.GetServiceBanner:output_type -> coder.agent.v2.ServiceBanner
|
||||
16, // 45: coder.agent.v2.Agent.UpdateStats:output_type -> coder.agent.v2.UpdateStatsResponse
|
||||
@@ -2936,7 +2936,7 @@ var file_agent_proto_agent_proto_depIdxs = []int32{
|
||||
21, // 48: coder.agent.v2.Agent.UpdateStartup:output_type -> coder.agent.v2.Startup
|
||||
25, // 49: coder.agent.v2.Agent.BatchUpdateMetadata:output_type -> coder.agent.v2.BatchUpdateMetadataResponse
|
||||
28, // 50: coder.agent.v2.Agent.BatchCreateLogs:output_type -> coder.agent.v2.BatchCreateLogsResponse
|
||||
30, // 51: coder.agent.v2.Agent.GetNotificationBanners:output_type -> coder.agent.v2.GetNotificationBannersResponse
|
||||
30, // 51: coder.agent.v2.Agent.GetAnnouncementBanners:output_type -> coder.agent.v2.GetAnnouncementBannersResponse
|
||||
43, // [43:52] is the sub-list for method output_type
|
||||
34, // [34:43] is the sub-list for method input_type
|
||||
34, // [34:34] is the sub-list for extension type_name
|
||||
@@ -3215,7 +3215,7 @@ func file_agent_proto_agent_proto_init() {
|
||||
}
|
||||
}
|
||||
file_agent_proto_agent_proto_msgTypes[22].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*GetNotificationBannersRequest); i {
|
||||
switch v := v.(*GetAnnouncementBannersRequest); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
@@ -3227,7 +3227,7 @@ func file_agent_proto_agent_proto_init() {
|
||||
}
|
||||
}
|
||||
file_agent_proto_agent_proto_msgTypes[23].Exporter = func(v interface{}, i int) interface{} {
|
||||
switch v := v.(*GetNotificationBannersResponse); i {
|
||||
switch v := v.(*GetAnnouncementBannersResponse); i {
|
||||
case 0:
|
||||
return &v.state
|
||||
case 1:
|
||||
|
||||
@@ -251,10 +251,10 @@ message BatchCreateLogsResponse {
|
||||
bool log_limit_exceeded = 1;
|
||||
}
|
||||
|
||||
message GetNotificationBannersRequest {}
|
||||
message GetAnnouncementBannersRequest {}
|
||||
|
||||
message GetNotificationBannersResponse {
|
||||
repeated BannerConfig notification_banners = 1;
|
||||
message GetAnnouncementBannersResponse {
|
||||
repeated BannerConfig announcement_banners = 1;
|
||||
}
|
||||
|
||||
message BannerConfig {
|
||||
@@ -272,5 +272,5 @@ service Agent {
|
||||
rpc UpdateStartup(UpdateStartupRequest) returns (Startup);
|
||||
rpc BatchUpdateMetadata(BatchUpdateMetadataRequest) returns (BatchUpdateMetadataResponse);
|
||||
rpc BatchCreateLogs(BatchCreateLogsRequest) returns (BatchCreateLogsResponse);
|
||||
rpc GetNotificationBanners(GetNotificationBannersRequest) returns (GetNotificationBannersResponse);
|
||||
rpc GetAnnouncementBanners(GetAnnouncementBannersRequest) returns (GetAnnouncementBannersResponse);
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ type DRPCAgentClient interface {
|
||||
UpdateStartup(ctx context.Context, in *UpdateStartupRequest) (*Startup, error)
|
||||
BatchUpdateMetadata(ctx context.Context, in *BatchUpdateMetadataRequest) (*BatchUpdateMetadataResponse, error)
|
||||
BatchCreateLogs(ctx context.Context, in *BatchCreateLogsRequest) (*BatchCreateLogsResponse, error)
|
||||
GetNotificationBanners(ctx context.Context, in *GetNotificationBannersRequest) (*GetNotificationBannersResponse, error)
|
||||
GetAnnouncementBanners(ctx context.Context, in *GetAnnouncementBannersRequest) (*GetAnnouncementBannersResponse, error)
|
||||
}
|
||||
|
||||
type drpcAgentClient struct {
|
||||
@@ -131,9 +131,9 @@ func (c *drpcAgentClient) BatchCreateLogs(ctx context.Context, in *BatchCreateLo
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *drpcAgentClient) GetNotificationBanners(ctx context.Context, in *GetNotificationBannersRequest) (*GetNotificationBannersResponse, error) {
|
||||
out := new(GetNotificationBannersResponse)
|
||||
err := c.cc.Invoke(ctx, "/coder.agent.v2.Agent/GetNotificationBanners", drpcEncoding_File_agent_proto_agent_proto{}, in, out)
|
||||
func (c *drpcAgentClient) GetAnnouncementBanners(ctx context.Context, in *GetAnnouncementBannersRequest) (*GetAnnouncementBannersResponse, error) {
|
||||
out := new(GetAnnouncementBannersResponse)
|
||||
err := c.cc.Invoke(ctx, "/coder.agent.v2.Agent/GetAnnouncementBanners", drpcEncoding_File_agent_proto_agent_proto{}, in, out)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -149,7 +149,7 @@ type DRPCAgentServer interface {
|
||||
UpdateStartup(context.Context, *UpdateStartupRequest) (*Startup, error)
|
||||
BatchUpdateMetadata(context.Context, *BatchUpdateMetadataRequest) (*BatchUpdateMetadataResponse, error)
|
||||
BatchCreateLogs(context.Context, *BatchCreateLogsRequest) (*BatchCreateLogsResponse, error)
|
||||
GetNotificationBanners(context.Context, *GetNotificationBannersRequest) (*GetNotificationBannersResponse, error)
|
||||
GetAnnouncementBanners(context.Context, *GetAnnouncementBannersRequest) (*GetAnnouncementBannersResponse, error)
|
||||
}
|
||||
|
||||
type DRPCAgentUnimplementedServer struct{}
|
||||
@@ -186,7 +186,7 @@ func (s *DRPCAgentUnimplementedServer) BatchCreateLogs(context.Context, *BatchCr
|
||||
return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented)
|
||||
}
|
||||
|
||||
func (s *DRPCAgentUnimplementedServer) GetNotificationBanners(context.Context, *GetNotificationBannersRequest) (*GetNotificationBannersResponse, error) {
|
||||
func (s *DRPCAgentUnimplementedServer) GetAnnouncementBanners(context.Context, *GetAnnouncementBannersRequest) (*GetAnnouncementBannersResponse, error) {
|
||||
return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented)
|
||||
}
|
||||
|
||||
@@ -269,14 +269,14 @@ func (DRPCAgentDescription) Method(n int) (string, drpc.Encoding, drpc.Receiver,
|
||||
)
|
||||
}, DRPCAgentServer.BatchCreateLogs, true
|
||||
case 8:
|
||||
return "/coder.agent.v2.Agent/GetNotificationBanners", drpcEncoding_File_agent_proto_agent_proto{},
|
||||
return "/coder.agent.v2.Agent/GetAnnouncementBanners", drpcEncoding_File_agent_proto_agent_proto{},
|
||||
func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) {
|
||||
return srv.(DRPCAgentServer).
|
||||
GetNotificationBanners(
|
||||
GetAnnouncementBanners(
|
||||
ctx,
|
||||
in1.(*GetNotificationBannersRequest),
|
||||
in1.(*GetAnnouncementBannersRequest),
|
||||
)
|
||||
}, DRPCAgentServer.GetNotificationBanners, true
|
||||
}, DRPCAgentServer.GetAnnouncementBanners, true
|
||||
default:
|
||||
return "", nil, nil, nil, false
|
||||
}
|
||||
@@ -414,16 +414,16 @@ func (x *drpcAgent_BatchCreateLogsStream) SendAndClose(m *BatchCreateLogsRespons
|
||||
return x.CloseSend()
|
||||
}
|
||||
|
||||
type DRPCAgent_GetNotificationBannersStream interface {
|
||||
type DRPCAgent_GetAnnouncementBannersStream interface {
|
||||
drpc.Stream
|
||||
SendAndClose(*GetNotificationBannersResponse) error
|
||||
SendAndClose(*GetAnnouncementBannersResponse) error
|
||||
}
|
||||
|
||||
type drpcAgent_GetNotificationBannersStream struct {
|
||||
type drpcAgent_GetAnnouncementBannersStream struct {
|
||||
drpc.Stream
|
||||
}
|
||||
|
||||
func (x *drpcAgent_GetNotificationBannersStream) SendAndClose(m *GetNotificationBannersResponse) error {
|
||||
func (x *drpcAgent_GetAnnouncementBannersStream) SendAndClose(m *GetAnnouncementBannersResponse) error {
|
||||
if err := x.MsgSend(m, drpcEncoding_File_agent_proto_agent_proto{}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -11,12 +11,12 @@ import (
|
||||
"github.com/coder/coder/v2/codersdk/agentsdk"
|
||||
)
|
||||
|
||||
type NotificationBannerAPI struct {
|
||||
type AnnouncementBannerAPI struct {
|
||||
appearanceFetcher *atomic.Pointer[appearance.Fetcher]
|
||||
}
|
||||
|
||||
// Deprecated: GetServiceBanner has been deprecated in favor of GetNotificationBanners.
|
||||
func (a *NotificationBannerAPI) GetServiceBanner(ctx context.Context, _ *proto.GetServiceBannerRequest) (*proto.ServiceBanner, error) {
|
||||
// Deprecated: GetServiceBanner has been deprecated in favor of GetAnnouncementBanners.
|
||||
func (a *AnnouncementBannerAPI) GetServiceBanner(ctx context.Context, _ *proto.GetServiceBannerRequest) (*proto.ServiceBanner, error) {
|
||||
cfg, err := (*a.appearanceFetcher.Load()).Fetch(ctx)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("fetch appearance: %w", err)
|
||||
@@ -24,16 +24,16 @@ func (a *NotificationBannerAPI) GetServiceBanner(ctx context.Context, _ *proto.G
|
||||
return agentsdk.ProtoFromServiceBanner(cfg.ServiceBanner), nil
|
||||
}
|
||||
|
||||
func (a *NotificationBannerAPI) GetNotificationBanners(ctx context.Context, _ *proto.GetNotificationBannersRequest) (*proto.GetNotificationBannersResponse, error) {
|
||||
func (a *AnnouncementBannerAPI) GetAnnouncementBanners(ctx context.Context, _ *proto.GetAnnouncementBannersRequest) (*proto.GetAnnouncementBannersResponse, error) {
|
||||
cfg, err := (*a.appearanceFetcher.Load()).Fetch(ctx)
|
||||
if err != nil {
|
||||
return nil, xerrors.Errorf("fetch appearance: %w", err)
|
||||
}
|
||||
banners := make([]*proto.BannerConfig, 0, len(cfg.NotificationBanners))
|
||||
for _, banner := range cfg.NotificationBanners {
|
||||
banners := make([]*proto.BannerConfig, 0, len(cfg.AnnouncementBanners))
|
||||
for _, banner := range cfg.AnnouncementBanners {
|
||||
banners = append(banners, agentsdk.ProtoFromBannerConfig(banner))
|
||||
}
|
||||
return &proto.GetNotificationBannersResponse{
|
||||
NotificationBanners: banners,
|
||||
return &proto.GetAnnouncementBannersResponse{
|
||||
AnnouncementBanners: banners,
|
||||
}, nil
|
||||
}
|
||||
+8
-8
@@ -14,7 +14,7 @@ import (
|
||||
"github.com/coder/coder/v2/codersdk/agentsdk"
|
||||
)
|
||||
|
||||
func TestGetNotificationBanners(t *testing.T) {
|
||||
func TestGetAnnouncementBanners(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
t.Run("OK", func(t *testing.T) {
|
||||
@@ -26,15 +26,15 @@ func TestGetNotificationBanners(t *testing.T) {
|
||||
BackgroundColor: "#00FF00",
|
||||
}}
|
||||
|
||||
var ff appearance.Fetcher = fakeFetcher{cfg: codersdk.AppearanceConfig{NotificationBanners: cfg}}
|
||||
var ff appearance.Fetcher = fakeFetcher{cfg: codersdk.AppearanceConfig{AnnouncementBanners: cfg}}
|
||||
ptr := atomic.Pointer[appearance.Fetcher]{}
|
||||
ptr.Store(&ff)
|
||||
|
||||
api := &NotificationBannerAPI{appearanceFetcher: &ptr}
|
||||
resp, err := api.GetNotificationBanners(context.Background(), &agentproto.GetNotificationBannersRequest{})
|
||||
api := &AnnouncementBannerAPI{appearanceFetcher: &ptr}
|
||||
resp, err := api.GetAnnouncementBanners(context.Background(), &agentproto.GetAnnouncementBannersRequest{})
|
||||
require.NoError(t, err)
|
||||
require.Len(t, resp.NotificationBanners, 1)
|
||||
require.Equal(t, cfg[0], agentsdk.BannerConfigFromProto(resp.NotificationBanners[0]))
|
||||
require.Len(t, resp.AnnouncementBanners, 1)
|
||||
require.Equal(t, cfg[0], agentsdk.BannerConfigFromProto(resp.AnnouncementBanners[0]))
|
||||
})
|
||||
|
||||
t.Run("FetchError", func(t *testing.T) {
|
||||
@@ -45,8 +45,8 @@ func TestGetNotificationBanners(t *testing.T) {
|
||||
ptr := atomic.Pointer[appearance.Fetcher]{}
|
||||
ptr.Store(&ff)
|
||||
|
||||
api := &NotificationBannerAPI{appearanceFetcher: &ptr}
|
||||
resp, err := api.GetNotificationBanners(context.Background(), &agentproto.GetNotificationBannersRequest{})
|
||||
api := &AnnouncementBannerAPI{appearanceFetcher: &ptr}
|
||||
resp, err := api.GetAnnouncementBanners(context.Background(), &agentproto.GetAnnouncementBannersRequest{})
|
||||
require.Error(t, err)
|
||||
require.ErrorIs(t, err, expectedErr)
|
||||
require.Nil(t, resp)
|
||||
@@ -36,7 +36,7 @@ import (
|
||||
type API struct {
|
||||
opts Options
|
||||
*ManifestAPI
|
||||
*NotificationBannerAPI
|
||||
*AnnouncementBannerAPI
|
||||
*StatsAPI
|
||||
*LifecycleAPI
|
||||
*AppsAPI
|
||||
@@ -108,7 +108,7 @@ func New(opts Options) *API {
|
||||
},
|
||||
}
|
||||
|
||||
api.NotificationBannerAPI = &NotificationBannerAPI{
|
||||
api.AnnouncementBannerAPI = &AnnouncementBannerAPI{
|
||||
appearanceFetcher: opts.AppearanceFetcher,
|
||||
}
|
||||
|
||||
|
||||
Generated
+14
-14
@@ -8378,20 +8378,20 @@ const docTemplate = `{
|
||||
"codersdk.AppearanceConfig": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"announcement_banners": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/codersdk.BannerConfig"
|
||||
}
|
||||
},
|
||||
"application_name": {
|
||||
"type": "string"
|
||||
},
|
||||
"logo_url": {
|
||||
"type": "string"
|
||||
},
|
||||
"notification_banners": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/codersdk.BannerConfig"
|
||||
}
|
||||
},
|
||||
"service_banner": {
|
||||
"description": "Deprecated: ServiceBanner has been replaced by NotificationBanners.",
|
||||
"description": "Deprecated: ServiceBanner has been replaced by AnnouncementBanners.",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/codersdk.BannerConfig"
|
||||
@@ -12148,20 +12148,20 @@ const docTemplate = `{
|
||||
"codersdk.UpdateAppearanceConfig": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"announcement_banners": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/codersdk.BannerConfig"
|
||||
}
|
||||
},
|
||||
"application_name": {
|
||||
"type": "string"
|
||||
},
|
||||
"logo_url": {
|
||||
"type": "string"
|
||||
},
|
||||
"notification_banners": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/codersdk.BannerConfig"
|
||||
}
|
||||
},
|
||||
"service_banner": {
|
||||
"description": "Deprecated: ServiceBanner has been replaced by NotificationBanners.",
|
||||
"description": "Deprecated: ServiceBanner has been replaced by AnnouncementBanners.",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/codersdk.BannerConfig"
|
||||
|
||||
Generated
+14
-14
@@ -7433,20 +7433,20 @@
|
||||
"codersdk.AppearanceConfig": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"announcement_banners": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/codersdk.BannerConfig"
|
||||
}
|
||||
},
|
||||
"application_name": {
|
||||
"type": "string"
|
||||
},
|
||||
"logo_url": {
|
||||
"type": "string"
|
||||
},
|
||||
"notification_banners": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/codersdk.BannerConfig"
|
||||
}
|
||||
},
|
||||
"service_banner": {
|
||||
"description": "Deprecated: ServiceBanner has been replaced by NotificationBanners.",
|
||||
"description": "Deprecated: ServiceBanner has been replaced by AnnouncementBanners.",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/codersdk.BannerConfig"
|
||||
@@ -10997,20 +10997,20 @@
|
||||
"codersdk.UpdateAppearanceConfig": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"announcement_banners": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/codersdk.BannerConfig"
|
||||
}
|
||||
},
|
||||
"application_name": {
|
||||
"type": "string"
|
||||
},
|
||||
"logo_url": {
|
||||
"type": "string"
|
||||
},
|
||||
"notification_banners": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/codersdk.BannerConfig"
|
||||
}
|
||||
},
|
||||
"service_banner": {
|
||||
"description": "Deprecated: ServiceBanner has been replaced by NotificationBanners.",
|
||||
"description": "Deprecated: ServiceBanner has been replaced by AnnouncementBanners.",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/codersdk.BannerConfig"
|
||||
|
||||
@@ -32,7 +32,7 @@ type AGPLFetcher struct{}
|
||||
|
||||
func (AGPLFetcher) Fetch(context.Context) (codersdk.AppearanceConfig, error) {
|
||||
return codersdk.AppearanceConfig{
|
||||
NotificationBanners: []codersdk.BannerConfig{},
|
||||
AnnouncementBanners: []codersdk.BannerConfig{},
|
||||
SupportLinks: DefaultSupportLinks,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -1142,6 +1142,11 @@ func (q *querier) GetAllTailnetTunnels(ctx context.Context) ([]database.TailnetT
|
||||
return q.db.GetAllTailnetTunnels(ctx)
|
||||
}
|
||||
|
||||
func (q *querier) GetAnnouncementBanners(ctx context.Context) (string, error) {
|
||||
// No authz checks
|
||||
return q.db.GetAnnouncementBanners(ctx)
|
||||
}
|
||||
|
||||
func (q *querier) GetAppSecurityKey(ctx context.Context) (string, error) {
|
||||
// No authz checks
|
||||
return q.db.GetAppSecurityKey(ctx)
|
||||
@@ -1359,11 +1364,6 @@ func (q *querier) GetLogoURL(ctx context.Context) (string, error) {
|
||||
return q.db.GetLogoURL(ctx)
|
||||
}
|
||||
|
||||
func (q *querier) GetNotificationBanners(ctx context.Context) (string, error) {
|
||||
// No authz checks
|
||||
return q.db.GetNotificationBanners(ctx)
|
||||
}
|
||||
|
||||
func (q *querier) GetOAuth2ProviderAppByID(ctx context.Context, id uuid.UUID) (database.OAuth2ProviderApp, error) {
|
||||
if err := q.authorizeContext(ctx, policy.ActionRead, rbac.ResourceOauth2App); err != nil {
|
||||
return database.OAuth2ProviderApp{}, err
|
||||
@@ -3405,6 +3405,13 @@ func (q *querier) UpdateWorkspacesDormantDeletingAtByTemplateID(ctx context.Cont
|
||||
return fetchAndExec(q.log, q.auth, policy.ActionUpdate, fetch, q.db.UpdateWorkspacesDormantDeletingAtByTemplateID)(ctx, arg)
|
||||
}
|
||||
|
||||
func (q *querier) UpsertAnnouncementBanners(ctx context.Context, value string) error {
|
||||
if err := q.authorizeContext(ctx, policy.ActionUpdate, rbac.ResourceDeploymentConfig); err != nil {
|
||||
return err
|
||||
}
|
||||
return q.db.UpsertAnnouncementBanners(ctx, value)
|
||||
}
|
||||
|
||||
func (q *querier) UpsertAppSecurityKey(ctx context.Context, data string) error {
|
||||
// No authz checks as this is done during startup
|
||||
return q.db.UpsertAppSecurityKey(ctx, data)
|
||||
@@ -3538,13 +3545,6 @@ func (q *querier) UpsertLogoURL(ctx context.Context, value string) error {
|
||||
return q.db.UpsertLogoURL(ctx, value)
|
||||
}
|
||||
|
||||
func (q *querier) UpsertNotificationBanners(ctx context.Context, value string) error {
|
||||
if err := q.authorizeContext(ctx, policy.ActionUpdate, rbac.ResourceDeploymentConfig); err != nil {
|
||||
return err
|
||||
}
|
||||
return q.db.UpsertNotificationBanners(ctx, value)
|
||||
}
|
||||
|
||||
func (q *querier) UpsertOAuthSigningKey(ctx context.Context, value string) error {
|
||||
if err := q.authorizeContext(ctx, policy.ActionUpdate, rbac.ResourceSystem); err != nil {
|
||||
return err
|
||||
|
||||
@@ -528,7 +528,7 @@ func (s *MethodTestSuite) TestLicense() {
|
||||
s.Run("UpsertLogoURL", s.Subtest(func(db database.Store, check *expects) {
|
||||
check.Args("value").Asserts(rbac.ResourceDeploymentConfig, policy.ActionUpdate)
|
||||
}))
|
||||
s.Run("UpsertNotificationBanners", s.Subtest(func(db database.Store, check *expects) {
|
||||
s.Run("UpsertAnnouncementBanners", s.Subtest(func(db database.Store, check *expects) {
|
||||
check.Args("value").Asserts(rbac.ResourceDeploymentConfig, policy.ActionUpdate)
|
||||
}))
|
||||
s.Run("GetLicenseByID", s.Subtest(func(db database.Store, check *expects) {
|
||||
@@ -559,8 +559,8 @@ func (s *MethodTestSuite) TestLicense() {
|
||||
require.NoError(s.T(), err)
|
||||
check.Args().Asserts().Returns("value")
|
||||
}))
|
||||
s.Run("GetNotificationBanners", s.Subtest(func(db database.Store, check *expects) {
|
||||
err := db.UpsertNotificationBanners(context.Background(), "value")
|
||||
s.Run("GetAnnouncementBanners", s.Subtest(func(db database.Store, check *expects) {
|
||||
err := db.UpsertAnnouncementBanners(context.Background(), "value")
|
||||
require.NoError(s.T(), err)
|
||||
check.Args().Asserts().Returns("value")
|
||||
}))
|
||||
|
||||
@@ -191,7 +191,7 @@ type data struct {
|
||||
deploymentID string
|
||||
derpMeshKey string
|
||||
lastUpdateCheck []byte
|
||||
notificationBanners []byte
|
||||
announcementBanners []byte
|
||||
healthSettings []byte
|
||||
applicationName string
|
||||
logoURL string
|
||||
@@ -1857,6 +1857,17 @@ func (*FakeQuerier) GetAllTailnetTunnels(context.Context) ([]database.TailnetTun
|
||||
return nil, ErrUnimplemented
|
||||
}
|
||||
|
||||
func (q *FakeQuerier) GetAnnouncementBanners(_ context.Context) (string, error) {
|
||||
q.mutex.RLock()
|
||||
defer q.mutex.RUnlock()
|
||||
|
||||
if q.announcementBanners == nil {
|
||||
return "", sql.ErrNoRows
|
||||
}
|
||||
|
||||
return string(q.announcementBanners), nil
|
||||
}
|
||||
|
||||
func (q *FakeQuerier) GetAppSecurityKey(_ context.Context) (string, error) {
|
||||
q.mutex.RLock()
|
||||
defer q.mutex.RUnlock()
|
||||
@@ -2540,17 +2551,6 @@ func (q *FakeQuerier) GetLogoURL(_ context.Context) (string, error) {
|
||||
return q.logoURL, nil
|
||||
}
|
||||
|
||||
func (q *FakeQuerier) GetNotificationBanners(_ context.Context) (string, error) {
|
||||
q.mutex.RLock()
|
||||
defer q.mutex.RUnlock()
|
||||
|
||||
if q.notificationBanners == nil {
|
||||
return "", sql.ErrNoRows
|
||||
}
|
||||
|
||||
return string(q.notificationBanners), nil
|
||||
}
|
||||
|
||||
func (q *FakeQuerier) GetOAuth2ProviderAppByID(_ context.Context, id uuid.UUID) (database.OAuth2ProviderApp, error) {
|
||||
q.mutex.Lock()
|
||||
defer q.mutex.Unlock()
|
||||
@@ -8358,6 +8358,14 @@ func (q *FakeQuerier) UpdateWorkspacesDormantDeletingAtByTemplateID(_ context.Co
|
||||
return nil
|
||||
}
|
||||
|
||||
func (q *FakeQuerier) UpsertAnnouncementBanners(_ context.Context, data string) error {
|
||||
q.mutex.RLock()
|
||||
defer q.mutex.RUnlock()
|
||||
|
||||
q.announcementBanners = []byte(data)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (q *FakeQuerier) UpsertAppSecurityKey(_ context.Context, data string) error {
|
||||
q.mutex.Lock()
|
||||
defer q.mutex.Unlock()
|
||||
@@ -8472,14 +8480,6 @@ func (q *FakeQuerier) UpsertLogoURL(_ context.Context, data string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (q *FakeQuerier) UpsertNotificationBanners(_ context.Context, data string) error {
|
||||
q.mutex.RLock()
|
||||
defer q.mutex.RUnlock()
|
||||
|
||||
q.notificationBanners = []byte(data)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (q *FakeQuerier) UpsertOAuthSigningKey(_ context.Context, value string) error {
|
||||
q.mutex.Lock()
|
||||
defer q.mutex.Unlock()
|
||||
|
||||
@@ -431,6 +431,13 @@ func (m metricsStore) GetAllTailnetTunnels(ctx context.Context) ([]database.Tail
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
func (m metricsStore) GetAnnouncementBanners(ctx context.Context) (string, error) {
|
||||
start := time.Now()
|
||||
r0, r1 := m.s.GetAnnouncementBanners(ctx)
|
||||
m.queryLatencies.WithLabelValues("GetAnnouncementBanners").Observe(time.Since(start).Seconds())
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
func (m metricsStore) GetAppSecurityKey(ctx context.Context) (string, error) {
|
||||
start := time.Now()
|
||||
key, err := m.s.GetAppSecurityKey(ctx)
|
||||
@@ -662,13 +669,6 @@ func (m metricsStore) GetLogoURL(ctx context.Context) (string, error) {
|
||||
return url, err
|
||||
}
|
||||
|
||||
func (m metricsStore) GetNotificationBanners(ctx context.Context) (string, error) {
|
||||
start := time.Now()
|
||||
r0, r1 := m.s.GetNotificationBanners(ctx)
|
||||
m.queryLatencies.WithLabelValues("GetNotificationBanners").Observe(time.Since(start).Seconds())
|
||||
return r0, r1
|
||||
}
|
||||
|
||||
func (m metricsStore) GetOAuth2ProviderAppByID(ctx context.Context, id uuid.UUID) (database.OAuth2ProviderApp, error) {
|
||||
start := time.Now()
|
||||
r0, r1 := m.s.GetOAuth2ProviderAppByID(ctx, id)
|
||||
@@ -2174,6 +2174,13 @@ func (m metricsStore) UpdateWorkspacesDormantDeletingAtByTemplateID(ctx context.
|
||||
return r0
|
||||
}
|
||||
|
||||
func (m metricsStore) UpsertAnnouncementBanners(ctx context.Context, value string) error {
|
||||
start := time.Now()
|
||||
r0 := m.s.UpsertAnnouncementBanners(ctx, value)
|
||||
m.queryLatencies.WithLabelValues("UpsertAnnouncementBanners").Observe(time.Since(start).Seconds())
|
||||
return r0
|
||||
}
|
||||
|
||||
func (m metricsStore) UpsertAppSecurityKey(ctx context.Context, value string) error {
|
||||
start := time.Now()
|
||||
r0 := m.s.UpsertAppSecurityKey(ctx, value)
|
||||
@@ -2230,13 +2237,6 @@ func (m metricsStore) UpsertLogoURL(ctx context.Context, value string) error {
|
||||
return r0
|
||||
}
|
||||
|
||||
func (m metricsStore) UpsertNotificationBanners(ctx context.Context, value string) error {
|
||||
start := time.Now()
|
||||
r0 := m.s.UpsertNotificationBanners(ctx, value)
|
||||
m.queryLatencies.WithLabelValues("UpsertNotificationBanners").Observe(time.Since(start).Seconds())
|
||||
return r0
|
||||
}
|
||||
|
||||
func (m metricsStore) UpsertOAuthSigningKey(ctx context.Context, value string) error {
|
||||
start := time.Now()
|
||||
r0 := m.s.UpsertOAuthSigningKey(ctx, value)
|
||||
|
||||
@@ -764,6 +764,21 @@ func (mr *MockStoreMockRecorder) GetAllTailnetTunnels(arg0 any) *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAllTailnetTunnels", reflect.TypeOf((*MockStore)(nil).GetAllTailnetTunnels), arg0)
|
||||
}
|
||||
|
||||
// GetAnnouncementBanners mocks base method.
|
||||
func (m *MockStore) GetAnnouncementBanners(arg0 context.Context) (string, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetAnnouncementBanners", arg0)
|
||||
ret0, _ := ret[0].(string)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// GetAnnouncementBanners indicates an expected call of GetAnnouncementBanners.
|
||||
func (mr *MockStoreMockRecorder) GetAnnouncementBanners(arg0 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetAnnouncementBanners", reflect.TypeOf((*MockStore)(nil).GetAnnouncementBanners), arg0)
|
||||
}
|
||||
|
||||
// GetAppSecurityKey mocks base method.
|
||||
func (m *MockStore) GetAppSecurityKey(arg0 context.Context) (string, error) {
|
||||
m.ctrl.T.Helper()
|
||||
@@ -1304,21 +1319,6 @@ func (mr *MockStoreMockRecorder) GetLogoURL(arg0 any) *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetLogoURL", reflect.TypeOf((*MockStore)(nil).GetLogoURL), arg0)
|
||||
}
|
||||
|
||||
// GetNotificationBanners mocks base method.
|
||||
func (m *MockStore) GetNotificationBanners(arg0 context.Context) (string, error) {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetNotificationBanners", arg0)
|
||||
ret0, _ := ret[0].(string)
|
||||
ret1, _ := ret[1].(error)
|
||||
return ret0, ret1
|
||||
}
|
||||
|
||||
// GetNotificationBanners indicates an expected call of GetNotificationBanners.
|
||||
func (mr *MockStoreMockRecorder) GetNotificationBanners(arg0 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetNotificationBanners", reflect.TypeOf((*MockStore)(nil).GetNotificationBanners), arg0)
|
||||
}
|
||||
|
||||
// GetOAuth2ProviderAppByID mocks base method.
|
||||
func (m *MockStore) GetOAuth2ProviderAppByID(arg0 context.Context, arg1 uuid.UUID) (database.OAuth2ProviderApp, error) {
|
||||
m.ctrl.T.Helper()
|
||||
@@ -4553,6 +4553,20 @@ func (mr *MockStoreMockRecorder) UpdateWorkspacesDormantDeletingAtByTemplateID(a
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpdateWorkspacesDormantDeletingAtByTemplateID", reflect.TypeOf((*MockStore)(nil).UpdateWorkspacesDormantDeletingAtByTemplateID), arg0, arg1)
|
||||
}
|
||||
|
||||
// UpsertAnnouncementBanners mocks base method.
|
||||
func (m *MockStore) UpsertAnnouncementBanners(arg0 context.Context, arg1 string) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "UpsertAnnouncementBanners", arg0, arg1)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// UpsertAnnouncementBanners indicates an expected call of UpsertAnnouncementBanners.
|
||||
func (mr *MockStoreMockRecorder) UpsertAnnouncementBanners(arg0, arg1 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpsertAnnouncementBanners", reflect.TypeOf((*MockStore)(nil).UpsertAnnouncementBanners), arg0, arg1)
|
||||
}
|
||||
|
||||
// UpsertAppSecurityKey mocks base method.
|
||||
func (m *MockStore) UpsertAppSecurityKey(arg0 context.Context, arg1 string) error {
|
||||
m.ctrl.T.Helper()
|
||||
@@ -4666,20 +4680,6 @@ func (mr *MockStoreMockRecorder) UpsertLogoURL(arg0, arg1 any) *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpsertLogoURL", reflect.TypeOf((*MockStore)(nil).UpsertLogoURL), arg0, arg1)
|
||||
}
|
||||
|
||||
// UpsertNotificationBanners mocks base method.
|
||||
func (m *MockStore) UpsertNotificationBanners(arg0 context.Context, arg1 string) error {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "UpsertNotificationBanners", arg0, arg1)
|
||||
ret0, _ := ret[0].(error)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// UpsertNotificationBanners indicates an expected call of UpsertNotificationBanners.
|
||||
func (mr *MockStoreMockRecorder) UpsertNotificationBanners(arg0, arg1 any) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UpsertNotificationBanners", reflect.TypeOf((*MockStore)(nil).UpsertNotificationBanners), arg0, arg1)
|
||||
}
|
||||
|
||||
// UpsertOAuthSigningKey mocks base method.
|
||||
func (m *MockStore) UpsertOAuthSigningKey(arg0 context.Context, arg1 string) error {
|
||||
m.ctrl.T.Helper()
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
update site_configs SET
|
||||
key = 'notification_banners'
|
||||
where key = 'announcement_banners';
|
||||
@@ -0,0 +1,3 @@
|
||||
update site_configs SET
|
||||
key = 'announcement_banners'
|
||||
where key = 'notification_banners';
|
||||
@@ -97,6 +97,7 @@ type sqlcQuerier interface {
|
||||
GetAllTailnetCoordinators(ctx context.Context) ([]TailnetCoordinator, error)
|
||||
GetAllTailnetPeers(ctx context.Context) ([]TailnetPeer, error)
|
||||
GetAllTailnetTunnels(ctx context.Context) ([]TailnetTunnel, error)
|
||||
GetAnnouncementBanners(ctx context.Context) (string, error)
|
||||
GetAppSecurityKey(ctx context.Context) (string, error)
|
||||
GetApplicationName(ctx context.Context) (string, error)
|
||||
// GetAuditLogsBefore retrieves `row_limit` number of audit logs before the provided
|
||||
@@ -137,7 +138,6 @@ type sqlcQuerier interface {
|
||||
GetLicenseByID(ctx context.Context, id int32) (License, error)
|
||||
GetLicenses(ctx context.Context) ([]License, error)
|
||||
GetLogoURL(ctx context.Context) (string, error)
|
||||
GetNotificationBanners(ctx context.Context) (string, error)
|
||||
GetOAuth2ProviderAppByID(ctx context.Context, id uuid.UUID) (OAuth2ProviderApp, error)
|
||||
GetOAuth2ProviderAppCodeByID(ctx context.Context, id uuid.UUID) (OAuth2ProviderAppCode, error)
|
||||
GetOAuth2ProviderAppCodeByPrefix(ctx context.Context, secretPrefix []byte) (OAuth2ProviderAppCode, error)
|
||||
@@ -416,6 +416,7 @@ type sqlcQuerier interface {
|
||||
UpdateWorkspaceProxyDeleted(ctx context.Context, arg UpdateWorkspaceProxyDeletedParams) error
|
||||
UpdateWorkspaceTTL(ctx context.Context, arg UpdateWorkspaceTTLParams) error
|
||||
UpdateWorkspacesDormantDeletingAtByTemplateID(ctx context.Context, arg UpdateWorkspacesDormantDeletingAtByTemplateIDParams) error
|
||||
UpsertAnnouncementBanners(ctx context.Context, value string) error
|
||||
UpsertAppSecurityKey(ctx context.Context, value string) error
|
||||
UpsertApplicationName(ctx context.Context, value string) error
|
||||
UpsertCustomRole(ctx context.Context, arg UpsertCustomRoleParams) (CustomRole, error)
|
||||
@@ -427,7 +428,6 @@ type sqlcQuerier interface {
|
||||
UpsertJFrogXrayScanByWorkspaceAndAgentID(ctx context.Context, arg UpsertJFrogXrayScanByWorkspaceAndAgentIDParams) error
|
||||
UpsertLastUpdateCheck(ctx context.Context, value string) error
|
||||
UpsertLogoURL(ctx context.Context, value string) error
|
||||
UpsertNotificationBanners(ctx context.Context, value string) error
|
||||
UpsertOAuthSigningKey(ctx context.Context, value string) error
|
||||
UpsertProvisionerDaemon(ctx context.Context, arg UpsertProvisionerDaemonParams) (ProvisionerDaemon, error)
|
||||
UpsertTailnetAgent(ctx context.Context, arg UpsertTailnetAgentParams) (TailnetAgent, error)
|
||||
|
||||
@@ -5727,6 +5727,17 @@ func (q *sqlQuerier) UpsertCustomRole(ctx context.Context, arg UpsertCustomRoleP
|
||||
return i, err
|
||||
}
|
||||
|
||||
const getAnnouncementBanners = `-- name: GetAnnouncementBanners :one
|
||||
SELECT value FROM site_configs WHERE key = 'announcement_banners'
|
||||
`
|
||||
|
||||
func (q *sqlQuerier) GetAnnouncementBanners(ctx context.Context) (string, error) {
|
||||
row := q.db.QueryRowContext(ctx, getAnnouncementBanners)
|
||||
var value string
|
||||
err := row.Scan(&value)
|
||||
return value, err
|
||||
}
|
||||
|
||||
const getAppSecurityKey = `-- name: GetAppSecurityKey :one
|
||||
SELECT value FROM site_configs WHERE key = 'app_signing_key'
|
||||
`
|
||||
@@ -5823,17 +5834,6 @@ func (q *sqlQuerier) GetLogoURL(ctx context.Context) (string, error) {
|
||||
return value, err
|
||||
}
|
||||
|
||||
const getNotificationBanners = `-- name: GetNotificationBanners :one
|
||||
SELECT value FROM site_configs WHERE key = 'notification_banners'
|
||||
`
|
||||
|
||||
func (q *sqlQuerier) GetNotificationBanners(ctx context.Context) (string, error) {
|
||||
row := q.db.QueryRowContext(ctx, getNotificationBanners)
|
||||
var value string
|
||||
err := row.Scan(&value)
|
||||
return value, err
|
||||
}
|
||||
|
||||
const getOAuthSigningKey = `-- name: GetOAuthSigningKey :one
|
||||
SELECT value FROM site_configs WHERE key = 'oauth_signing_key'
|
||||
`
|
||||
@@ -5863,6 +5863,16 @@ func (q *sqlQuerier) InsertDeploymentID(ctx context.Context, value string) error
|
||||
return err
|
||||
}
|
||||
|
||||
const upsertAnnouncementBanners = `-- name: UpsertAnnouncementBanners :exec
|
||||
INSERT INTO site_configs (key, value) VALUES ('announcement_banners', $1)
|
||||
ON CONFLICT (key) DO UPDATE SET value = $1 WHERE site_configs.key = 'announcement_banners'
|
||||
`
|
||||
|
||||
func (q *sqlQuerier) UpsertAnnouncementBanners(ctx context.Context, value string) error {
|
||||
_, err := q.db.ExecContext(ctx, upsertAnnouncementBanners, value)
|
||||
return err
|
||||
}
|
||||
|
||||
const upsertAppSecurityKey = `-- name: UpsertAppSecurityKey :exec
|
||||
INSERT INTO site_configs (key, value) VALUES ('app_signing_key', $1)
|
||||
ON CONFLICT (key) DO UPDATE set value = $1 WHERE site_configs.key = 'app_signing_key'
|
||||
@@ -5936,16 +5946,6 @@ func (q *sqlQuerier) UpsertLogoURL(ctx context.Context, value string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
const upsertNotificationBanners = `-- name: UpsertNotificationBanners :exec
|
||||
INSERT INTO site_configs (key, value) VALUES ('notification_banners', $1)
|
||||
ON CONFLICT (key) DO UPDATE SET value = $1 WHERE site_configs.key = 'notification_banners'
|
||||
`
|
||||
|
||||
func (q *sqlQuerier) UpsertNotificationBanners(ctx context.Context, value string) error {
|
||||
_, err := q.db.ExecContext(ctx, upsertNotificationBanners, value)
|
||||
return err
|
||||
}
|
||||
|
||||
const upsertOAuthSigningKey = `-- name: UpsertOAuthSigningKey :exec
|
||||
INSERT INTO site_configs (key, value) VALUES ('oauth_signing_key', $1)
|
||||
ON CONFLICT (key) DO UPDATE set value = $1 WHERE site_configs.key = 'oauth_signing_key'
|
||||
|
||||
@@ -36,12 +36,12 @@ ON CONFLICT (key) DO UPDATE SET value = $1 WHERE site_configs.key = 'last_update
|
||||
-- name: GetLastUpdateCheck :one
|
||||
SELECT value FROM site_configs WHERE key = 'last_update_check';
|
||||
|
||||
-- name: UpsertNotificationBanners :exec
|
||||
INSERT INTO site_configs (key, value) VALUES ('notification_banners', $1)
|
||||
ON CONFLICT (key) DO UPDATE SET value = $1 WHERE site_configs.key = 'notification_banners';
|
||||
-- name: UpsertAnnouncementBanners :exec
|
||||
INSERT INTO site_configs (key, value) VALUES ('announcement_banners', $1)
|
||||
ON CONFLICT (key) DO UPDATE SET value = $1 WHERE site_configs.key = 'announcement_banners';
|
||||
|
||||
-- name: GetNotificationBanners :one
|
||||
SELECT value FROM site_configs WHERE key = 'notification_banners';
|
||||
-- name: GetAnnouncementBanners :one
|
||||
SELECT value FROM site_configs WHERE key = 'announcement_banners';
|
||||
|
||||
-- name: UpsertLogoURL :exec
|
||||
INSERT INTO site_configs (key, value) VALUES ('logo_url', $1)
|
||||
|
||||
@@ -2105,18 +2105,18 @@ func (c *Client) DeploymentStats(ctx context.Context) (DeploymentStats, error) {
|
||||
type AppearanceConfig struct {
|
||||
ApplicationName string `json:"application_name"`
|
||||
LogoURL string `json:"logo_url"`
|
||||
// Deprecated: ServiceBanner has been replaced by NotificationBanners.
|
||||
// Deprecated: ServiceBanner has been replaced by AnnouncementBanners.
|
||||
ServiceBanner BannerConfig `json:"service_banner"`
|
||||
NotificationBanners []BannerConfig `json:"notification_banners"`
|
||||
AnnouncementBanners []BannerConfig `json:"announcement_banners"`
|
||||
SupportLinks []LinkConfig `json:"support_links,omitempty"`
|
||||
}
|
||||
|
||||
type UpdateAppearanceConfig struct {
|
||||
ApplicationName string `json:"application_name"`
|
||||
LogoURL string `json:"logo_url"`
|
||||
// Deprecated: ServiceBanner has been replaced by NotificationBanners.
|
||||
// Deprecated: ServiceBanner has been replaced by AnnouncementBanners.
|
||||
ServiceBanner BannerConfig `json:"service_banner"`
|
||||
NotificationBanners []BannerConfig `json:"notification_banners"`
|
||||
AnnouncementBanners []BannerConfig `json:"announcement_banners"`
|
||||
}
|
||||
|
||||
// Deprecated: ServiceBannerConfig has been renamed to BannerConfig.
|
||||
|
||||
Generated
+9
-9
@@ -19,15 +19,15 @@ curl -X GET http://coder-server:8080/api/v2/appearance \
|
||||
|
||||
```json
|
||||
{
|
||||
"application_name": "string",
|
||||
"logo_url": "string",
|
||||
"notification_banners": [
|
||||
"announcement_banners": [
|
||||
{
|
||||
"background_color": "string",
|
||||
"enabled": true,
|
||||
"message": "string"
|
||||
}
|
||||
],
|
||||
"application_name": "string",
|
||||
"logo_url": "string",
|
||||
"service_banner": {
|
||||
"background_color": "string",
|
||||
"enabled": true,
|
||||
@@ -69,15 +69,15 @@ curl -X PUT http://coder-server:8080/api/v2/appearance \
|
||||
|
||||
```json
|
||||
{
|
||||
"application_name": "string",
|
||||
"logo_url": "string",
|
||||
"notification_banners": [
|
||||
"announcement_banners": [
|
||||
{
|
||||
"background_color": "string",
|
||||
"enabled": true,
|
||||
"message": "string"
|
||||
}
|
||||
],
|
||||
"application_name": "string",
|
||||
"logo_url": "string",
|
||||
"service_banner": {
|
||||
"background_color": "string",
|
||||
"enabled": true,
|
||||
@@ -98,15 +98,15 @@ curl -X PUT http://coder-server:8080/api/v2/appearance \
|
||||
|
||||
```json
|
||||
{
|
||||
"application_name": "string",
|
||||
"logo_url": "string",
|
||||
"notification_banners": [
|
||||
"announcement_banners": [
|
||||
{
|
||||
"background_color": "string",
|
||||
"enabled": true,
|
||||
"message": "string"
|
||||
}
|
||||
],
|
||||
"application_name": "string",
|
||||
"logo_url": "string",
|
||||
"service_banner": {
|
||||
"background_color": "string",
|
||||
"enabled": true,
|
||||
|
||||
Generated
+10
-10
@@ -749,15 +749,15 @@
|
||||
|
||||
```json
|
||||
{
|
||||
"application_name": "string",
|
||||
"logo_url": "string",
|
||||
"notification_banners": [
|
||||
"announcement_banners": [
|
||||
{
|
||||
"background_color": "string",
|
||||
"enabled": true,
|
||||
"message": "string"
|
||||
}
|
||||
],
|
||||
"application_name": "string",
|
||||
"logo_url": "string",
|
||||
"service_banner": {
|
||||
"background_color": "string",
|
||||
"enabled": true,
|
||||
@@ -777,10 +777,10 @@
|
||||
|
||||
| Name | Type | Required | Restrictions | Description |
|
||||
| ---------------------- | ------------------------------------------------------- | -------- | ------------ | ------------------------------------------------------------------- |
|
||||
| `announcement_banners` | array of [codersdk.BannerConfig](#codersdkbannerconfig) | false | | |
|
||||
| `application_name` | string | false | | |
|
||||
| `logo_url` | string | false | | |
|
||||
| `notification_banners` | array of [codersdk.BannerConfig](#codersdkbannerconfig) | false | | |
|
||||
| `service_banner` | [codersdk.BannerConfig](#codersdkbannerconfig) | false | | Deprecated: ServiceBanner has been replaced by NotificationBanners. |
|
||||
| `service_banner` | [codersdk.BannerConfig](#codersdkbannerconfig) | false | | Deprecated: ServiceBanner has been replaced by AnnouncementBanners. |
|
||||
| `support_links` | array of [codersdk.LinkConfig](#codersdklinkconfig) | false | | |
|
||||
|
||||
## codersdk.ArchiveTemplateVersionsRequest
|
||||
@@ -5301,15 +5301,15 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o
|
||||
|
||||
```json
|
||||
{
|
||||
"application_name": "string",
|
||||
"logo_url": "string",
|
||||
"notification_banners": [
|
||||
"announcement_banners": [
|
||||
{
|
||||
"background_color": "string",
|
||||
"enabled": true,
|
||||
"message": "string"
|
||||
}
|
||||
],
|
||||
"application_name": "string",
|
||||
"logo_url": "string",
|
||||
"service_banner": {
|
||||
"background_color": "string",
|
||||
"enabled": true,
|
||||
@@ -5322,10 +5322,10 @@ CreateWorkspaceRequest provides options for creating a new workspace. Only one o
|
||||
|
||||
| Name | Type | Required | Restrictions | Description |
|
||||
| ---------------------- | ------------------------------------------------------- | -------- | ------------ | ------------------------------------------------------------------- |
|
||||
| `announcement_banners` | array of [codersdk.BannerConfig](#codersdkbannerconfig) | false | | |
|
||||
| `application_name` | string | false | | |
|
||||
| `logo_url` | string | false | | |
|
||||
| `notification_banners` | array of [codersdk.BannerConfig](#codersdkbannerconfig) | false | | |
|
||||
| `service_banner` | [codersdk.BannerConfig](#codersdkbannerconfig) | false | | Deprecated: ServiceBanner has been replaced by NotificationBanners. |
|
||||
| `service_banner` | [codersdk.BannerConfig](#codersdkbannerconfig) | false | | Deprecated: ServiceBanner has been replaced by AnnouncementBanners. |
|
||||
|
||||
## codersdk.UpdateCheckResponse
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ func (f *appearanceFetcher) Fetch(ctx context.Context) (codersdk.AppearanceConfi
|
||||
var (
|
||||
applicationName string
|
||||
logoURL string
|
||||
notificationBannersJSON string
|
||||
announcementBannersJSON string
|
||||
)
|
||||
eg.Go(func() (err error) {
|
||||
applicationName, err = f.database.GetApplicationName(ctx)
|
||||
@@ -75,7 +75,7 @@ func (f *appearanceFetcher) Fetch(ctx context.Context) (codersdk.AppearanceConfi
|
||||
return nil
|
||||
})
|
||||
eg.Go(func() (err error) {
|
||||
notificationBannersJSON, err = f.database.GetNotificationBanners(ctx)
|
||||
announcementBannersJSON, err = f.database.GetAnnouncementBanners(ctx)
|
||||
if err != nil && !errors.Is(err, sql.ErrNoRows) {
|
||||
return xerrors.Errorf("get notification banners: %w", err)
|
||||
}
|
||||
@@ -89,22 +89,22 @@ func (f *appearanceFetcher) Fetch(ctx context.Context) (codersdk.AppearanceConfi
|
||||
cfg := codersdk.AppearanceConfig{
|
||||
ApplicationName: applicationName,
|
||||
LogoURL: logoURL,
|
||||
NotificationBanners: []codersdk.BannerConfig{},
|
||||
AnnouncementBanners: []codersdk.BannerConfig{},
|
||||
SupportLinks: agpl.DefaultSupportLinks,
|
||||
}
|
||||
|
||||
if notificationBannersJSON != "" {
|
||||
err = json.Unmarshal([]byte(notificationBannersJSON), &cfg.NotificationBanners)
|
||||
if announcementBannersJSON != "" {
|
||||
err = json.Unmarshal([]byte(announcementBannersJSON), &cfg.AnnouncementBanners)
|
||||
if err != nil {
|
||||
return codersdk.AppearanceConfig{}, xerrors.Errorf(
|
||||
"unmarshal notification banners json: %w, raw: %s", err, notificationBannersJSON,
|
||||
"unmarshal announcement banners json: %w, raw: %s", err, announcementBannersJSON,
|
||||
)
|
||||
}
|
||||
|
||||
// Redundant, but improves compatibility with slightly mismatched agent versions.
|
||||
// Maybe we can remove this after a grace period? -Kayla, May 6th 2024
|
||||
if len(cfg.NotificationBanners) > 0 {
|
||||
cfg.ServiceBanner = cfg.NotificationBanners[0]
|
||||
if len(cfg.AnnouncementBanners) > 0 {
|
||||
cfg.ServiceBanner = cfg.AnnouncementBanners[0]
|
||||
}
|
||||
}
|
||||
if len(f.supportLinks) > 0 {
|
||||
@@ -149,7 +149,7 @@ func (api *API) putAppearance(rw http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
for _, banner := range appearance.NotificationBanners {
|
||||
for _, banner := range appearance.AnnouncementBanners {
|
||||
if err := validateHexColor(banner.BackgroundColor); err != nil {
|
||||
httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{
|
||||
Message: fmt.Sprintf("Invalid color format: %q", banner.BackgroundColor),
|
||||
@@ -159,22 +159,22 @@ func (api *API) putAppearance(rw http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
}
|
||||
|
||||
if appearance.NotificationBanners == nil {
|
||||
appearance.NotificationBanners = []codersdk.BannerConfig{}
|
||||
if appearance.AnnouncementBanners == nil {
|
||||
appearance.AnnouncementBanners = []codersdk.BannerConfig{}
|
||||
}
|
||||
notificationBannersJSON, err := json.Marshal(appearance.NotificationBanners)
|
||||
announcementBannersJSON, err := json.Marshal(appearance.AnnouncementBanners)
|
||||
if err != nil {
|
||||
httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{
|
||||
Message: "Unable to marshal notification banners",
|
||||
Message: "Unable to marshal announcement banners",
|
||||
Detail: err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
err = api.Database.UpsertNotificationBanners(ctx, string(notificationBannersJSON))
|
||||
err = api.Database.UpsertAnnouncementBanners(ctx, string(announcementBannersJSON))
|
||||
if err != nil {
|
||||
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
|
||||
Message: "Unable to set notification banners",
|
||||
Message: "Unable to set announcement banners",
|
||||
Detail: err.Error(),
|
||||
})
|
||||
return
|
||||
|
||||
@@ -55,7 +55,7 @@ func TestCustomLogoAndCompanyName(t *testing.T) {
|
||||
require.Equal(t, uac.LogoURL, got.LogoURL)
|
||||
}
|
||||
|
||||
func TestNotificationBanners(t *testing.T) {
|
||||
func TestAnnouncementBanners(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
t.Run("User", func(t *testing.T) {
|
||||
@@ -70,7 +70,7 @@ func TestNotificationBanners(t *testing.T) {
|
||||
// Without a license, there should be no banners.
|
||||
sb, err := basicUserClient.Appearance(ctx)
|
||||
require.NoError(t, err)
|
||||
require.Empty(t, sb.NotificationBanners)
|
||||
require.Empty(t, sb.AnnouncementBanners)
|
||||
|
||||
coderdenttest.AddLicense(t, adminClient, coderdenttest.LicenseOptions{
|
||||
Features: license.Features{
|
||||
@@ -81,11 +81,11 @@ func TestNotificationBanners(t *testing.T) {
|
||||
// Default state
|
||||
sb, err = basicUserClient.Appearance(ctx)
|
||||
require.NoError(t, err)
|
||||
require.Empty(t, sb.NotificationBanners)
|
||||
require.Empty(t, sb.AnnouncementBanners)
|
||||
|
||||
// Regular user should be unable to set the banner
|
||||
uac := codersdk.UpdateAppearanceConfig{
|
||||
NotificationBanners: []codersdk.BannerConfig{{Enabled: true}},
|
||||
AnnouncementBanners: []codersdk.BannerConfig{{Enabled: true}},
|
||||
}
|
||||
err = basicUserClient.UpdateAppearance(ctx, uac)
|
||||
require.Error(t, err)
|
||||
@@ -96,7 +96,7 @@ func TestNotificationBanners(t *testing.T) {
|
||||
|
||||
// But an admin can
|
||||
wantBanner := codersdk.UpdateAppearanceConfig{
|
||||
NotificationBanners: []codersdk.BannerConfig{{
|
||||
AnnouncementBanners: []codersdk.BannerConfig{{
|
||||
Enabled: true,
|
||||
Message: "The beep-bop will be boop-beeped on Saturday at 12AM PST.",
|
||||
BackgroundColor: "#00FF00",
|
||||
@@ -106,10 +106,10 @@ func TestNotificationBanners(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
gotBanner, err := adminClient.Appearance(ctx) //nolint:gocritic // we should assert at least once that the owner can get the banner
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, wantBanner.NotificationBanners, gotBanner.NotificationBanners)
|
||||
require.Equal(t, wantBanner.AnnouncementBanners, gotBanner.AnnouncementBanners)
|
||||
|
||||
// But even an admin can't give a bad color
|
||||
wantBanner.NotificationBanners[0].BackgroundColor = "#bad color"
|
||||
wantBanner.AnnouncementBanners[0].BackgroundColor = "#bad color"
|
||||
err = adminClient.UpdateAppearance(ctx, wantBanner)
|
||||
require.Error(t, err)
|
||||
var sdkErr *codersdk.Error
|
||||
@@ -139,7 +139,7 @@ func TestNotificationBanners(t *testing.T) {
|
||||
},
|
||||
})
|
||||
cfg := codersdk.UpdateAppearanceConfig{
|
||||
NotificationBanners: []codersdk.BannerConfig{{
|
||||
AnnouncementBanners: []codersdk.BannerConfig{{
|
||||
Enabled: true,
|
||||
Message: "The beep-bop will be boop-beeped on Saturday at 12AM PST.",
|
||||
BackgroundColor: "#00FF00",
|
||||
@@ -155,35 +155,35 @@ func TestNotificationBanners(t *testing.T) {
|
||||
|
||||
agentClient := agentsdk.New(client.URL)
|
||||
agentClient.SetSessionToken(r.AgentToken)
|
||||
banners := requireGetNotificationBanners(ctx, t, agentClient)
|
||||
require.Equal(t, cfg.NotificationBanners, banners)
|
||||
banners := requireGetAnnouncementBanners(ctx, t, agentClient)
|
||||
require.Equal(t, cfg.AnnouncementBanners, banners)
|
||||
|
||||
// Create an AGPL Coderd against the same database
|
||||
agplClient := coderdtest.New(t, &coderdtest.Options{Database: store, Pubsub: ps})
|
||||
agplAgentClient := agentsdk.New(agplClient.URL)
|
||||
agplAgentClient.SetSessionToken(r.AgentToken)
|
||||
banners = requireGetNotificationBanners(ctx, t, agplAgentClient)
|
||||
banners = requireGetAnnouncementBanners(ctx, t, agplAgentClient)
|
||||
require.Equal(t, []codersdk.BannerConfig{}, banners)
|
||||
|
||||
// No license means no banner.
|
||||
err = client.DeleteLicense(ctx, lic.ID)
|
||||
require.NoError(t, err)
|
||||
banners = requireGetNotificationBanners(ctx, t, agentClient)
|
||||
banners = requireGetAnnouncementBanners(ctx, t, agentClient)
|
||||
require.Equal(t, []codersdk.BannerConfig{}, banners)
|
||||
})
|
||||
}
|
||||
|
||||
func requireGetNotificationBanners(ctx context.Context, t *testing.T, client *agentsdk.Client) []codersdk.BannerConfig {
|
||||
func requireGetAnnouncementBanners(ctx context.Context, t *testing.T, client *agentsdk.Client) []codersdk.BannerConfig {
|
||||
cc, err := client.ConnectRPC(ctx)
|
||||
require.NoError(t, err)
|
||||
defer func() {
|
||||
_ = cc.Close()
|
||||
}()
|
||||
aAPI := proto.NewDRPCAgentClient(cc)
|
||||
bannersProto, err := aAPI.GetNotificationBanners(ctx, &proto.GetNotificationBannersRequest{})
|
||||
bannersProto, err := aAPI.GetAnnouncementBanners(ctx, &proto.GetAnnouncementBannersRequest{})
|
||||
require.NoError(t, err)
|
||||
banners := make([]codersdk.BannerConfig, 0, len(bannersProto.NotificationBanners))
|
||||
for _, bannerProto := range bannersProto.NotificationBanners {
|
||||
banners := make([]codersdk.BannerConfig, 0, len(bannersProto.AnnouncementBanners))
|
||||
for _, bannerProto := range bannersProto.AnnouncementBanners {
|
||||
banners = append(banners, agentsdk.BannerConfigFromProto(bannerProto))
|
||||
}
|
||||
return banners
|
||||
|
||||
+1
-1
@@ -1581,7 +1581,7 @@ class ApiMethods {
|
||||
return {
|
||||
application_name: "",
|
||||
logo_url: "",
|
||||
notification_banners: [],
|
||||
announcement_banners: [],
|
||||
service_banner: {
|
||||
enabled: false,
|
||||
},
|
||||
|
||||
Generated
+2
-2
@@ -49,7 +49,7 @@ export interface AppearanceConfig {
|
||||
readonly application_name: string;
|
||||
readonly logo_url: string;
|
||||
readonly service_banner: BannerConfig;
|
||||
readonly notification_banners: readonly BannerConfig[];
|
||||
readonly announcement_banners: readonly BannerConfig[];
|
||||
readonly support_links?: readonly LinkConfig[];
|
||||
}
|
||||
|
||||
@@ -1309,7 +1309,7 @@ export interface UpdateAppearanceConfig {
|
||||
readonly application_name: string;
|
||||
readonly logo_url: string;
|
||||
readonly service_banner: BannerConfig;
|
||||
readonly notification_banners: readonly BannerConfig[];
|
||||
readonly announcement_banners: readonly BannerConfig[];
|
||||
}
|
||||
|
||||
// From codersdk/updatecheck.go
|
||||
|
||||
+5
-5
@@ -1,13 +1,13 @@
|
||||
import type { Meta, StoryObj } from "@storybook/react";
|
||||
import { NotificationBannerView } from "./NotificationBannerView";
|
||||
import { AnnouncementBannerView } from "./AnnouncementBannerView";
|
||||
|
||||
const meta: Meta<typeof NotificationBannerView> = {
|
||||
title: "modules/dashboard/NotificationBannerView",
|
||||
component: NotificationBannerView,
|
||||
const meta: Meta<typeof AnnouncementBannerView> = {
|
||||
title: "modules/dashboard/AnnouncementBannerView",
|
||||
component: AnnouncementBannerView,
|
||||
};
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof NotificationBannerView>;
|
||||
type Story = StoryObj<typeof AnnouncementBannerView>;
|
||||
|
||||
export const Production: Story = {
|
||||
args: {
|
||||
+2
-2
@@ -3,12 +3,12 @@ import type { FC } from "react";
|
||||
import { InlineMarkdown } from "components/Markdown/Markdown";
|
||||
import { readableForegroundColor } from "utils/colors";
|
||||
|
||||
export interface NotificationBannerViewProps {
|
||||
export interface AnnouncementBannerViewProps {
|
||||
message?: string;
|
||||
backgroundColor?: string;
|
||||
}
|
||||
|
||||
export const NotificationBannerView: FC<NotificationBannerViewProps> = ({
|
||||
export const AnnouncementBannerView: FC<AnnouncementBannerViewProps> = ({
|
||||
message,
|
||||
backgroundColor,
|
||||
}) => {
|
||||
+5
-5
@@ -1,10 +1,10 @@
|
||||
import type { FC } from "react";
|
||||
import { useDashboard } from "modules/dashboard/useDashboard";
|
||||
import { NotificationBannerView } from "./NotificationBannerView";
|
||||
import { AnnouncementBannerView } from "./AnnouncementBannerView";
|
||||
|
||||
export const NotificationBanners: FC = () => {
|
||||
export const AnnouncementBanners: FC = () => {
|
||||
const { appearance, entitlements } = useDashboard();
|
||||
const notificationBanners = appearance.notification_banners;
|
||||
const announcementBanners = appearance.announcement_banners;
|
||||
|
||||
const isEntitled =
|
||||
entitlements.features.appearance.entitlement !== "not_entitled";
|
||||
@@ -14,10 +14,10 @@ export const NotificationBanners: FC = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
{notificationBanners
|
||||
{announcementBanners
|
||||
.filter((banner) => banner.enabled)
|
||||
.map((banner) => (
|
||||
<NotificationBannerView
|
||||
<AnnouncementBannerView
|
||||
key={banner.message}
|
||||
message={banner.message}
|
||||
backgroundColor={banner.background_color}
|
||||
@@ -6,8 +6,8 @@ import { type FC, type HTMLAttributes, Suspense } from "react";
|
||||
import { Outlet } from "react-router-dom";
|
||||
import { Loader } from "components/Loader/Loader";
|
||||
import { useAuthenticated } from "contexts/auth/RequireAuth";
|
||||
import { AnnouncementBanners } from "modules/dashboard/AnnouncementBanners/AnnouncementBanners";
|
||||
import { LicenseBanner } from "modules/dashboard/LicenseBanner/LicenseBanner";
|
||||
import { NotificationBanners } from "modules/dashboard/NotificationBanners/NotificationBanners";
|
||||
import { dashboardContentBottomPadding } from "theme/constants";
|
||||
import { docs } from "utils/docs";
|
||||
import { DeploymentBanner } from "./DeploymentBanner/DeploymentBanner";
|
||||
@@ -22,7 +22,7 @@ export const DashboardLayout: FC = () => {
|
||||
return (
|
||||
<>
|
||||
{canViewDeployment && <LicenseBanner />}
|
||||
<NotificationBanners />
|
||||
<AnnouncementBanners />
|
||||
|
||||
<div
|
||||
css={{
|
||||
|
||||
+6
-6
@@ -1,10 +1,10 @@
|
||||
import { action } from "@storybook/addon-actions";
|
||||
import type { Meta, StoryObj } from "@storybook/react";
|
||||
import { NotificationBannerDialog } from "./NotificationBannerDialog";
|
||||
import { AnnouncementBannerDialog } from "./AnnouncementBannerDialog";
|
||||
|
||||
const meta: Meta<typeof NotificationBannerDialog> = {
|
||||
title: "pages/DeploySettingsPage/NotificationBannerDialog",
|
||||
component: NotificationBannerDialog,
|
||||
const meta: Meta<typeof AnnouncementBannerDialog> = {
|
||||
title: "pages/DeploySettingsPage/AnnouncementBannerDialog",
|
||||
component: AnnouncementBannerDialog,
|
||||
args: {
|
||||
banner: {
|
||||
enabled: true,
|
||||
@@ -17,8 +17,8 @@ const meta: Meta<typeof NotificationBannerDialog> = {
|
||||
};
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof NotificationBannerDialog>;
|
||||
type Story = StoryObj<typeof AnnouncementBannerDialog>;
|
||||
|
||||
const Example: Story = {};
|
||||
|
||||
export { Example as NotificationBannerDialog };
|
||||
export { Example as AnnouncementBannerDialog };
|
||||
+5
-5
@@ -7,16 +7,16 @@ import { BlockPicker } from "react-color";
|
||||
import type { BannerConfig } from "api/typesGenerated";
|
||||
import { Dialog, DialogActionButtons } from "components/Dialogs/Dialog";
|
||||
import { Stack } from "components/Stack/Stack";
|
||||
import { NotificationBannerView } from "modules/dashboard/NotificationBanners/NotificationBannerView";
|
||||
import { AnnouncementBannerView } from "modules/dashboard/AnnouncementBanners/AnnouncementBannerView";
|
||||
import { getFormHelpers } from "utils/formUtils";
|
||||
|
||||
interface NotificationBannerDialogProps {
|
||||
interface AnnouncementBannerDialogProps {
|
||||
banner: BannerConfig;
|
||||
onCancel: () => void;
|
||||
onUpdate: (banner: Partial<BannerConfig>) => Promise<void>;
|
||||
}
|
||||
|
||||
export const NotificationBannerDialog: FC<NotificationBannerDialogProps> = ({
|
||||
export const AnnouncementBannerDialog: FC<AnnouncementBannerDialogProps> = ({
|
||||
banner,
|
||||
onCancel,
|
||||
onUpdate,
|
||||
@@ -39,14 +39,14 @@ export const NotificationBannerDialog: FC<NotificationBannerDialogProps> = ({
|
||||
<Dialog css={styles.dialogWrapper} open onClose={onCancel}>
|
||||
{/* Banner preview */}
|
||||
<div css={{ position: "fixed", top: 0, left: 0, right: 0 }}>
|
||||
<NotificationBannerView
|
||||
<AnnouncementBannerView
|
||||
message={bannerForm.values.message}
|
||||
backgroundColor={bannerForm.values.background_color}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div css={styles.dialogContent}>
|
||||
<h3 css={styles.dialogTitle}>Notification banner</h3>
|
||||
<h3 css={styles.dialogTitle}>Announcement banner</h3>
|
||||
<Stack>
|
||||
<div>
|
||||
<h4 css={styles.settingName}>Message</h4>
|
||||
+2
-2
@@ -12,7 +12,7 @@ import {
|
||||
ThreeDotsButton,
|
||||
} from "components/MoreMenu/MoreMenu";
|
||||
|
||||
interface NotificationBannerItemProps {
|
||||
interface AnnouncementBannerItemProps {
|
||||
enabled: boolean;
|
||||
backgroundColor?: string;
|
||||
message?: string;
|
||||
@@ -21,7 +21,7 @@ interface NotificationBannerItemProps {
|
||||
onDelete: () => void;
|
||||
}
|
||||
|
||||
export const NotificationBannerItem: FC<NotificationBannerItemProps> = ({
|
||||
export const AnnouncementBannerItem: FC<AnnouncementBannerItemProps> = ({
|
||||
enabled,
|
||||
backgroundColor = "#004852",
|
||||
message,
|
||||
+12
-12
@@ -13,20 +13,20 @@ import type { BannerConfig } from "api/typesGenerated";
|
||||
import { ConfirmDialog } from "components/Dialogs/ConfirmDialog/ConfirmDialog";
|
||||
import { EmptyState } from "components/EmptyState/EmptyState";
|
||||
import { Stack } from "components/Stack/Stack";
|
||||
import { NotificationBannerDialog } from "./NotificationBannerDialog";
|
||||
import { NotificationBannerItem } from "./NotificationBannerItem";
|
||||
import { AnnouncementBannerDialog } from "./AnnouncementBannerDialog";
|
||||
import { AnnouncementBannerItem } from "./AnnouncementBannerItem";
|
||||
|
||||
interface NotificationBannerSettingsProps {
|
||||
interface AnnouncementBannersettingsProps {
|
||||
isEntitled: boolean;
|
||||
notificationBanners: readonly BannerConfig[];
|
||||
announcementBanners: readonly BannerConfig[];
|
||||
onSubmit: (banners: readonly BannerConfig[]) => Promise<void>;
|
||||
}
|
||||
|
||||
export const NotificationBannerSettings: FC<
|
||||
NotificationBannerSettingsProps
|
||||
> = ({ isEntitled, notificationBanners, onSubmit }) => {
|
||||
export const AnnouncementBannerSettings: FC<
|
||||
AnnouncementBannersettingsProps
|
||||
> = ({ isEntitled, announcementBanners, onSubmit }) => {
|
||||
const theme = useTheme();
|
||||
const [banners, setBanners] = useState(notificationBanners);
|
||||
const [banners, setBanners] = useState(announcementBanners);
|
||||
const [editingBannerId, setEditingBannerId] = useState<number | null>(null);
|
||||
const [deletingBannerId, setDeletingBannerId] = useState<number | null>(null);
|
||||
|
||||
@@ -84,7 +84,7 @@ export const NotificationBannerSettings: FC<
|
||||
fontWeight: 600,
|
||||
}}
|
||||
>
|
||||
Notification Banners
|
||||
Announcement Banners
|
||||
</h3>
|
||||
<Button
|
||||
disabled={!isEntitled}
|
||||
@@ -125,12 +125,12 @@ export const NotificationBannerSettings: FC<
|
||||
<TableCell colSpan={999}>
|
||||
<EmptyState
|
||||
css={{ minHeight: 160 }}
|
||||
message="No notification banners"
|
||||
message="No announcement banners"
|
||||
/>
|
||||
</TableCell>
|
||||
) : (
|
||||
banners.map((banner, i) => (
|
||||
<NotificationBannerItem
|
||||
<AnnouncementBannerItem
|
||||
key={banner.message}
|
||||
enabled={banner.enabled && Boolean(banner.message)}
|
||||
backgroundColor={banner.background_color}
|
||||
@@ -172,7 +172,7 @@ export const NotificationBannerSettings: FC<
|
||||
</div>
|
||||
|
||||
{editingBanner && (
|
||||
<NotificationBannerDialog
|
||||
<AnnouncementBannerDialog
|
||||
banner={editingBanner}
|
||||
onCancel={() => setEditingBannerId(null)}
|
||||
onUpdate={async (banner) => {
|
||||
+1
-1
@@ -13,7 +13,7 @@ const meta: Meta<typeof AppearanceSettingsPageView> = {
|
||||
message: "",
|
||||
background_color: "#00ff00",
|
||||
},
|
||||
notification_banners: [
|
||||
announcement_banners: [
|
||||
{
|
||||
enabled: true,
|
||||
message: "The beep-bop will be boop-beeped on Saturday at 12AM PST.",
|
||||
|
||||
+5
-5
@@ -19,7 +19,7 @@ import {
|
||||
import { getFormHelpers } from "utils/formUtils";
|
||||
import { Fieldset } from "../Fieldset";
|
||||
import { Header } from "../Header";
|
||||
import { NotificationBannerSettings } from "./NotificationBannerSettings";
|
||||
import { AnnouncementBannerSettings } from "./AnnouncementBannerSettings";
|
||||
|
||||
export type AppearanceSettingsPageViewProps = {
|
||||
appearance: UpdateAppearanceConfig;
|
||||
@@ -144,11 +144,11 @@ export const AppearanceSettingsPageView: FC<
|
||||
/>
|
||||
</Fieldset>
|
||||
|
||||
<NotificationBannerSettings
|
||||
<AnnouncementBannerSettings
|
||||
isEntitled={isEntitled}
|
||||
notificationBanners={appearance.notification_banners || []}
|
||||
onSubmit={(notificationBanners) =>
|
||||
onSaveAppearance({ notification_banners: notificationBanners })
|
||||
announcementBanners={appearance.announcement_banners || []}
|
||||
onSubmit={(announcementBanners) =>
|
||||
onSaveAppearance({ announcement_banners: announcementBanners })
|
||||
}
|
||||
/>
|
||||
</>
|
||||
|
||||
@@ -11,8 +11,8 @@ import { ErrorAlert } from "components/Alert/ErrorAlert";
|
||||
import { Loader } from "components/Loader/Loader";
|
||||
import { Margins } from "components/Margins/Margins";
|
||||
import { useEffectEvent } from "hooks/hookPolyfills";
|
||||
import { AnnouncementBanners } from "modules/dashboard/AnnouncementBanners/AnnouncementBanners";
|
||||
import { Navbar } from "modules/dashboard/Navbar/Navbar";
|
||||
import { NotificationBanners } from "modules/dashboard/NotificationBanners/NotificationBanners";
|
||||
import { useDashboard } from "modules/dashboard/useDashboard";
|
||||
import { workspaceChecks, type WorkspacePermissions } from "./permissions";
|
||||
import { WorkspaceReadyPage } from "./WorkspaceReadyPage";
|
||||
@@ -106,7 +106,7 @@ export const WorkspacePage: FC = () => {
|
||||
|
||||
return (
|
||||
<>
|
||||
<NotificationBanners />
|
||||
<AnnouncementBanners />
|
||||
<div css={{ height: "100%", display: "flex", flexDirection: "column" }}>
|
||||
<Navbar />
|
||||
{pageError ? (
|
||||
|
||||
@@ -2372,7 +2372,7 @@ export const MockAppearanceConfig: TypesGen.AppearanceConfig = {
|
||||
service_banner: {
|
||||
enabled: false,
|
||||
},
|
||||
notification_banners: [],
|
||||
announcement_banners: [],
|
||||
};
|
||||
|
||||
export const MockWorkspaceBuildParameter1: TypesGen.WorkspaceBuildParameter = {
|
||||
|
||||
Reference in New Issue
Block a user