Skip to content
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

feat: add cluster-wide message #9261

Merged
merged 34 commits into from
Jun 12, 2024
Merged

feat: add cluster-wide message #9261

merged 34 commits into from
Jun 12, 2024

Conversation

maxrussell
Copy link
Contributor

@maxrussell maxrussell commented Apr 27, 2024

Ticket

DET-10228 DET-10227 DET-10168 DET-9994

Description

Admin users should be able to set a cluster-wide message that is displayed to all users for things like server maintenance.

Test Plan

This should be tested manually in Release Party; here are the acceptance criteria:

  • Non-admins should not be able to set the cluster message or use the det master cluster-message get CLI command (since the latter can show not-yet-active cluster messages).
  • Admins should be able to set the cluster message, and it should show up in the Web UI for all users.
  • Start and end time should work
    • Messages should be able to be scheduled in the future and only show up when the start time has been reached
    • Messages should end after the end time and no longer show up in det master info
  • --duration should work
  • Cluster message banner should disappear within a minute or two after the message expires.
  • If the browser is too narrow to fit the full text of the cluster message, its text should be truncated with an ellipsis (...) rather than make the banner taller to add lines.
  • The cluster message banner being present should not cause layout problems
    • It is a known issue that resizing the browser intermittently causes extra scrollbars to appear. Reloading the page should cause these to go away.

Checklist

  • Acceptance testing completed with PM (@hkumar92)
  • Changes have been manually QA'd
  • User-facing API changes need the "User-facing API Change" label.
  • Release notes should be added as a separate file under docs/release-notes/.
    See Release Note for details.

@cla-bot cla-bot bot added the cla-signed label Apr 27, 2024
Copy link

netlify bot commented Apr 27, 2024

Deploy Preview for determined-ui ready!

Name Link
🔨 Latest commit 4ffeadf
🔍 Latest deploy log https://app.netlify.com/sites/determined-ui/deploys/6668e192d5cc4d0008915abb
😎 Deploy Preview https://deploy-preview-9261--determined-ui.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site configuration.

@maxrussell maxrussell force-pushed the max/maint-msg-fresh branch 2 times, most recently from 01cd526 to 3658f57 Compare May 7, 2024 23:23
@tara-det-ai tara-det-ai self-requested a review May 15, 2024 20:25
Copy link

codecov bot commented May 15, 2024

Codecov Report

Attention: Patch coverage is 37.92049% with 203 lines in your changes missing coverage. Please review.

Project coverage is 48.97%. Comparing base (439734b) to head (4ffeadf).
Report is 3 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #9261      +/-   ##
==========================================
- Coverage   49.00%   48.97%   -0.03%     
==========================================
  Files        1235     1238       +3     
  Lines      160191   160507     +316     
  Branches     2781     2784       +3     
==========================================
+ Hits        78494    78604     +110     
- Misses      81522    81728     +206     
  Partials      175      175              
Flag Coverage Δ
backend 43.81% <41.55%> (-0.04%) ⬇️
harness 63.85% <25.00%> (-0.11%) ⬇️
web 44.13% <52.45%> (+0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files Coverage Δ
webui/react/src/components/ClusterMessage.tsx 100.00% <100.00%> (ø)
webui/react/src/stores/determinedInfo.tsx 86.02% <100.00%> (+1.49%) ⬆️
master/internal/db/postgres_clustermessage.go 94.11% <94.11%> (ø)
webui/react/src/App.tsx 0.00% <0.00%> (ø)
master/pkg/model/maintenance_message.go 0.00% <0.00%> (ø)
webui/react/src/components/Navigation.tsx 0.00% <0.00%> (ø)
webui/react/src/services/decoder.ts 20.13% <6.66%> (-0.32%) ⬇️
harness/determined/cli/master.py 23.52% <19.04%> (-2.01%) ⬇️
harness/determined/common/api/bindings.py 40.23% <26.37%> (-0.12%) ⬇️
master/internal/api_master.go 2.38% <0.00%> (-1.30%) ⬇️

... and 5 files with indirect coverage changes

@determined-ci determined-ci requested a review from a team May 16, 2024 21:54
@determined-ci determined-ci added the documentation Improvements or additions to documentation label May 16, 2024
@determined-ci determined-ci removed the documentation Improvements or additions to documentation label May 20, 2024
@tara-det-ai tara-det-ai mentioned this pull request May 20, 2024
4 tasks
@determined-ci determined-ci added the documentation Improvements or additions to documentation label Jun 4, 2024
Copy link
Member

@tara-det-ai tara-det-ai left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

requested edits

@determined-ci determined-ci requested a review from a team June 6, 2024 18:52
@maxrussell maxrussell changed the title draft: feat: add cluster-wide message feat: add cluster-wide message Jun 8, 2024
@maxrussell maxrussell marked this pull request as ready for review June 8, 2024 00:59
@maxrussell maxrussell requested review from a team as code owners June 8, 2024 00:59
Copy link
Contributor

@azhou-determined azhou-determined left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor comments, otherwise python-side lgtm

Copy link
Contributor

@keita-determined keita-determined left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added few comments but pretty good shape

also, i think this needs to be tested in release party even though there are test cases especially for webui because the test cases don't handle the entire webui layout, and its good to have human eyes on it (webui is buggy in general...)

@@ -2,6 +2,6 @@
background-color: var(--theme-background);
display: flex;
flex-direction: column;
height: 100%;
max-height: 90vh;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

qq: do we need this change?

webui/react/src/components/ClusterMessage.tsx Show resolved Hide resolved
message?: ClusterMessage;
}

