Skip to content

Commit

Permalink
Merge #45143 #45426
Browse files Browse the repository at this point in the history
45143: ui: Release notes signup r=dhartunian a=koorosh

Resolves: #43912
Depends on: #44744, #44821, #44856 

- [x] WIP. Current branch has two branches merged which haven't been approved/merged in master branch yet.

- [x] rebase branch to remove merge commits from branches other than master.

Add Release notes signup form to Cluster Overview page
right after page title.
Release Notes signup view is created in `src/views/dashboard`
directory because it will be the main page where we display
this view. And Cluster Overview page is a temporary place
while Dashboard view doesn't exist.

These changes integrate three main parts: ReleaseNotesForm,
AlertNotification component and custom analytics saga.



45426: coldata: minor tweak of flat bytes r=yuzefovich a=yuzefovich

This commit changes `maybeBackfillOffsets` to update `maxSetIndex`
accordingly (this might be a minor performance improvement). In a sense,
when we're backfilling offsets, we *are* setting indices to point to
empty `[]byte` slices. Also, the logic for `Set` method is slightly
refactored.

Release note: None

Co-authored-by: Andrii Vorobiov <and.vorobiov@gmail.com>
Co-authored-by: Yahor Yuzefovich <yahor@cockroachlabs.com>
  • Loading branch information
3 people committed Feb 28, 2020
3 parents 55c43f6 + 989e097 + c1c1100 commit c778c12
Show file tree
Hide file tree
Showing 9 changed files with 206 additions and 25 deletions.
22 changes: 10 additions & 12 deletions pkg/col/coldata/bytes.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ func (b *Bytes) UpdateOffsetsToBeNonDecreasing(n uint64) {

// maybeBackfillOffsets is an optimized version of
// UpdateOffsetsToBeNonDecreasing that assumes that all offsets up to
// b.maxSetIndex+1 are non-decreasing. Note that this method can be a noop when
// b.maxSetIndex+1 are non-decreasing. Note that this method is a noop when
// i <= b.maxSetIndex+1.
func (b *Bytes) maybeBackfillOffsets(i int) {
// Note that we're not checking whether this Bytes is a window because
Expand All @@ -96,6 +96,9 @@ func (b *Bytes) maybeBackfillOffsets(i int) {
for j := b.maxSetIndex + 2; j <= i; j++ {
b.offsets[j] = b.offsets[b.maxSetIndex+1]
}
if i > b.maxSetIndex {
b.maxSetIndex = i - 1
}
}

// Get returns the ith []byte in Bytes. Note that the returned byte slice is
Expand Down Expand Up @@ -123,17 +126,12 @@ func (b *Bytes) Set(i int, v []byte) {
),
)
}
if i == b.maxSetIndex {
// We are overwriting an element at the end of b.data, truncate so we can
// append in every path.
b.data = b.data[:b.offsets[i]]
} else {
// We're maybe setting an element not right after the last already present
// element (i.e. there might be gaps in b.offsets). This is probably due to
// NULL values that are stored separately. In order to maintain the
// assumption of non-decreasing offsets, we need to backfill them.
b.maybeBackfillOffsets(i)
}
// We're maybe setting an element not right after the last already present
// element (i.e. there might be gaps in b.offsets). This is probably due to
// NULL values that are stored separately. In order to maintain the
// assumption of non-decreasing offsets, we need to backfill them.
b.maybeBackfillOffsets(i)
b.data = b.data[:b.offsets[i]]
b.offsets[i] = int32(len(b.data))
b.data = append(b.data, v...)
b.offsets[i+1] = int32(len(b.data))
Expand Down
22 changes: 22 additions & 0 deletions pkg/ui/assets/dashboard/email_signup_background.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions pkg/ui/src/components/core/typography.styl
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ $font-family--bold = SourceSansPro-Bold
$font-family--semi-bold = SourceSansPro-SemiBold
$font-family--monospace = SFMono

