diff --git a/api/gen/proto/go/userpreferences/v1/unified_resource_preferences.pb.go b/api/gen/proto/go/userpreferences/v1/unified_resource_preferences.pb.go index 7e531f94eccc3..ed56bc371aeda 100644 --- a/api/gen/proto/go/userpreferences/v1/unified_resource_preferences.pb.go +++ b/api/gen/proto/go/userpreferences/v1/unified_resource_preferences.pb.go @@ -138,6 +138,58 @@ func (ViewMode) EnumDescriptor() ([]byte, []int) { return file_teleport_userpreferences_v1_unified_resource_preferences_proto_rawDescGZIP(), []int{1} } +// * LabelsViewMode is whether the labels for resources should all be collapsed or expanded. This only applies to the list view. +type LabelsViewMode int32 + +const ( + LabelsViewMode_LABELS_VIEW_MODE_UNSPECIFIED LabelsViewMode = 0 + // EXPANDED is the expanded state which shows all labels for every resource. + LabelsViewMode_LABELS_VIEW_MODE_EXPANDED LabelsViewMode = 1 + // COLLAPSED is the collapsed state which hides all labels for every resource. + LabelsViewMode_LABELS_VIEW_MODE_COLLAPSED LabelsViewMode = 2 +) + +// Enum value maps for LabelsViewMode. +var ( + LabelsViewMode_name = map[int32]string{ + 0: "LABELS_VIEW_MODE_UNSPECIFIED", + 1: "LABELS_VIEW_MODE_EXPANDED", + 2: "LABELS_VIEW_MODE_COLLAPSED", + } + LabelsViewMode_value = map[string]int32{ + "LABELS_VIEW_MODE_UNSPECIFIED": 0, + "LABELS_VIEW_MODE_EXPANDED": 1, + "LABELS_VIEW_MODE_COLLAPSED": 2, + } +) + +func (x LabelsViewMode) Enum() *LabelsViewMode { + p := new(LabelsViewMode) + *p = x + return p +} + +func (x LabelsViewMode) String() string { + return protoimpl.X.EnumStringOf(x.Descriptor(), protoreflect.EnumNumber(x)) +} + +func (LabelsViewMode) Descriptor() protoreflect.EnumDescriptor { + return file_teleport_userpreferences_v1_unified_resource_preferences_proto_enumTypes[2].Descriptor() +} + +func (LabelsViewMode) Type() protoreflect.EnumType { + return &file_teleport_userpreferences_v1_unified_resource_preferences_proto_enumTypes[2] +} + +func (x LabelsViewMode) Number() protoreflect.EnumNumber { + return protoreflect.EnumNumber(x) +} + +// Deprecated: Use LabelsViewMode.Descriptor instead. +func (LabelsViewMode) EnumDescriptor() ([]byte, []int) { + return file_teleport_userpreferences_v1_unified_resource_preferences_proto_rawDescGZIP(), []int{2} +} + // UnifiedResourcePreferences are preferences used in the Unified Resource web UI type UnifiedResourcePreferences struct { state protoimpl.MessageState @@ -148,6 +200,8 @@ type UnifiedResourcePreferences struct { DefaultTab DefaultTab `protobuf:"varint,1,opt,name=default_tab,json=defaultTab,proto3,enum=teleport.userpreferences.v1.DefaultTab" json:"default_tab,omitempty"` // view_mode is the view mode selected in the unified resource Web UI ViewMode ViewMode `protobuf:"varint,2,opt,name=view_mode,json=viewMode,proto3,enum=teleport.userpreferences.v1.ViewMode" json:"view_mode,omitempty"` + // labels_view_mode is whether the labels for resources should all be collapsed or expanded in the unified resource Web UI list view. + LabelsViewMode LabelsViewMode `protobuf:"varint,3,opt,name=labels_view_mode,json=labelsViewMode,proto3,enum=teleport.userpreferences.v1.LabelsViewMode" json:"labels_view_mode,omitempty"` } func (x *UnifiedResourcePreferences) Reset() { @@ -196,6 +250,13 @@ func (x *UnifiedResourcePreferences) GetViewMode() ViewMode { return ViewMode_VIEW_MODE_UNSPECIFIED } +func (x *UnifiedResourcePreferences) GetLabelsViewMode() LabelsViewMode { + if x != nil { + return x.LabelsViewMode + } + return LabelsViewMode_LABELS_VIEW_MODE_UNSPECIFIED +} + var File_teleport_userpreferences_v1_unified_resource_preferences_proto protoreflect.FileDescriptor var file_teleport_userpreferences_v1_unified_resource_preferences_proto_rawDesc = []byte{ @@ -204,7 +265,7 @@ var file_teleport_userpreferences_v1_unified_resource_preferences_proto_rawDesc 0x69, 0x66, 0x69, 0x65, 0x64, 0x5f, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x1b, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x70, - 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x22, 0xaa, 0x01, + 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x22, 0x81, 0x02, 0x0a, 0x1a, 0x55, 0x6e, 0x69, 0x66, 0x69, 0x65, 0x64, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x50, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x12, 0x48, 0x0a, 0x0b, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x74, 0x61, 0x62, 0x18, 0x01, 0x20, 0x01, 0x28, @@ -215,24 +276,36 @@ var file_teleport_userpreferences_v1_unified_resource_preferences_proto_rawDesc 0x6f, 0x64, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x25, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, 0x75, 0x73, 0x65, 0x72, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x56, 0x69, 0x65, 0x77, 0x4d, 0x6f, 0x64, 0x65, - 0x52, 0x08, 0x76, 0x69, 0x65, 0x77, 0x4d, 0x6f, 0x64, 0x65, 0x2a, 0x56, 0x0a, 0x0a, 0x44, 0x65, - 0x66, 0x61, 0x75, 0x6c, 0x74, 0x54, 0x61, 0x62, 0x12, 0x1b, 0x0a, 0x17, 0x44, 0x45, 0x46, 0x41, - 0x55, 0x4c, 0x54, 0x5f, 0x54, 0x41, 0x42, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, - 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f, 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, - 0x5f, 0x54, 0x41, 0x42, 0x5f, 0x41, 0x4c, 0x4c, 0x10, 0x01, 0x12, 0x16, 0x0a, 0x12, 0x44, 0x45, - 0x46, 0x41, 0x55, 0x4c, 0x54, 0x5f, 0x54, 0x41, 0x42, 0x5f, 0x50, 0x49, 0x4e, 0x4e, 0x45, 0x44, - 0x10, 0x02, 0x2a, 0x4d, 0x0a, 0x08, 0x56, 0x69, 0x65, 0x77, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x19, - 0x0a, 0x15, 0x56, 0x49, 0x45, 0x57, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, - 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x12, 0x0a, 0x0e, 0x56, 0x49, 0x45, - 0x57, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x43, 0x41, 0x52, 0x44, 0x10, 0x01, 0x12, 0x12, 0x0a, - 0x0e, 0x56, 0x49, 0x45, 0x57, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x4c, 0x49, 0x53, 0x54, 0x10, - 0x02, 0x42, 0x59, 0x5a, 0x57, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, - 0x67, 0x72, 0x61, 0x76, 0x69, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x65, - 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, 0x6f, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x70, 0x72, 0x65, 0x66, - 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x2f, 0x76, 0x31, 0x3b, 0x75, 0x73, 0x65, 0x72, 0x70, - 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x33, + 0x52, 0x08, 0x76, 0x69, 0x65, 0x77, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x55, 0x0a, 0x10, 0x6c, 0x61, + 0x62, 0x65, 0x6c, 0x73, 0x5f, 0x76, 0x69, 0x65, 0x77, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0e, 0x32, 0x2b, 0x2e, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x2e, + 0x75, 0x73, 0x65, 0x72, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, 0x73, 0x2e, + 0x76, 0x31, 0x2e, 0x4c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x56, 0x69, 0x65, 0x77, 0x4d, 0x6f, 0x64, + 0x65, 0x52, 0x0e, 0x6c, 0x61, 0x62, 0x65, 0x6c, 0x73, 0x56, 0x69, 0x65, 0x77, 0x4d, 0x6f, 0x64, + 0x65, 0x2a, 0x56, 0x0a, 0x0a, 0x44, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x54, 0x61, 0x62, 0x12, + 0x1b, 0x0a, 0x17, 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x5f, 0x54, 0x41, 0x42, 0x5f, 0x55, + 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x13, 0x0a, 0x0f, + 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x5f, 0x54, 0x41, 0x42, 0x5f, 0x41, 0x4c, 0x4c, 0x10, + 0x01, 0x12, 0x16, 0x0a, 0x12, 0x44, 0x45, 0x46, 0x41, 0x55, 0x4c, 0x54, 0x5f, 0x54, 0x41, 0x42, + 0x5f, 0x50, 0x49, 0x4e, 0x4e, 0x45, 0x44, 0x10, 0x02, 0x2a, 0x4d, 0x0a, 0x08, 0x56, 0x69, 0x65, + 0x77, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x19, 0x0a, 0x15, 0x56, 0x49, 0x45, 0x57, 0x5f, 0x4d, 0x4f, + 0x44, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, + 0x12, 0x12, 0x0a, 0x0e, 0x56, 0x49, 0x45, 0x57, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x43, 0x41, + 0x52, 0x44, 0x10, 0x01, 0x12, 0x12, 0x0a, 0x0e, 0x56, 0x49, 0x45, 0x57, 0x5f, 0x4d, 0x4f, 0x44, + 0x45, 0x5f, 0x4c, 0x49, 0x53, 0x54, 0x10, 0x02, 0x2a, 0x71, 0x0a, 0x0e, 0x4c, 0x61, 0x62, 0x65, + 0x6c, 0x73, 0x56, 0x69, 0x65, 0x77, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x20, 0x0a, 0x1c, 0x4c, 0x41, + 0x42, 0x45, 0x4c, 0x53, 0x5f, 0x56, 0x49, 0x45, 0x57, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, 0x55, + 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x1d, 0x0a, 0x19, + 0x4c, 0x41, 0x42, 0x45, 0x4c, 0x53, 0x5f, 0x56, 0x49, 0x45, 0x57, 0x5f, 0x4d, 0x4f, 0x44, 0x45, + 0x5f, 0x45, 0x58, 0x50, 0x41, 0x4e, 0x44, 0x45, 0x44, 0x10, 0x01, 0x12, 0x1e, 0x0a, 0x1a, 0x4c, + 0x41, 0x42, 0x45, 0x4c, 0x53, 0x5f, 0x56, 0x49, 0x45, 0x57, 0x5f, 0x4d, 0x4f, 0x44, 0x45, 0x5f, + 0x43, 0x4f, 0x4c, 0x4c, 0x41, 0x50, 0x53, 0x45, 0x44, 0x10, 0x02, 0x42, 0x59, 0x5a, 0x57, 0x67, + 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x67, 0x72, 0x61, 0x76, 0x69, 0x74, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x61, 0x6c, 0x2f, 0x74, 0x65, 0x6c, 0x65, 0x70, 0x6f, 0x72, 0x74, + 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, + 0x6f, 0x2f, 0x75, 0x73, 0x65, 0x72, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, 0x6e, 0x63, 0x65, + 0x73, 0x2f, 0x76, 0x31, 0x3b, 0x75, 0x73, 0x65, 0x72, 0x70, 0x72, 0x65, 0x66, 0x65, 0x72, 0x65, + 0x6e, 0x63, 0x65, 0x73, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -247,21 +320,23 @@ func file_teleport_userpreferences_v1_unified_resource_preferences_proto_rawDesc return file_teleport_userpreferences_v1_unified_resource_preferences_proto_rawDescData } -var file_teleport_userpreferences_v1_unified_resource_preferences_proto_enumTypes = make([]protoimpl.EnumInfo, 2) +var file_teleport_userpreferences_v1_unified_resource_preferences_proto_enumTypes = make([]protoimpl.EnumInfo, 3) var file_teleport_userpreferences_v1_unified_resource_preferences_proto_msgTypes = make([]protoimpl.MessageInfo, 1) var file_teleport_userpreferences_v1_unified_resource_preferences_proto_goTypes = []interface{}{ (DefaultTab)(0), // 0: teleport.userpreferences.v1.DefaultTab (ViewMode)(0), // 1: teleport.userpreferences.v1.ViewMode - (*UnifiedResourcePreferences)(nil), // 2: teleport.userpreferences.v1.UnifiedResourcePreferences + (LabelsViewMode)(0), // 2: teleport.userpreferences.v1.LabelsViewMode + (*UnifiedResourcePreferences)(nil), // 3: teleport.userpreferences.v1.UnifiedResourcePreferences } var file_teleport_userpreferences_v1_unified_resource_preferences_proto_depIdxs = []int32{ 0, // 0: teleport.userpreferences.v1.UnifiedResourcePreferences.default_tab:type_name -> teleport.userpreferences.v1.DefaultTab 1, // 1: teleport.userpreferences.v1.UnifiedResourcePreferences.view_mode:type_name -> teleport.userpreferences.v1.ViewMode - 2, // [2:2] is the sub-list for method output_type - 2, // [2:2] is the sub-list for method input_type - 2, // [2:2] is the sub-list for extension type_name - 2, // [2:2] is the sub-list for extension extendee - 0, // [0:2] is the sub-list for field type_name + 2, // 2: teleport.userpreferences.v1.UnifiedResourcePreferences.labels_view_mode:type_name -> teleport.userpreferences.v1.LabelsViewMode + 3, // [3:3] is the sub-list for method output_type + 3, // [3:3] is the sub-list for method input_type + 3, // [3:3] is the sub-list for extension type_name + 3, // [3:3] is the sub-list for extension extendee + 0, // [0:3] is the sub-list for field type_name } func init() { file_teleport_userpreferences_v1_unified_resource_preferences_proto_init() } @@ -288,7 +363,7 @@ func file_teleport_userpreferences_v1_unified_resource_preferences_proto_init() File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_teleport_userpreferences_v1_unified_resource_preferences_proto_rawDesc, - NumEnums: 2, + NumEnums: 3, NumMessages: 1, NumExtensions: 0, NumServices: 0, diff --git a/api/proto/teleport/userpreferences/v1/unified_resource_preferences.proto b/api/proto/teleport/userpreferences/v1/unified_resource_preferences.proto index ce9da16775c1c..3ea3e150f8c8c 100644 --- a/api/proto/teleport/userpreferences/v1/unified_resource_preferences.proto +++ b/api/proto/teleport/userpreferences/v1/unified_resource_preferences.proto @@ -24,6 +24,8 @@ message UnifiedResourcePreferences { DefaultTab default_tab = 1; // view_mode is the view mode selected in the unified resource Web UI ViewMode view_mode = 2; + // labels_view_mode is whether the labels for resources should all be collapsed or expanded in the unified resource Web UI list view. + LabelsViewMode labels_view_mode = 3; } // DefaultTab is the default tab selected in the unified resource web UI @@ -43,3 +45,12 @@ enum ViewMode { // LIST is the list view VIEW_MODE_LIST = 2; } + +/** LabelsViewMode is whether the labels for resources should all be collapsed or expanded. This only applies to the list view. */ +enum LabelsViewMode { + LABELS_VIEW_MODE_UNSPECIFIED = 0; + // EXPANDED is the expanded state which shows all labels for every resource. + LABELS_VIEW_MODE_EXPANDED = 1; + // COLLAPSED is the collapsed state which hides all labels for every resource. + LABELS_VIEW_MODE_COLLAPSED = 2; +} diff --git a/lib/auth/userpreferences/userpreferencesv1/service_test.go b/lib/auth/userpreferences/userpreferencesv1/service_test.go index f8ae03e60ead1..9e2fac7c2d86b 100644 --- a/lib/auth/userpreferences/userpreferencesv1/service_test.go +++ b/lib/auth/userpreferences/userpreferencesv1/service_test.go @@ -59,8 +59,9 @@ func TestService_GetUserPreferences(t *testing.T) { }, Theme: userpreferencesv1.Theme_THEME_LIGHT, UnifiedResourcePreferences: &userpreferencesv1.UnifiedResourcePreferences{ - DefaultTab: userpreferencesv1.DefaultTab_DEFAULT_TAB_ALL, - ViewMode: userpreferencesv1.ViewMode_VIEW_MODE_CARD, + DefaultTab: userpreferencesv1.DefaultTab_DEFAULT_TAB_ALL, + ViewMode: userpreferencesv1.ViewMode_VIEW_MODE_CARD, + LabelsViewMode: userpreferencesv1.LabelsViewMode_LABELS_VIEW_MODE_COLLAPSED, }, Onboard: &userpreferencesv1.OnboardUserPreferences{ PreferredResources: []userpreferencesv1.Resource{}, diff --git a/lib/services/local/userpreferences.go b/lib/services/local/userpreferences.go index a976e854f50bc..63865b60ff13a 100644 --- a/lib/services/local/userpreferences.go +++ b/lib/services/local/userpreferences.go @@ -42,8 +42,9 @@ func DefaultUserPreferences() *userpreferencesv1.UserPreferences { }, Theme: userpreferencesv1.Theme_THEME_LIGHT, UnifiedResourcePreferences: &userpreferencesv1.UnifiedResourcePreferences{ - DefaultTab: userpreferencesv1.DefaultTab_DEFAULT_TAB_ALL, - ViewMode: userpreferencesv1.ViewMode_VIEW_MODE_CARD, + DefaultTab: userpreferencesv1.DefaultTab_DEFAULT_TAB_ALL, + ViewMode: userpreferencesv1.ViewMode_VIEW_MODE_CARD, + LabelsViewMode: userpreferencesv1.LabelsViewMode_LABELS_VIEW_MODE_COLLAPSED, }, Onboard: &userpreferencesv1.OnboardUserPreferences{ PreferredResources: []userpreferencesv1.Resource{}, diff --git a/lib/services/local/userpreferences_test.go b/lib/services/local/userpreferences_test.go index 4caaf80e78b1c..fe8115a509839 100644 --- a/lib/services/local/userpreferences_test.go +++ b/lib/services/local/userpreferences_test.go @@ -120,8 +120,9 @@ func TestUserPreferencesCRUD(t *testing.T) { Onboard: defaultPref.Onboard, Theme: defaultPref.Theme, UnifiedResourcePreferences: &userpreferencesv1.UnifiedResourcePreferences{ - DefaultTab: userpreferencesv1.DefaultTab_DEFAULT_TAB_PINNED, - ViewMode: userpreferencesv1.ViewMode_VIEW_MODE_CARD, + DefaultTab: userpreferencesv1.DefaultTab_DEFAULT_TAB_PINNED, + ViewMode: userpreferencesv1.ViewMode_VIEW_MODE_CARD, + LabelsViewMode: userpreferencesv1.LabelsViewMode_LABELS_VIEW_MODE_COLLAPSED, }, ClusterPreferences: defaultPref.ClusterPreferences, }, @@ -230,8 +231,9 @@ func TestUserPreferencesCRUD(t *testing.T) { Preferences: &userpreferencesv1.UserPreferences{ Theme: userpreferencesv1.Theme_THEME_LIGHT, UnifiedResourcePreferences: &userpreferencesv1.UnifiedResourcePreferences{ - DefaultTab: userpreferencesv1.DefaultTab_DEFAULT_TAB_PINNED, - ViewMode: userpreferencesv1.ViewMode_VIEW_MODE_LIST, + DefaultTab: userpreferencesv1.DefaultTab_DEFAULT_TAB_PINNED, + ViewMode: userpreferencesv1.ViewMode_VIEW_MODE_LIST, + LabelsViewMode: userpreferencesv1.LabelsViewMode_LABELS_VIEW_MODE_COLLAPSED, }, Assist: &userpreferencesv1.AssistUserPreferences{ PreferredLogins: []string{"baz"}, @@ -256,8 +258,9 @@ func TestUserPreferencesCRUD(t *testing.T) { expected: &userpreferencesv1.UserPreferences{ Theme: userpreferencesv1.Theme_THEME_LIGHT, UnifiedResourcePreferences: &userpreferencesv1.UnifiedResourcePreferences{ - DefaultTab: userpreferencesv1.DefaultTab_DEFAULT_TAB_PINNED, - ViewMode: userpreferencesv1.ViewMode_VIEW_MODE_LIST, + DefaultTab: userpreferencesv1.DefaultTab_DEFAULT_TAB_PINNED, + ViewMode: userpreferencesv1.ViewMode_VIEW_MODE_LIST, + LabelsViewMode: userpreferencesv1.LabelsViewMode_LABELS_VIEW_MODE_COLLAPSED, }, Assist: &userpreferencesv1.AssistUserPreferences{ PreferredLogins: []string{"baz"}, diff --git a/lib/web/userpreferences.go b/lib/web/userpreferences.go index 100dbfda5f0c0..58591c0b4484b 100644 --- a/lib/web/userpreferences.go +++ b/lib/web/userpreferences.go @@ -51,8 +51,9 @@ type ClusterUserPreferencesResponse struct { } type UnifiedResourcePreferencesResponse struct { - DefaultTab userpreferencesv1.DefaultTab `json:"defaultTab"` - ViewMode userpreferencesv1.ViewMode `json:"viewMode"` + DefaultTab userpreferencesv1.DefaultTab `json:"defaultTab"` + ViewMode userpreferencesv1.ViewMode `json:"viewMode"` + LabelsViewMode userpreferencesv1.LabelsViewMode `json:"labelsViewMode"` } // UserPreferencesResponse is the JSON response for the user preferences. @@ -120,8 +121,9 @@ func makePreferenceRequest(req UserPreferencesResponse) *userpreferencesv1.Upser Preferences: &userpreferencesv1.UserPreferences{ Theme: req.Theme, UnifiedResourcePreferences: &userpreferencesv1.UnifiedResourcePreferences{ - DefaultTab: req.UnifiedResourcePreferences.DefaultTab, - ViewMode: req.UnifiedResourcePreferences.ViewMode, + DefaultTab: req.UnifiedResourcePreferences.DefaultTab, + ViewMode: req.UnifiedResourcePreferences.ViewMode, + LabelsViewMode: req.UnifiedResourcePreferences.LabelsViewMode, }, Assist: &userpreferencesv1.AssistUserPreferences{ PreferredLogins: req.Assist.PreferredLogins, @@ -205,8 +207,9 @@ func assistUserPreferencesResponse(resp *userpreferencesv1.AssistUserPreferences // unifiedResourcePreferencesResponse creates a JSON response for the assist user preferences. func unifiedResourcePreferencesResponse(resp *userpreferencesv1.UnifiedResourcePreferences) UnifiedResourcePreferencesResponse { return UnifiedResourcePreferencesResponse{ - DefaultTab: resp.DefaultTab, - ViewMode: resp.ViewMode, + DefaultTab: resp.DefaultTab, + ViewMode: resp.ViewMode, + LabelsViewMode: resp.LabelsViewMode, } } diff --git a/web/packages/shared/components/UnifiedResources/CardsView/ResourceCard.tsx b/web/packages/shared/components/UnifiedResources/CardsView/ResourceCard.tsx index 7e2206ccd6a94..541c88c824111 100644 --- a/web/packages/shared/components/UnifiedResources/CardsView/ResourceCard.tsx +++ b/web/packages/shared/components/UnifiedResources/CardsView/ResourceCard.tsx @@ -59,7 +59,7 @@ export function ResourceCard({ pinResource, selectResource, selected, -}: Omit) { +}: Omit) { const { primaryDesc, secondaryDesc } = cardViewProps; const [showMoreLabelsButton, setShowMoreLabelsButton] = useState(false); diff --git a/web/packages/shared/components/UnifiedResources/FilterPanel.tsx b/web/packages/shared/components/UnifiedResources/FilterPanel.tsx index 8ab8ba2cf1624..1f09826f24ffb 100644 --- a/web/packages/shared/components/UnifiedResources/FilterPanel.tsx +++ b/web/packages/shared/components/UnifiedResources/FilterPanel.tsx @@ -27,6 +27,8 @@ import { ChevronDown, SquaresFour, Rows, + ArrowsIn, + ArrowsOut, } from 'design/Icon'; import { ViewMode } from 'shared/services/unifiedResourcePreferences'; @@ -57,7 +59,9 @@ interface FilterPanelProps { selected: boolean; BulkActions?: React.ReactElement; currentViewMode: ViewMode; - onSelectViewMode: (viewMode: ViewMode) => void; + setCurrentViewMode: (viewMode: ViewMode) => void; + expandAllLabels: boolean; + setExpandAllLabels: (expandAllLabels: boolean) => void; } export function FilterPanel({ @@ -68,7 +72,9 @@ export function FilterPanel({ selected, BulkActions, currentViewMode, - onSelectViewMode, + setCurrentViewMode, + expandAllLabels, + setExpandAllLabels, }: FilterPanelProps) { const { sort, kinds } = params; @@ -112,10 +118,34 @@ export function FilterPanel({ /> - {BulkActions} + {BulkActions} + {currentViewMode === ViewMode.VIEW_MODE_LIST && ( + props.theme.colors.text.slightlyMuted}; + text-transform: none; + padding-left: ${props => props.theme.space[2]}px; + padding-right: ${props => props.theme.space[2]}px; + height: 22px; + width: 128px; + `} + onClick={() => setExpandAllLabels(!expandAllLabels)} + > + + {expandAllLabels ? ( + + ) : ( + + )} + {expandAllLabels ? 'Collapse ' : 'Expand '} All Labels + + + )} void; + setCurrentViewMode: (viewMode: ViewMode) => void; }) { return ( @@ -426,7 +456,7 @@ function ViewModeSwitch({ className={ currentViewMode === ViewMode.VIEW_MODE_CARD ? 'selected' : '' } - onClick={() => onSelectViewMode(ViewMode.VIEW_MODE_CARD)} + onClick={() => setCurrentViewMode(ViewMode.VIEW_MODE_CARD)} css={` border-right: 1px solid ${props => props.theme.colors.spotBackground[2]}; @@ -440,7 +470,7 @@ function ViewModeSwitch({ className={ currentViewMode === ViewMode.VIEW_MODE_LIST ? 'selected' : '' } - onClick={() => onSelectViewMode(ViewMode.VIEW_MODE_LIST)} + onClick={() => setCurrentViewMode(ViewMode.VIEW_MODE_LIST)} css={` border-top-right-radius: 4px; border-bottom-right-radius: 4px; diff --git a/web/packages/shared/components/UnifiedResources/ListView/ListView.tsx b/web/packages/shared/components/UnifiedResources/ListView/ListView.tsx index 885bd7319617c..4d7c8e05d3bb7 100644 --- a/web/packages/shared/components/UnifiedResources/ListView/ListView.tsx +++ b/web/packages/shared/components/UnifiedResources/ListView/ListView.tsx @@ -35,6 +35,7 @@ export function ListView({ onPinResource, pinningSupport, isProcessing, + expandAllLabels, }: ResourceViewProps) { return ( @@ -53,6 +54,7 @@ export function ListView({ selected={selectedResources.includes(key)} selectResource={() => onSelectResource(key)} pinResource={() => onPinResource(key)} + expandAllLabels={expandAllLabels} /> ))} {isProcessing && ( diff --git a/web/packages/shared/components/UnifiedResources/ListView/ResourceListItem.story.tsx b/web/packages/shared/components/UnifiedResources/ListView/ResourceListItem.story.tsx index 4077f569fff80..55e48fea2de07 100644 --- a/web/packages/shared/components/UnifiedResources/ListView/ResourceListItem.story.tsx +++ b/web/packages/shared/components/UnifiedResources/ListView/ResourceListItem.story.tsx @@ -126,6 +126,7 @@ export const ListItems: Story = { listViewProps={res.listViewProps} labels={res.labels} ActionButton={res.ActionButton} + expandAllLabels={false} /> ))} diff --git a/web/packages/shared/components/UnifiedResources/ListView/ResourceListItem.tsx b/web/packages/shared/components/UnifiedResources/ListView/ResourceListItem.tsx index 89cc40754163c..28422c412a487 100644 --- a/web/packages/shared/components/UnifiedResources/ListView/ResourceListItem.tsx +++ b/web/packages/shared/components/UnifiedResources/ListView/ResourceListItem.tsx @@ -14,7 +14,7 @@ * limitations under the License. */ -import React, { useState } from 'react'; +import React, { useEffect, useState } from 'react'; import styled from 'styled-components'; import { Box, ButtonIcon, Flex, Label, Text } from 'design'; @@ -43,12 +43,18 @@ export function ResourceListItem({ pinResource, selectResource, selected, + expandAllLabels, }: Omit) { const { description, resourceType, addr } = listViewProps; - const [showLabels, setShowLabels] = useState(false); + const [showLabels, setShowLabels] = useState(expandAllLabels); const [hovered, setHovered] = useState(false); + // Update whether this item's labels are shown if the `expandAllLabels` preference is updated. + useEffect(() => { + setShowLabels(expandAllLabels); + }, [expandAllLabels]); + const showLabelsButton = labels.length > 0 && (hovered || showLabels); // Determines which column the resource type text should end at. diff --git a/web/packages/shared/components/UnifiedResources/UnifiedResources.story.tsx b/web/packages/shared/components/UnifiedResources/UnifiedResources.story.tsx index 1701a259ebdf6..4dc187b9bd5ba 100644 --- a/web/packages/shared/components/UnifiedResources/UnifiedResources.story.tsx +++ b/web/packages/shared/components/UnifiedResources/UnifiedResources.story.tsx @@ -31,6 +31,7 @@ import { UnifiedResourcePreferences, DefaultTab, ViewMode, + LabelsViewMode, } from 'shared/services/unifiedResourcePreferences'; import { UnifiedResources, useUnifiedResourcesFetch } from './UnifiedResources'; @@ -95,6 +96,7 @@ const story = ({ const [userPrefs, setUserPrefs] = useState({ defaultTab: DefaultTab.DEFAULT_TAB_ALL, viewMode: ViewMode.VIEW_MODE_CARD, + labelsViewMode: LabelsViewMode.LABELS_VIEW_MODE_COLLAPSED, }); const { fetch, attempt, resources } = useUnifiedResourcesFetch({ fetchFunc, diff --git a/web/packages/shared/components/UnifiedResources/UnifiedResources.tsx b/web/packages/shared/components/UnifiedResources/UnifiedResources.tsx index 239099eb92f69..014bfcfb8bc4e 100644 --- a/web/packages/shared/components/UnifiedResources/UnifiedResources.tsx +++ b/web/packages/shared/components/UnifiedResources/UnifiedResources.tsx @@ -36,6 +36,7 @@ import { DefaultTab, ViewMode, UnifiedResourcePreferences, + LabelsViewMode, } from 'shared/services/unifiedResourcePreferences'; import { HoverTooltip } from 'shared/components/ToolTip'; import { @@ -292,6 +293,13 @@ export function UnifiedResources(props: UnifiedResourcesProps) { }); }; + const setLabelsViewMode = (labelsViewMode: LabelsViewMode) => { + updateUnifiedResourcesPreferences({ + ...unifiedResourcePreferences, + labelsViewMode, + }); + }; + const getSelectedResources = () => { return resources .filter(({ resource }) => @@ -326,6 +334,10 @@ export function UnifiedResources(props: UnifiedResourcesProps) { ]; }; + const expandAllLabels = + unifiedResourcePreferences.labelsViewMode === + LabelsViewMode.LABELS_VIEW_MODE_EXPANDED; + const ViewComponent = unifiedResourcePreferences.viewMode === ViewMode.VIEW_MODE_LIST ? ListView @@ -380,7 +392,15 @@ export function UnifiedResources(props: UnifiedResourcesProps) { selectVisible={toggleSelectVisible} selected={allSelected} currentViewMode={unifiedResourcePreferences.viewMode} - onSelectViewMode={selectViewMode} + setCurrentViewMode={selectViewMode} + expandAllLabels={expandAllLabels} + setExpandAllLabels={expandAllLabels => { + setLabelsViewMode( + expandAllLabels + ? LabelsViewMode.LABELS_VIEW_MODE_EXPANDED + : LabelsViewMode.LABELS_VIEW_MODE_COLLAPSED + ); + }} BulkActions={ <> {selectedResources.length > 0 && ( @@ -462,6 +482,7 @@ export function UnifiedResources(props: UnifiedResourcesProps) { item: mapResourceToViewItem(unifiedResource), key: generateUnifiedResourceKey(unifiedResource.resource), }))} + expandAllLabels={expandAllLabels} /> )}
diff --git a/web/packages/shared/components/UnifiedResources/types.ts b/web/packages/shared/components/UnifiedResources/types.ts index 4f5140391e538..1a79b920e4ae0 100644 --- a/web/packages/shared/components/UnifiedResources/types.ts +++ b/web/packages/shared/components/UnifiedResources/types.ts @@ -145,6 +145,7 @@ export type ResourceItemProps = { selected: boolean; pinned: boolean; pinningSupport: PinningSupport; + expandAllLabels: boolean; }; // Props that are needed for the Card view. @@ -185,4 +186,5 @@ export type ResourceViewProps = { pinningSupport: PinningSupport; isProcessing: boolean; mappedResources: { item: UnifiedResourceViewItem; key: string }[]; + expandAllLabels: boolean; }; diff --git a/web/packages/shared/services/unifiedResourcePreferences.ts b/web/packages/shared/services/unifiedResourcePreferences.ts index aa40cc8186166..f7c8ba84e2771 100644 --- a/web/packages/shared/services/unifiedResourcePreferences.ts +++ b/web/packages/shared/services/unifiedResourcePreferences.ts @@ -31,6 +31,8 @@ export interface UnifiedResourcePreferences { defaultTab: DefaultTab; /** View mode selected in the unified resource view (Cards/List). */ viewMode: ViewMode; + /** Labels view mode is whether the labels for resources should all be collapsed or expanded. This only applies to the list view. */ + labelsViewMode: LabelsViewMode; } export enum DefaultTab { @@ -44,3 +46,9 @@ export enum ViewMode { VIEW_MODE_CARD = 1, VIEW_MODE_LIST = 2, } + +export enum LabelsViewMode { + LABELS_VIEW_MODE_UNSPECIFIED = 0, + LABELS_VIEW_MODE_EXPANDED = 1, + LABELS_VIEW_MODE_COLLAPSED = 2, +} diff --git a/web/packages/teleport/src/services/userPreferences/userPreferences.ts b/web/packages/teleport/src/services/userPreferences/userPreferences.ts index adb7776ec6ad8..5e8cf6488bd98 100644 --- a/web/packages/teleport/src/services/userPreferences/userPreferences.ts +++ b/web/packages/teleport/src/services/userPreferences/userPreferences.ts @@ -92,6 +92,8 @@ export function makeDefaultUserPreferences(): UserPreferences { unifiedResourcePreferences: { defaultTab: unifiedResourcePreferences.DefaultTab.DEFAULT_TAB_ALL, viewMode: unifiedResourcePreferences.ViewMode.VIEW_MODE_CARD, + labelsViewMode: + unifiedResourcePreferences.LabelsViewMode.LABELS_VIEW_MODE_COLLAPSED, }, clusterPreferences: makeDefaultUserClusterPreferences(), };