mirror of
https://github.com/ClusterCockpit/cc-backend
synced 2026-08-08 14:27:14 +02:00
add tooltips to metricConfig, rendered in metricSelect, rework availability display
This commit is contained in:
@@ -143,6 +143,7 @@ type MetricConfig {
|
|||||||
alert: Float!
|
alert: Float!
|
||||||
lowerIsBetter: Boolean
|
lowerIsBetter: Boolean
|
||||||
subClusters: [SubClusterConfig!]!
|
subClusters: [SubClusterConfig!]!
|
||||||
|
tooltip: String
|
||||||
}
|
}
|
||||||
|
|
||||||
type Tag {
|
type Tag {
|
||||||
@@ -300,6 +301,7 @@ type GlobalMetricListItem {
|
|||||||
unit: Unit!
|
unit: Unit!
|
||||||
scope: MetricScope!
|
scope: MetricScope!
|
||||||
footprint: String
|
footprint: String
|
||||||
|
tooltip: String
|
||||||
availability: [ClusterSupport!]!
|
availability: [ClusterSupport!]!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -32,7 +32,9 @@ type Config = graphql.Config[ResolverRoot, DirectiveRoot, ComplexityRoot]
|
|||||||
|
|
||||||
type ResolverRoot interface {
|
type ResolverRoot interface {
|
||||||
Cluster() ClusterResolver
|
Cluster() ClusterResolver
|
||||||
|
GlobalMetricListItem() GlobalMetricListItemResolver
|
||||||
Job() JobResolver
|
Job() JobResolver
|
||||||
|
MetricConfig() MetricConfigResolver
|
||||||
MetricValue() MetricValueResolver
|
MetricValue() MetricValueResolver
|
||||||
Mutation() MutationResolver
|
Mutation() MutationResolver
|
||||||
Node() NodeResolver
|
Node() NodeResolver
|
||||||
@@ -100,6 +102,7 @@ type ComplexityRoot struct {
|
|||||||
Footprint func(childComplexity int) int
|
Footprint func(childComplexity int) int
|
||||||
Name func(childComplexity int) int
|
Name func(childComplexity int) int
|
||||||
Scope func(childComplexity int) int
|
Scope func(childComplexity int) int
|
||||||
|
Tooltip func(childComplexity int) int
|
||||||
Unit func(childComplexity int) int
|
Unit func(childComplexity int) int
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -219,6 +222,7 @@ type ComplexityRoot struct {
|
|||||||
Scope func(childComplexity int) int
|
Scope func(childComplexity int) int
|
||||||
SubClusters func(childComplexity int) int
|
SubClusters func(childComplexity int) int
|
||||||
Timestep func(childComplexity int) int
|
Timestep func(childComplexity int) int
|
||||||
|
Tooltip func(childComplexity int) int
|
||||||
Unit func(childComplexity int) int
|
Unit func(childComplexity int) int
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -441,6 +445,9 @@ type ComplexityRoot struct {
|
|||||||
type ClusterResolver interface {
|
type ClusterResolver interface {
|
||||||
Partitions(ctx context.Context, obj *schema.Cluster) ([]string, error)
|
Partitions(ctx context.Context, obj *schema.Cluster) ([]string, error)
|
||||||
}
|
}
|
||||||
|
type GlobalMetricListItemResolver interface {
|
||||||
|
Tooltip(ctx context.Context, obj *schema.GlobalMetricListItem) (*string, error)
|
||||||
|
}
|
||||||
type JobResolver interface {
|
type JobResolver interface {
|
||||||
StartTime(ctx context.Context, obj *schema.Job) (*time.Time, error)
|
StartTime(ctx context.Context, obj *schema.Job) (*time.Time, error)
|
||||||
|
|
||||||
@@ -452,6 +459,9 @@ type JobResolver interface {
|
|||||||
MetaData(ctx context.Context, obj *schema.Job) (any, error)
|
MetaData(ctx context.Context, obj *schema.Job) (any, error)
|
||||||
UserData(ctx context.Context, obj *schema.Job) (*model.User, error)
|
UserData(ctx context.Context, obj *schema.Job) (*model.User, error)
|
||||||
}
|
}
|
||||||
|
type MetricConfigResolver interface {
|
||||||
|
Tooltip(ctx context.Context, obj *schema.MetricConfig) (*string, error)
|
||||||
|
}
|
||||||
type MetricValueResolver interface {
|
type MetricValueResolver interface {
|
||||||
Name(ctx context.Context, obj *schema.MetricValue) (*string, error)
|
Name(ctx context.Context, obj *schema.MetricValue) (*string, error)
|
||||||
}
|
}
|
||||||
@@ -690,6 +700,12 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin
|
|||||||
}
|
}
|
||||||
|
|
||||||
return e.ComplexityRoot.GlobalMetricListItem.Scope(childComplexity), true
|
return e.ComplexityRoot.GlobalMetricListItem.Scope(childComplexity), true
|
||||||
|
case "GlobalMetricListItem.tooltip":
|
||||||
|
if e.ComplexityRoot.GlobalMetricListItem.Tooltip == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
return e.ComplexityRoot.GlobalMetricListItem.Tooltip(childComplexity), true
|
||||||
case "GlobalMetricListItem.unit":
|
case "GlobalMetricListItem.unit":
|
||||||
if e.ComplexityRoot.GlobalMetricListItem.Unit == nil {
|
if e.ComplexityRoot.GlobalMetricListItem.Unit == nil {
|
||||||
break
|
break
|
||||||
@@ -1217,6 +1233,12 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin
|
|||||||
}
|
}
|
||||||
|
|
||||||
return e.ComplexityRoot.MetricConfig.Timestep(childComplexity), true
|
return e.ComplexityRoot.MetricConfig.Timestep(childComplexity), true
|
||||||
|
case "MetricConfig.tooltip":
|
||||||
|
if e.ComplexityRoot.MetricConfig.Tooltip == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
return e.ComplexityRoot.MetricConfig.Tooltip(childComplexity), true
|
||||||
case "MetricConfig.unit":
|
case "MetricConfig.unit":
|
||||||
if e.ComplexityRoot.MetricConfig.Unit == nil {
|
if e.ComplexityRoot.MetricConfig.Unit == nil {
|
||||||
break
|
break
|
||||||
@@ -2418,6 +2440,7 @@ type MetricConfig {
|
|||||||
alert: Float!
|
alert: Float!
|
||||||
lowerIsBetter: Boolean
|
lowerIsBetter: Boolean
|
||||||
subClusters: [SubClusterConfig!]!
|
subClusters: [SubClusterConfig!]!
|
||||||
|
tooltip: String
|
||||||
}
|
}
|
||||||
|
|
||||||
type Tag {
|
type Tag {
|
||||||
@@ -2575,6 +2598,7 @@ type GlobalMetricListItem {
|
|||||||
unit: Unit!
|
unit: Unit!
|
||||||
scope: MetricScope!
|
scope: MetricScope!
|
||||||
footprint: String
|
footprint: String
|
||||||
|
tooltip: String
|
||||||
availability: [ClusterSupport!]!
|
availability: [ClusterSupport!]!
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2957,6 +2981,8 @@ func (ec *executionContext) childFields_GlobalMetricListItem(ctx context.Context
|
|||||||
return ec.fieldContext_GlobalMetricListItem_scope(ctx, field)
|
return ec.fieldContext_GlobalMetricListItem_scope(ctx, field)
|
||||||
case "footprint":
|
case "footprint":
|
||||||
return ec.fieldContext_GlobalMetricListItem_footprint(ctx, field)
|
return ec.fieldContext_GlobalMetricListItem_footprint(ctx, field)
|
||||||
|
case "tooltip":
|
||||||
|
return ec.fieldContext_GlobalMetricListItem_tooltip(ctx, field)
|
||||||
case "availability":
|
case "availability":
|
||||||
return ec.fieldContext_GlobalMetricListItem_availability(ctx, field)
|
return ec.fieldContext_GlobalMetricListItem_availability(ctx, field)
|
||||||
}
|
}
|
||||||
@@ -3187,6 +3213,8 @@ func (ec *executionContext) childFields_MetricConfig(ctx context.Context, field
|
|||||||
return ec.fieldContext_MetricConfig_lowerIsBetter(ctx, field)
|
return ec.fieldContext_MetricConfig_lowerIsBetter(ctx, field)
|
||||||
case "subClusters":
|
case "subClusters":
|
||||||
return ec.fieldContext_MetricConfig_subClusters(ctx, field)
|
return ec.fieldContext_MetricConfig_subClusters(ctx, field)
|
||||||
|
case "tooltip":
|
||||||
|
return ec.fieldContext_MetricConfig_tooltip(ctx, field)
|
||||||
}
|
}
|
||||||
return nil, fmt.Errorf("no field named %q was found under type MetricConfig", field.Name)
|
return nil, fmt.Errorf("no field named %q was found under type MetricConfig", field.Name)
|
||||||
}
|
}
|
||||||
@@ -5159,6 +5187,29 @@ func (ec *executionContext) fieldContext_GlobalMetricListItem_footprint(_ contex
|
|||||||
return graphql.NewScalarFieldContext("GlobalMetricListItem", field, false, false, errors.New("field of type String does not have child fields"))
|
return graphql.NewScalarFieldContext("GlobalMetricListItem", field, false, false, errors.New("field of type String does not have child fields"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) _GlobalMetricListItem_tooltip(ctx context.Context, field graphql.CollectedField, obj *schema.GlobalMetricListItem) (ret graphql.Marshaler) {
|
||||||
|
return graphql.ResolveField(
|
||||||
|
ctx,
|
||||||
|
ec.OperationContext,
|
||||||
|
field,
|
||||||
|
func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
|
||||||
|
return ec.fieldContext_GlobalMetricListItem_tooltip(ctx, field)
|
||||||
|
},
|
||||||
|
func(ctx context.Context) (any, error) {
|
||||||
|
return ec.Resolvers.GlobalMetricListItem().Tooltip(ctx, obj)
|
||||||
|
},
|
||||||
|
nil,
|
||||||
|
func(ctx context.Context, selections ast.SelectionSet, v *string) graphql.Marshaler {
|
||||||
|
return ec.marshalOString2ᚖstring(ctx, selections, v)
|
||||||
|
},
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
func (ec *executionContext) fieldContext_GlobalMetricListItem_tooltip(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
|
||||||
|
return graphql.NewScalarFieldContext("GlobalMetricListItem", field, true, true, errors.New("field of type String does not have child fields"))
|
||||||
|
}
|
||||||
|
|
||||||
func (ec *executionContext) _GlobalMetricListItem_availability(ctx context.Context, field graphql.CollectedField, obj *schema.GlobalMetricListItem) (ret graphql.Marshaler) {
|
func (ec *executionContext) _GlobalMetricListItem_availability(ctx context.Context, field graphql.CollectedField, obj *schema.GlobalMetricListItem) (ret graphql.Marshaler) {
|
||||||
return graphql.ResolveField(
|
return graphql.ResolveField(
|
||||||
ctx,
|
ctx,
|
||||||
@@ -7349,6 +7400,29 @@ func (ec *executionContext) fieldContext_MetricConfig_subClusters(_ context.Cont
|
|||||||
return fc, nil
|
return fc, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) _MetricConfig_tooltip(ctx context.Context, field graphql.CollectedField, obj *schema.MetricConfig) (ret graphql.Marshaler) {
|
||||||
|
return graphql.ResolveField(
|
||||||
|
ctx,
|
||||||
|
ec.OperationContext,
|
||||||
|
field,
|
||||||
|
func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) {
|
||||||
|
return ec.fieldContext_MetricConfig_tooltip(ctx, field)
|
||||||
|
},
|
||||||
|
func(ctx context.Context) (any, error) {
|
||||||
|
return ec.Resolvers.MetricConfig().Tooltip(ctx, obj)
|
||||||
|
},
|
||||||
|
nil,
|
||||||
|
func(ctx context.Context, selections ast.SelectionSet, v *string) graphql.Marshaler {
|
||||||
|
return ec.marshalOString2ᚖstring(ctx, selections, v)
|
||||||
|
},
|
||||||
|
true,
|
||||||
|
false,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
func (ec *executionContext) fieldContext_MetricConfig_tooltip(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) {
|
||||||
|
return graphql.NewScalarFieldContext("MetricConfig", field, true, true, errors.New("field of type String does not have child fields"))
|
||||||
|
}
|
||||||
|
|
||||||
func (ec *executionContext) _MetricFootprints_metric(ctx context.Context, field graphql.CollectedField, obj *model.MetricFootprints) (ret graphql.Marshaler) {
|
func (ec *executionContext) _MetricFootprints_metric(ctx context.Context, field graphql.CollectedField, obj *model.MetricFootprints) (ret graphql.Marshaler) {
|
||||||
return graphql.ResolveField(
|
return graphql.ResolveField(
|
||||||
ctx,
|
ctx,
|
||||||
@@ -13269,24 +13343,57 @@ func (ec *executionContext) _GlobalMetricListItem(ctx context.Context, sel ast.S
|
|||||||
case "name":
|
case "name":
|
||||||
out.Values[i] = ec._GlobalMetricListItem_name(ctx, field, obj)
|
out.Values[i] = ec._GlobalMetricListItem_name(ctx, field, obj)
|
||||||
if out.Values[i] == graphql.Null {
|
if out.Values[i] == graphql.Null {
|
||||||
out.Invalids++
|
atomic.AddUint32(&out.Invalids, 1)
|
||||||
}
|
}
|
||||||
case "unit":
|
case "unit":
|
||||||
out.Values[i] = ec._GlobalMetricListItem_unit(ctx, field, obj)
|
out.Values[i] = ec._GlobalMetricListItem_unit(ctx, field, obj)
|
||||||
if out.Values[i] == graphql.Null {
|
if out.Values[i] == graphql.Null {
|
||||||
out.Invalids++
|
atomic.AddUint32(&out.Invalids, 1)
|
||||||
}
|
}
|
||||||
case "scope":
|
case "scope":
|
||||||
out.Values[i] = ec._GlobalMetricListItem_scope(ctx, field, obj)
|
out.Values[i] = ec._GlobalMetricListItem_scope(ctx, field, obj)
|
||||||
if out.Values[i] == graphql.Null {
|
if out.Values[i] == graphql.Null {
|
||||||
out.Invalids++
|
atomic.AddUint32(&out.Invalids, 1)
|
||||||
}
|
}
|
||||||
case "footprint":
|
case "footprint":
|
||||||
out.Values[i] = ec._GlobalMetricListItem_footprint(ctx, field, obj)
|
out.Values[i] = ec._GlobalMetricListItem_footprint(ctx, field, obj)
|
||||||
|
case "tooltip":
|
||||||
|
field := field
|
||||||
|
|
||||||
|
innerFunc := func(ctx context.Context, _ *graphql.FieldSet) (res graphql.Marshaler) {
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
ec.Error(ctx, ec.Recover(ctx, r))
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
res = ec._GlobalMetricListItem_tooltip(ctx, field, obj)
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
if field.Deferrable != nil {
|
||||||
|
dfs, ok := deferred[field.Deferrable.Label]
|
||||||
|
di := 0
|
||||||
|
if ok {
|
||||||
|
dfs.AddField(field)
|
||||||
|
di = len(dfs.Values) - 1
|
||||||
|
} else {
|
||||||
|
dfs = graphql.NewFieldSet([]graphql.CollectedField{field})
|
||||||
|
deferred[field.Deferrable.Label] = dfs
|
||||||
|
}
|
||||||
|
dfs.Concurrently(di, func(ctx context.Context) graphql.Marshaler {
|
||||||
|
return innerFunc(ctx, dfs)
|
||||||
|
})
|
||||||
|
|
||||||
|
// don't run the out.Concurrently() call below
|
||||||
|
out.Values[i] = graphql.Null
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) })
|
||||||
case "availability":
|
case "availability":
|
||||||
out.Values[i] = ec._GlobalMetricListItem_availability(ctx, field, obj)
|
out.Values[i] = ec._GlobalMetricListItem_availability(ctx, field, obj)
|
||||||
if out.Values[i] == graphql.Null {
|
if out.Values[i] == graphql.Null {
|
||||||
out.Invalids++
|
atomic.AddUint32(&out.Invalids, 1)
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
panic("unknown field " + strconv.Quote(field.Name))
|
panic("unknown field " + strconv.Quote(field.Name))
|
||||||
@@ -14209,52 +14316,85 @@ func (ec *executionContext) _MetricConfig(ctx context.Context, sel ast.Selection
|
|||||||
case "name":
|
case "name":
|
||||||
out.Values[i] = ec._MetricConfig_name(ctx, field, obj)
|
out.Values[i] = ec._MetricConfig_name(ctx, field, obj)
|
||||||
if out.Values[i] == graphql.Null {
|
if out.Values[i] == graphql.Null {
|
||||||
out.Invalids++
|
atomic.AddUint32(&out.Invalids, 1)
|
||||||
}
|
}
|
||||||
case "unit":
|
case "unit":
|
||||||
out.Values[i] = ec._MetricConfig_unit(ctx, field, obj)
|
out.Values[i] = ec._MetricConfig_unit(ctx, field, obj)
|
||||||
if out.Values[i] == graphql.Null {
|
if out.Values[i] == graphql.Null {
|
||||||
out.Invalids++
|
atomic.AddUint32(&out.Invalids, 1)
|
||||||
}
|
}
|
||||||
case "scope":
|
case "scope":
|
||||||
out.Values[i] = ec._MetricConfig_scope(ctx, field, obj)
|
out.Values[i] = ec._MetricConfig_scope(ctx, field, obj)
|
||||||
if out.Values[i] == graphql.Null {
|
if out.Values[i] == graphql.Null {
|
||||||
out.Invalids++
|
atomic.AddUint32(&out.Invalids, 1)
|
||||||
}
|
}
|
||||||
case "aggregation":
|
case "aggregation":
|
||||||
out.Values[i] = ec._MetricConfig_aggregation(ctx, field, obj)
|
out.Values[i] = ec._MetricConfig_aggregation(ctx, field, obj)
|
||||||
if out.Values[i] == graphql.Null {
|
if out.Values[i] == graphql.Null {
|
||||||
out.Invalids++
|
atomic.AddUint32(&out.Invalids, 1)
|
||||||
}
|
}
|
||||||
case "timestep":
|
case "timestep":
|
||||||
out.Values[i] = ec._MetricConfig_timestep(ctx, field, obj)
|
out.Values[i] = ec._MetricConfig_timestep(ctx, field, obj)
|
||||||
if out.Values[i] == graphql.Null {
|
if out.Values[i] == graphql.Null {
|
||||||
out.Invalids++
|
atomic.AddUint32(&out.Invalids, 1)
|
||||||
}
|
}
|
||||||
case "peak":
|
case "peak":
|
||||||
out.Values[i] = ec._MetricConfig_peak(ctx, field, obj)
|
out.Values[i] = ec._MetricConfig_peak(ctx, field, obj)
|
||||||
if out.Values[i] == graphql.Null {
|
if out.Values[i] == graphql.Null {
|
||||||
out.Invalids++
|
atomic.AddUint32(&out.Invalids, 1)
|
||||||
}
|
}
|
||||||
case "normal":
|
case "normal":
|
||||||
out.Values[i] = ec._MetricConfig_normal(ctx, field, obj)
|
out.Values[i] = ec._MetricConfig_normal(ctx, field, obj)
|
||||||
case "caution":
|
case "caution":
|
||||||
out.Values[i] = ec._MetricConfig_caution(ctx, field, obj)
|
out.Values[i] = ec._MetricConfig_caution(ctx, field, obj)
|
||||||
if out.Values[i] == graphql.Null {
|
if out.Values[i] == graphql.Null {
|
||||||
out.Invalids++
|
atomic.AddUint32(&out.Invalids, 1)
|
||||||
}
|
}
|
||||||
case "alert":
|
case "alert":
|
||||||
out.Values[i] = ec._MetricConfig_alert(ctx, field, obj)
|
out.Values[i] = ec._MetricConfig_alert(ctx, field, obj)
|
||||||
if out.Values[i] == graphql.Null {
|
if out.Values[i] == graphql.Null {
|
||||||
out.Invalids++
|
atomic.AddUint32(&out.Invalids, 1)
|
||||||
}
|
}
|
||||||
case "lowerIsBetter":
|
case "lowerIsBetter":
|
||||||
out.Values[i] = ec._MetricConfig_lowerIsBetter(ctx, field, obj)
|
out.Values[i] = ec._MetricConfig_lowerIsBetter(ctx, field, obj)
|
||||||
case "subClusters":
|
case "subClusters":
|
||||||
out.Values[i] = ec._MetricConfig_subClusters(ctx, field, obj)
|
out.Values[i] = ec._MetricConfig_subClusters(ctx, field, obj)
|
||||||
if out.Values[i] == graphql.Null {
|
if out.Values[i] == graphql.Null {
|
||||||
out.Invalids++
|
atomic.AddUint32(&out.Invalids, 1)
|
||||||
}
|
}
|
||||||
|
case "tooltip":
|
||||||
|
field := field
|
||||||
|
|
||||||
|
innerFunc := func(ctx context.Context, _ *graphql.FieldSet) (res graphql.Marshaler) {
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
ec.Error(ctx, ec.Recover(ctx, r))
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
res = ec._MetricConfig_tooltip(ctx, field, obj)
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
if field.Deferrable != nil {
|
||||||
|
dfs, ok := deferred[field.Deferrable.Label]
|
||||||
|
di := 0
|
||||||
|
if ok {
|
||||||
|
dfs.AddField(field)
|
||||||
|
di = len(dfs.Values) - 1
|
||||||
|
} else {
|
||||||
|
dfs = graphql.NewFieldSet([]graphql.CollectedField{field})
|
||||||
|
deferred[field.Deferrable.Label] = dfs
|
||||||
|
}
|
||||||
|
dfs.Concurrently(di, func(ctx context.Context) graphql.Marshaler {
|
||||||
|
return innerFunc(ctx, dfs)
|
||||||
|
})
|
||||||
|
|
||||||
|
// don't run the out.Concurrently() call below
|
||||||
|
out.Values[i] = graphql.Null
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) })
|
||||||
default:
|
default:
|
||||||
panic("unknown field " + strconv.Quote(field.Name))
|
panic("unknown field " + strconv.Quote(field.Name))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,6 +32,11 @@ func (r *clusterResolver) Partitions(ctx context.Context, obj *schema.Cluster) (
|
|||||||
return r.Repo.Partitions(obj.Name)
|
return r.Repo.Partitions(obj.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Tooltip is the resolver for the tooltip field.
|
||||||
|
func (r *globalMetricListItemResolver) Tooltip(ctx context.Context, obj *schema.GlobalMetricListItem) (*string, error) {
|
||||||
|
return &obj.Tooltip, nil
|
||||||
|
}
|
||||||
|
|
||||||
// StartTime is the resolver for the startTime field.
|
// StartTime is the resolver for the startTime field.
|
||||||
func (r *jobResolver) StartTime(ctx context.Context, obj *schema.Job) (*time.Time, error) {
|
func (r *jobResolver) StartTime(ctx context.Context, obj *schema.Job) (*time.Time, error) {
|
||||||
timestamp := time.Unix(obj.StartTime, 0)
|
timestamp := time.Unix(obj.StartTime, 0)
|
||||||
@@ -127,6 +132,11 @@ func (r *jobResolver) UserData(ctx context.Context, obj *schema.Job) (*model.Use
|
|||||||
return repository.GetUserRepository().FetchUserInCtx(ctx, obj.User)
|
return repository.GetUserRepository().FetchUserInCtx(ctx, obj.User)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Tooltip is the resolver for the tooltip field.
|
||||||
|
func (r *metricConfigResolver) Tooltip(ctx context.Context, obj *schema.MetricConfig) (*string, error) {
|
||||||
|
return &obj.Tooltip, nil
|
||||||
|
}
|
||||||
|
|
||||||
// Name is the resolver for the name field.
|
// Name is the resolver for the name field.
|
||||||
func (r *metricValueResolver) Name(ctx context.Context, obj *schema.MetricValue) (*string, error) {
|
func (r *metricValueResolver) Name(ctx context.Context, obj *schema.MetricValue) (*string, error) {
|
||||||
panic(fmt.Errorf("not implemented: Name - name"))
|
panic(fmt.Errorf("not implemented: Name - name"))
|
||||||
@@ -1054,9 +1064,17 @@ func (r *subClusterResolver) NumberOfNodes(ctx context.Context, obj *schema.SubC
|
|||||||
// Cluster returns generated.ClusterResolver implementation.
|
// Cluster returns generated.ClusterResolver implementation.
|
||||||
func (r *Resolver) Cluster() generated.ClusterResolver { return &clusterResolver{r} }
|
func (r *Resolver) Cluster() generated.ClusterResolver { return &clusterResolver{r} }
|
||||||
|
|
||||||
|
// GlobalMetricListItem returns generated.GlobalMetricListItemResolver implementation.
|
||||||
|
func (r *Resolver) GlobalMetricListItem() generated.GlobalMetricListItemResolver {
|
||||||
|
return &globalMetricListItemResolver{r}
|
||||||
|
}
|
||||||
|
|
||||||
// Job returns generated.JobResolver implementation.
|
// Job returns generated.JobResolver implementation.
|
||||||
func (r *Resolver) Job() generated.JobResolver { return &jobResolver{r} }
|
func (r *Resolver) Job() generated.JobResolver { return &jobResolver{r} }
|
||||||
|
|
||||||
|
// MetricConfig returns generated.MetricConfigResolver implementation.
|
||||||
|
func (r *Resolver) MetricConfig() generated.MetricConfigResolver { return &metricConfigResolver{r} }
|
||||||
|
|
||||||
// MetricValue returns generated.MetricValueResolver implementation.
|
// MetricValue returns generated.MetricValueResolver implementation.
|
||||||
func (r *Resolver) MetricValue() generated.MetricValueResolver { return &metricValueResolver{r} }
|
func (r *Resolver) MetricValue() generated.MetricValueResolver { return &metricValueResolver{r} }
|
||||||
|
|
||||||
@@ -1073,7 +1091,9 @@ func (r *Resolver) Query() generated.QueryResolver { return &queryResolver{r} }
|
|||||||
func (r *Resolver) SubCluster() generated.SubClusterResolver { return &subClusterResolver{r} }
|
func (r *Resolver) SubCluster() generated.SubClusterResolver { return &subClusterResolver{r} }
|
||||||
|
|
||||||
type clusterResolver struct{ *Resolver }
|
type clusterResolver struct{ *Resolver }
|
||||||
|
type globalMetricListItemResolver struct{ *Resolver }
|
||||||
type jobResolver struct{ *Resolver }
|
type jobResolver struct{ *Resolver }
|
||||||
|
type metricConfigResolver struct{ *Resolver }
|
||||||
type metricValueResolver struct{ *Resolver }
|
type metricValueResolver struct{ *Resolver }
|
||||||
type mutationResolver struct{ *Resolver }
|
type mutationResolver struct{ *Resolver }
|
||||||
type nodeResolver struct{ *Resolver }
|
type nodeResolver struct{ *Resolver }
|
||||||
|
|||||||
@@ -63,8 +63,11 @@ func initClusterConfig() error {
|
|||||||
|
|
||||||
if _, ok := metricLookup[mc.Name]; !ok {
|
if _, ok := metricLookup[mc.Name]; !ok {
|
||||||
metricLookup[mc.Name] = schema.GlobalMetricListItem{
|
metricLookup[mc.Name] = schema.GlobalMetricListItem{
|
||||||
Name: mc.Name, Scope: mc.Scope, Unit: mc.Unit, Footprint: mc.Footprint,
|
Name: mc.Name, Scope: mc.Scope, Unit: mc.Unit, Footprint: mc.Footprint, Tooltip: mc.Tooltip,
|
||||||
}
|
}
|
||||||
|
} else if item := metricLookup[mc.Name]; item.Tooltip == "" && mc.Tooltip != "" {
|
||||||
|
item.Tooltip = mc.Tooltip
|
||||||
|
metricLookup[mc.Name] = item
|
||||||
}
|
}
|
||||||
|
|
||||||
availability := schema.ClusterSupport{Cluster: cluster.Name}
|
availability := schema.ClusterSupport{Cluster: cluster.Name}
|
||||||
@@ -139,8 +142,10 @@ func initClusterConfig() error {
|
|||||||
userItem, ok := userMetricLookup[mc.Name]
|
userItem, ok := userMetricLookup[mc.Name]
|
||||||
if !ok {
|
if !ok {
|
||||||
userItem = schema.GlobalMetricListItem{
|
userItem = schema.GlobalMetricListItem{
|
||||||
Name: mc.Name, Scope: mc.Scope, Unit: mc.Unit, Footprint: mc.Footprint,
|
Name: mc.Name, Scope: mc.Scope, Unit: mc.Unit, Footprint: mc.Footprint, Tooltip: mc.Tooltip,
|
||||||
}
|
}
|
||||||
|
} else if userItem.Tooltip == "" && mc.Tooltip != "" {
|
||||||
|
userItem.Tooltip = mc.Tooltip
|
||||||
}
|
}
|
||||||
userItem.Availability = append(userItem.Availability, userAvailability)
|
userItem.Availability = append(userItem.Availability, userAvailability)
|
||||||
userMetricLookup[mc.Name] = userItem
|
userMetricLookup[mc.Name] = userItem
|
||||||
|
|||||||
@@ -60,6 +60,8 @@
|
|||||||
let presetProject = $derived(filterPresets?.project ? filterPresets.project : "");
|
let presetProject = $derived(filterPresets?.project ? filterPresets.project : "");
|
||||||
let selectedCluster = $derived(filterPresets?.cluster ? filterPresets.cluster : null);
|
let selectedCluster = $derived(filterPresets?.cluster ? filterPresets.cluster : null);
|
||||||
let selectedSubCluster = $derived(filterPresets?.partition ? filterPresets.partition : null);
|
let selectedSubCluster = $derived(filterPresets?.partition ? filterPresets.partition : null);
|
||||||
|
const maxClusters = $derived($initq?.data?.clusters?.length || 0);
|
||||||
|
const maxSubClusters = $derived($initq?.data?.clusters?.find((c) => c.name == selectedCluster)?.subClusters?.length || 0);
|
||||||
let metrics = $derived.by(() => {
|
let metrics = $derived.by(() => {
|
||||||
if (thisInit && ccconfig) {
|
if (thisInit && ccconfig) {
|
||||||
if (selectedCluster) {
|
if (selectedCluster) {
|
||||||
@@ -243,6 +245,8 @@
|
|||||||
presetMetrics={metrics}
|
presetMetrics={metrics}
|
||||||
cluster={selectedCluster}
|
cluster={selectedCluster}
|
||||||
subCluster={selectedSubCluster}
|
subCluster={selectedSubCluster}
|
||||||
|
{maxClusters}
|
||||||
|
{maxSubClusters}
|
||||||
configName="metricConfig_jobListMetrics"
|
configName="metricConfig_jobListMetrics"
|
||||||
footprintSelect
|
footprintSelect
|
||||||
{globalMetrics}
|
{globalMetrics}
|
||||||
|
|||||||
@@ -63,8 +63,9 @@
|
|||||||
let pendingHostnameFilter = $state("");
|
let pendingHostnameFilter = $state("");
|
||||||
let isMetricsSelectionOpen = $state(false);
|
let isMetricsSelectionOpen = $state(false);
|
||||||
|
|
||||||
/* Derived Init Return */
|
/* Derived Init Returns */
|
||||||
const thisInit = $derived($initq?.data ? true : false);
|
const thisInit = $derived($initq?.data ? true : false);
|
||||||
|
const maxSubClusters = $derived($initq?.data?.clusters?.find((c) => c.name == cluster)?.subClusters?.length || 0);
|
||||||
|
|
||||||
/* Derived States */
|
/* Derived States */
|
||||||
const ccconfig = $derived(thisInit ? getContext("cc-config") : null);
|
const ccconfig = $derived(thisInit ? getContext("cc-config") : null);
|
||||||
@@ -284,6 +285,7 @@
|
|||||||
{cluster}
|
{cluster}
|
||||||
{subCluster}
|
{subCluster}
|
||||||
{globalMetrics}
|
{globalMetrics}
|
||||||
|
maxSubClusters={subCluster? null: maxSubClusters}
|
||||||
configName="nodeList_selectedMetrics"
|
configName="nodeList_selectedMetrics"
|
||||||
applyMetrics={(newMetrics) =>
|
applyMetrics={(newMetrics) =>
|
||||||
selectedMetrics = [...newMetrics]
|
selectedMetrics = [...newMetrics]
|
||||||
|
|||||||
@@ -90,6 +90,8 @@
|
|||||||
const shortDuration = $derived(ccconfig?.jobList_hideShortRunningJobs);
|
const shortDuration = $derived(ccconfig?.jobList_hideShortRunningJobs);
|
||||||
let selectedCluster = $derived(filterPresets?.cluster ? filterPresets.cluster : null);
|
let selectedCluster = $derived(filterPresets?.cluster ? filterPresets.cluster : null);
|
||||||
let selectedSubCluster = $derived(filterPresets?.partition ? filterPresets.partition : null);
|
let selectedSubCluster = $derived(filterPresets?.partition ? filterPresets.partition : null);
|
||||||
|
const maxClusters = $derived($initq?.data?.clusters?.length || 0);
|
||||||
|
const maxSubClusters = $derived($initq?.data?.clusters?.find((c) => c.name == selectedCluster)?.subClusters?.length || 0);
|
||||||
let metrics = $derived.by(() => {
|
let metrics = $derived.by(() => {
|
||||||
if (thisInit && ccconfig) {
|
if (thisInit && ccconfig) {
|
||||||
if (selectedCluster) {
|
if (selectedCluster) {
|
||||||
@@ -531,6 +533,8 @@
|
|||||||
presetMetrics={metrics}
|
presetMetrics={metrics}
|
||||||
cluster={selectedCluster}
|
cluster={selectedCluster}
|
||||||
subCluster={selectedSubCluster}
|
subCluster={selectedSubCluster}
|
||||||
|
{maxClusters}
|
||||||
|
{maxSubClusters}
|
||||||
configName="metricConfig_jobListMetrics"
|
configName="metricConfig_jobListMetrics"
|
||||||
footprintSelect
|
footprintSelect
|
||||||
{globalMetrics}
|
{globalMetrics}
|
||||||
|
|||||||
@@ -22,6 +22,8 @@
|
|||||||
ModalFooter,
|
ModalFooter,
|
||||||
Button,
|
Button,
|
||||||
ListGroup,
|
ListGroup,
|
||||||
|
Icon,
|
||||||
|
Tooltip
|
||||||
} from "@sveltestrap/sveltestrap";
|
} from "@sveltestrap/sveltestrap";
|
||||||
import { gql, getContextClient, mutationStore } from "@urql/svelte";
|
import { gql, getContextClient, mutationStore } from "@urql/svelte";
|
||||||
|
|
||||||
@@ -33,6 +35,8 @@
|
|||||||
presetMetrics = [],
|
presetMetrics = [],
|
||||||
cluster = null,
|
cluster = null,
|
||||||
subCluster = null,
|
subCluster = null,
|
||||||
|
maxClusters = null,
|
||||||
|
maxSubClusters = null,
|
||||||
footprintSelect = false,
|
footprintSelect = false,
|
||||||
configName,
|
configName,
|
||||||
globalMetrics,
|
globalMetrics,
|
||||||
@@ -86,20 +90,47 @@
|
|||||||
return availableMetrics;
|
return availableMetrics;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function printAvailabilityCount(metric, cluster) {
|
||||||
|
const avail = globalMetrics.find((gm) => gm.name === metric)?.availability
|
||||||
|
if (avail) {
|
||||||
|
if (!cluster) {
|
||||||
|
return `${avail.length} / ${maxClusters} Cluster`
|
||||||
|
} else {
|
||||||
|
const subAvail = avail.find((av) => av.cluster === cluster)?.subClusters
|
||||||
|
if (subAvail) {
|
||||||
|
return `${subAvail.length} / ${maxSubClusters} SubCluster`
|
||||||
|
} else {
|
||||||
|
return `0 / ${maxSubClusters} SubCluster`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return `0 / ${maxClusters} Cluster`
|
||||||
|
}
|
||||||
|
|
||||||
function printAvailability(metric, cluster) {
|
function printAvailability(metric, cluster) {
|
||||||
const avail = globalMetrics.find((gm) => gm.name === metric)?.availability
|
const avail = globalMetrics.find((gm) => gm.name === metric)?.availability
|
||||||
if (avail) {
|
if (avail) {
|
||||||
if (!cluster) {
|
if (!cluster) {
|
||||||
return avail.map((av) => av.cluster).join(', ')
|
console.log(metric, avail.map((av) => av.cluster))
|
||||||
|
return avail.map((av) => av.cluster)
|
||||||
} else {
|
} else {
|
||||||
const subAvail = avail.find((av) => av.cluster === cluster)?.subClusters
|
const subAvail = avail.find((av) => av.cluster === cluster)?.subClusters
|
||||||
if (subAvail) {
|
if (subAvail) {
|
||||||
return subAvail.join(', ')
|
console.log(metric, subAvail)
|
||||||
|
return subAvail
|
||||||
} else {
|
} else {
|
||||||
return `Not available for ${cluster}`
|
return [`Not available for ${cluster}`]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return [`Not available for ${cluster}`]
|
||||||
|
}
|
||||||
|
|
||||||
|
function printTooltip(metric) {
|
||||||
|
const toolt = globalMetrics.find((gm) => gm.name === metric)?.tooltip
|
||||||
|
if (toolt) {
|
||||||
|
return toolt
|
||||||
|
}
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -172,7 +203,7 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Modal {isOpen} toggle={() => (isOpen = !isOpen)}>
|
<Modal {isOpen} toggle={() => (isOpen = !isOpen)}>
|
||||||
<ModalHeader>Configure columns (Metric availability shown)</ModalHeader>
|
<ModalHeader>Configure columns</ModalHeader>
|
||||||
<ModalBody>
|
<ModalBody>
|
||||||
<ListGroup>
|
<ListGroup>
|
||||||
{#if footprintSelect}
|
{#if footprintSelect}
|
||||||
@@ -213,9 +244,34 @@
|
|||||||
/>
|
/>
|
||||||
{/if}
|
{/if}
|
||||||
{metric}
|
{metric}
|
||||||
<span style="float: right; text-align: justify;">
|
{#if maxClusters !== null || maxSubClusters !== null}
|
||||||
{printAvailability(metric, cluster)}
|
<span style="float: right;" class="ms-1">
|
||||||
|
<Button id={`${metric}-avail-info`} outline color="secondary" size="sm" class="ml-2">
|
||||||
|
<b>{ printAvailabilityCount(metric, cluster) }</b>
|
||||||
|
</Button>
|
||||||
|
<Tooltip target={`${metric}-avail-info`} placement="right">
|
||||||
|
<b>Availability</b>
|
||||||
|
<ul style="text-align: left; padding-left: 1.0rem; margin-bottom: 0.25rem;">
|
||||||
|
{#each printAvailability(metric, cluster) as avail}
|
||||||
|
<li>{avail}</li>
|
||||||
|
{/each}
|
||||||
|
</ul>
|
||||||
|
</Tooltip>
|
||||||
</span>
|
</span>
|
||||||
|
{/if}
|
||||||
|
{#if printTooltip(metric) !== ""}
|
||||||
|
<span style="float: right;">
|
||||||
|
<Button id={`${metric}-kind-info`} outline color="secondary" size="sm" class="ml-2">
|
||||||
|
<Icon name="info-square" />
|
||||||
|
</Button>
|
||||||
|
<Tooltip target={`${metric}-kind-info`} placement="right">
|
||||||
|
<b>Information</b>
|
||||||
|
<p style="text-align: left; margin-bottom: 0.25rem;">
|
||||||
|
{ printTooltip(metric) }
|
||||||
|
</p>
|
||||||
|
</Tooltip>
|
||||||
|
</span>
|
||||||
|
{/if}
|
||||||
</li>
|
</li>
|
||||||
{/each}
|
{/each}
|
||||||
</ListGroup>
|
</ListGroup>
|
||||||
|
|||||||
@@ -81,6 +81,7 @@ export function init(extraInitQuery = "") {
|
|||||||
name
|
name
|
||||||
scope
|
scope
|
||||||
footprint
|
footprint
|
||||||
|
tooltip
|
||||||
unit { base, prefix }
|
unit { base, prefix }
|
||||||
availability { cluster, subClusters }
|
availability { cluster, subClusters }
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user