const ClusterMessageBanner: React.FC<Props> = ({ message }) => {
Copy link
Contributor

@keita-determined keita-determined Jun 11, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

refactor

diff --git a/webui/react/src/components/ClusterMessage.module.scss b/webui/react/src/components/ClusterMessage.module.scss
index 5eb3396b72..d9b0284d9f 100644
--- a/webui/react/src/components/ClusterMessage.module.scss
+++ b/webui/react/src/components/ClusterMessage.module.scss
@@ -5,20 +5,21 @@ $height: 40px;
   background-color: #b44;
   color: #ddd;
   display: inline-flex;
+  gap: 4px; // proper value 2px? 4px? 1ch?
   height: $height;
   justify-content: center;
   min-height: $height;
   padding: 0 1em;
   width: 100%;
-}
-.base > * {
-  max-height: 100%; // probably not needed
-  overflow: hidden;
-  text-align: center;
-  text-overflow: ellipsis;
-  white-space: nowrap;
+
+  > span {
+    max-height: 100%;
+    overflow: hidden;
+    text-align: center;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+  }
 }
 .clusterMessageLabel {
   font-weight: bold;
-  width: 60%;
 }
diff --git a/webui/react/src/components/ClusterMessage.tsx b/webui/react/src/components/ClusterMessage.tsx
index 9825445058..fa5e9c5a3d 100644
--- a/webui/react/src/components/ClusterMessage.tsx
+++ b/webui/react/src/components/ClusterMessage.tsx
@@ -11,12 +11,10 @@ interface Props {
 const ClusterMessageBanner: React.FC<Props> = ({ message }) => {
   return message ? (
     <div className={css.base}>
-      <span>
-        <span className={css.clusterMessageLabel} data-testid="admin-msg">
-          Message from Admin:
-        </span>{' '}
-        <span data-testid="cluster-msg">{message.message}</span>
+      <span className={css.clusterMessageLabel} data-testid="admin-msg">
+        Message from Admin:
       </span>
+      <span data-testid="cluster-msg">{message.message}</span>
     </div>
   ) : null;
 };

<span className={css.clusterMessageLabel} data-testid="admin-msg">
Message from Admin:
</span>{' '}
<span data-testid="cluster-msg">{message.message}</span>
Copy link
Contributor

@keita-determined keita-determined Jun 11, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

qq: do we wanna show the default string when message.message is empty string?

image

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, good catch. I think we should only show the banner when the message has length > 0.

@@ -16,11 +16,11 @@ import css from './Navigation.module.scss';
import NavigationSideBar from './NavigationSideBar';
import NavigationTabbar from './NavigationTabbar';

interface Props {
children?: React.ReactNode;
interface Props extends PropsWithChildren {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

qq: why do we wanna use PropsWithChildren? i think children is preferable

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That was chosen so we could also pass clusterMessagePresent, which isn't a child. Is there a better way to do that?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

interface Props {
  children?: React.ReactNode;
  isClusterMessagePresent?: boolean;
}

i think this should work

interface Props {
children?: React.ReactNode;
interface Props extends PropsWithChildren {
clusterMessagePresent?: boolean;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
clusterMessagePresent?: boolean;
isClusterMessagePresent?: boolean;

@@ -90,10 +90,24 @@ export const mapV1MasterInfo = (data: Sdk.V1GetMasterResponse): DeterminedInfo =
return acc;
}, BrandingType.Determined);

const clustMsg = data.clusterMessage
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const clustMsg = data.clusterMessage
const clustMsg: ClusterMessage | undefined = data.clusterMessage

@@ -31,7 +31,7 @@
}
}
&.noScroll {
max-height: 100vh;
max-height: 80vh;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

qq: do we need to change this?

@maxrussell maxrussell enabled auto-merge (squash) June 11, 2024 23:58
@maxrussell maxrussell merged commit 86e6b68 into main Jun 12, 2024
81 of 99 checks passed
@maxrussell maxrussell deleted the max/maint-msg-fresh branch June 12, 2024 00:12
expect(screen.getByTestId('cluster-msg')).toBeInTheDocument();

// make sure the cluster message is visible, but the admin msg is not.
expect(screen.getByText(msg)).toBeInTheDocument();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We care about the content as opposed to the element. In this test case we care about the text content as well, os we should add a check for the actual content.
@amandavialva01 @keita-determined

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use testID then get by text inside the test ID element

// only one cluster message is allowed at any time. Messages may be at most ClusterMessageMaxLength
// characters long. Returns a wrapped ErrInvalidInput when input is invalid.
func SetClusterMessage(ctx context.Context, db *bun.DB, msg model.ClusterMessage) error {
if msgLen := utf8.RuneCountInString(msg.Message); msgLen > ClusterMessageMaxLength {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe we could put a 0 check here? @amandavialva01

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cla-signed documentation Improvements or additions to documentation User-facing API Change
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants