New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add operators status to Dashboards #3755
Add operators status to Dashboards #3755
Conversation
9f20b2f
to
e90f256
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking awesome to me. 🎉
I notice that "InstallSucceeded" matches what appears in the Installed Operators List page, but the Details page for a given operator/CSV shows the status as "Succeeded" instead.
I'd probably expect/prefer to see "Succeeded" in this popover, but I'm not sure which one is correct. Is one coming from status.reason
and the other from status.phase
in the CSV? FYI @itsptk
}) => ( | ||
<> | ||
<div className="co-operator-section"> | ||
Operators extend Kubernetes with additional custom resources to manage applications |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Operators extend Kubernetes with additional custom resources to manage applications | |
Operators extend OpenShift with additional custom resources to manage applications. |
Added a period and switched to "OpenShift". We might want to validate the language here with an SME.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@dmesser @tlwu2013 I spoke with @alecmerdler and he mentioned we are transforming this CSV status in the Installed Operator details to show as just "Succeeded." Could that be appropriate here as well? This is a roll-up status of all the CSVs' statuses for an operator across namespaces, showing the "worst" status.
f0a4be6
to
d924a91
Compare
d924a91
to
c35bfae
Compare
I think my inclination would be to continue to gather the operator status from reason and just transform the string in the status card (similar to the installed operator details.) Changing where this status is gathered from is a bigger change and would need more consideration. |
CSV details page is using |
|
For the "Degraded" and "Upgrading" sublabels, would we be able to show a count of how many are degraded/upgrading like |
@rawagner I shared the original design at a UX meeting earlier today and got some great feedback about the all-okay state. I haven't gotten feedback on this design tweak yet, but here it is for reference: Instead of showing the first 5 alphabetical operators that are all "Succeeded" in each section (which is somewhat arbitrary, distracting, and doesn't confirm that all the other operators are healthy) we'd show a collapsed "All succeeded" (or whatever it ends up being) status with the same "View all" link on the left. Sorry for the mid-PR change, just trying to keep up with you. 🙂 |
Spoke with @tlwu2013 , we agreed that this popover should be using status.phase, since thats what the user would see in the the operator details if they clicked the operator name in popover. We didn't want to change the operator list view status at this time, as that is being actively reworked in https://jira.coreos.com/browse/PD-275 |
62fc88d
to
910a506
Compare
|
||
/** | ||
* Link to all resources page. | ||
* If not provided than list page of first resource from resources prop is used. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
* If not provided than list page of first resource from resources prop is used. | |
* If not provided then a list page of first resource from resources prop is used. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
/** | ||
* Link to all resources page. | ||
* If not provided than list page of first resource from resources prop is used. | ||
* */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
* */ | |
*/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
const operatorStatuses = getOperatorsWithStatuses(resources); | ||
const sortedOperatorStatuses = getMostImportantStatuses(operatorStatuses) | ||
.sort((a, b) => a.operators[0].metadata.name.localeCompare(b.operators[0].metadata.name)) | ||
.slice(0, 5); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are we limiting displayed operator statuses to a total of 5 by design?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, max 5 is by design
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm, thinking about this again, maybe we should reconsider and show all degraded/failed operators in the popover rather than just the first alphabetical 5 (which is arbitrary). I think that would be more useful.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, limit is now removed
) : ( | ||
!operatorsHealthy && | ||
sortedOperatorStatuses.map((operatorStatus) => ( | ||
<AsyncComponent |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
operators: [], | ||
}; | ||
} | ||
const operatorsByStatus: { [key: string]: OperatorStatusWithResources<R> } = operators.reduce<{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd prefer the alternative way, which types the accumulator value
const operatorsByStatus = operators.reduce(
(acc, o) => {
// ..
},
{} as { [key: string]: OperatorStatusWithResources<R> },
);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
doing
{} as { [key: string]: OperatorStatusWithResources<R> }
throws error
Type assertion on object literals is forbidden, use a type annotation instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is that an ESLint rule? It shouldn't do any harm on empty objects 😃 oh well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, eslint rule eslint(@typescript-eslint/no-object-literal-type-assertion)
:)
}, | ||
}; | ||
|
||
type HealthStateMappingKeys = Exclude<keyof typeof HealthState, 'LOADING'>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
], | ||
getOperatorsWithStatuses: getClusterServiceVersionsWithStatuses, | ||
operatorRowLoader: () => | ||
import( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's stay consistent in how we use dynamic imports within this specific module:
loader: async () =>
(await import('./components/dashboard/csv-status' /* webpackChunkName: "csv-dashboard-status" */))
.default,
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed
status: { | ||
installedCSV: getName(csv), | ||
}, | ||
} as any); // 'as any' to supress typescript error caused by lodash; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can't we use generic type params when calling _.find
function? Using as any
is discouraged.
/> | ||
); | ||
}) | ||
.reverse(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What's the intention behind reversing the sections
array?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we want to have CSV operators before Cluster operators thus we need to reverse the order of extensions (cluster operators are contributed by console app, CSV by operator-lifecycle). We can improve that later on if we will have any more complex cases, like including some extensions before/after others (similar to nav items) but reverse is enough for now
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't it better then to explicitly sort the extensions in a way that Cluster operators come before any other ones?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A better solution IMO is to add e.g. priority
property to allow sorting extensions in a specific way when they are consumed.
For now, I'm OK with a simple reverse
.
export type AsyncComponentProps = { | ||
loader: () => Promise<React.ComponentType>; | ||
LoadingComponent?: React.ReactNode; | ||
} & any; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can improve that later, but I'd encourage not to use type Foo = xxx & any
in new code, just like with as any
type cast.
8e33ab1
to
f8b9b47
Compare
f8b9b47
to
ad46355
Compare
ad46355
to
754cc33
Compare
754cc33
to
e8db4b9
Compare
/lgtm |
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: jeff-phillips-18, rawagner, vojtechszocs The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
depends on #3754