$font-weight--extra-bold = 900
$font-weight--bold = 600
$font-weight--medium = 500
$font-weight--light = 400
Expand Down
2 changes: 0 additions & 2 deletions pkg/ui/src/redux/customAnalytics/customAnalyticsSagas.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import Analytics from "analytics-node";

import { signUpEmailSubscription } from "./customAnalyticsSagas";
import {
completeEmailSubscriptionSignUp,
signUpForEmailSubscription,
} from "./customAnanlyticsActions";

Expand All @@ -33,7 +32,6 @@ describe("customAnalyticsSagas", () => {
const action = signUpForEmailSubscription(clusterId, email);

return expectSaga(signUpEmailSubscription, action)
.put(completeEmailSubscriptionSignUp())
.dispatch(action)
.run()
.then(() => {
Expand Down
7 changes: 5 additions & 2 deletions pkg/ui/src/redux/customAnalytics/customAnalyticsSagas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ import Analytics from "analytics-node";

import { PayloadAction } from "src/interfaces/action";
import { COCKROACHLABS_ADDR } from "src/util/cockroachlabsAPI";
import { emailSubscriptionAlertLocalSetting } from "src/redux/alerts";

import {
completeEmailSubscriptionSignUp,
EMAIL_SUBSCRIPTION_SIGN_UP,
EmailSubscriptionSignUpPayload,
} from "./customAnanlyticsActions";
Expand Down Expand Up @@ -44,9 +45,11 @@ export function* signUpEmailSubscription(action: PayloadAction<EmailSubscription
userId: clusterId,
traits: {
email,
release_notes_sign_up_from_admin_ui: "true",
product_updates: "true",
},
});
yield put(completeEmailSubscriptionSignUp());
yield put(emailSubscriptionAlertLocalSetting.set(true));
}

export function* customAnalyticsSaga() {
Expand Down
9 changes: 0 additions & 9 deletions pkg/ui/src/redux/customAnalytics/customAnanlyticsActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,9 @@
// by the Apache License, Version 2.0, included in the file
// licenses/APL.txt.

import { Action } from "redux";

import { PayloadAction } from "src/interfaces/action";

export const EMAIL_SUBSCRIPTION_SIGN_UP = "cockroachui/customanalytics/EMAIL_SUBSCRIPTION_SIGN_UP";
export const EMAIL_SUBSCRIPTION_SIGN_UP_COMPLETE = "cockroachui/customanalytics/EMAIL_SUBSCRIPTION_SIGN_UP_COMPLETE";

export type EmailSubscriptionSignUpPayload = {
email: string;
Expand All @@ -29,9 +26,3 @@ export function signUpForEmailSubscription(clusterId: string, email: string): Pa
},
};
}

export function completeEmailSubscriptionSignUp(): Action {
return {
type: EMAIL_SUBSCRIPTION_SIGN_UP_COMPLETE,
};
}
2 changes: 2 additions & 0 deletions pkg/ui/src/views/cluster/containers/clusterOverview/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import createChartComponent from "src/views/shared/util/d3-react";
import capacityChart from "./capacity";
import spinner from "assets/spinner.gif";
import { refreshNodes, refreshLiveness } from "src/redux/apiReducers";
import EmailSubscription from "src/views/dashboard/emailSubscription";
import "./cluster.styl";

// tslint:disable-next-line:variable-name
Expand Down Expand Up @@ -217,6 +218,7 @@ export default class ClusterOverview extends React.Component<any, any> {
return (
<div className="cluster-page">
<Helmet title="Cluster Overview" />
<EmailSubscription />
<section className="cluster-overview">
<ClusterSummaryConnected />
</section>
Expand Down
79 changes: 79 additions & 0 deletions pkg/ui/src/views/dashboard/emailSubscription.styl
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
// Copyright 2020 The Cockroach Authors.
//
// Use of this software is governed by the Business Source License
// included in the file licenses/BSL.txt.
//
// As of the Change Date specified in that file, in accordance with
// the Business Source License, use of this software will be governed
// by the Apache License, Version 2.0, included in the file
// licenses/APL.txt.

@require '~src/components/core/index.styl'

$text-width = 352px

.crl-email-subscription
border-radius 5px
box-shadow: 0 0 1px 0 rgba(67, 90, 111, 0.41)
display flex
flex-direction row
align-items center
justify-content flex-end
height 90px
background-color $colors--white
background-image url("../../../assets/dashboard/email_signup_background.svg")
background-repeat no-repeat
background-position-x $text-width

&__text
font-size $font-size--large
font-family $font-family--base
line-height 1.6
letter-spacing -0.2px
color $colors--white
flex-grow 1
height inherit
border-radius inherit
& > div
max-width $text-width
background $colors--primary-green-3
padding-left $spacing-large
height inherit
border-bottom-left-radius: inherit;
border-top-left-radius: inherit;
display flex
align-items center


&__controls
flex-grow 0
margin-left $spacing-medium

&__close-button
flex-grow 0
color $colors--neutral-7
align-self flex-start
margin $spacing-smaller $spacing-small $spacing-small $spacing-medium
cursor pointer
font-size $font-size--large
line-height $spacing-smaller
font-weight $font-weight--extra-bold


@media (max-width: 1055px) {
background-position center

.crl-email-subscription__text {
font-size $font-size--tall
font-family $font-family--base
line-height 1.6
}
}

@media (max-width: 940px) {
background-position left

.crl-email-subscription__text {
display none
}
}
87 changes: 87 additions & 0 deletions pkg/ui/src/views/dashboard/emailSubscription.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
// Copyright 2020 The Cockroach Authors.
//
// Use of this software is governed by the Business Source License
// included in the file licenses/BSL.txt.
//
// As of the Change Date specified in that file, in accordance with
// the Business Source License, use of this software will be governed
// by the Apache License, Version 2.0, included in the file
// licenses/APL.txt.

import React from "react";
import { connect } from "react-redux";

import { EmailSubscriptionForm } from "src/views/shared/components/emailSubscriptionForm";
import { signUpForEmailSubscription } from "src/redux/customAnalytics";
import { AdminUIState } from "src/redux/state";
import { clusterIdSelector } from "src/redux/nodes";
import { LocalSetting } from "src/redux/localsettings";

import "./emailSubscription.styl";

type EmailSubscriptionProps = MapDispatchToProps & MapStateToProps;

class EmailSubscription extends React.Component<EmailSubscriptionProps> {
handleEmailSubscriptionSubmit = (email: string) => {
this.props.signUpForEmailSubscription(this.props.clusterId, email);
}

handlePanelHide = () => {
this.props.hidePanel();
}

render() {
const { isHiddenPanel } = this.props;

if (isHiddenPanel) {
return null;
}

return (
<section className="section">
<div className="crl-email-subscription">
<div className="crl-email-subscription__text">
<div>
Keep up-to-date with CockroachDB
software releases and best practices.
</div>
</div>
<div className="crl-email-subscription__controls">
<EmailSubscriptionForm onSubmit={this.handleEmailSubscriptionSubmit} />
</div>
<div
onClick={this.handlePanelHide}
className="crl-email-subscription__close-button"
>
&times;
</div>
</div>
</section>
);
}
}

const hidePanelLocalSetting = new LocalSetting<AdminUIState, boolean>(
"dashboard/release_notes_signup/hide", (s) => s.localSettings, false,
);

interface MapDispatchToProps {
signUpForEmailSubscription: (clusterId: string, email: string) => void;
hidePanel: () => void;
}

const mapDispatchToProps = {
signUpForEmailSubscription,
hidePanel: () => hidePanelLocalSetting.set(true),
};

interface MapStateToProps {
isHiddenPanel: boolean;
clusterId: string;
}
const mapStateToProps = (state: AdminUIState) => ({
isHiddenPanel: hidePanelLocalSetting.selector(state),
clusterId: clusterIdSelector(state),
});

export default connect(mapStateToProps, mapDispatchToProps)(EmailSubscription);

0 comments on commit c778c12

Please sign in to comment.