diff --git a/client/web/BUILD.bazel b/client/web/BUILD.bazel
index cbbdfc1d113e9..1acc0289f1ae7 100644
--- a/client/web/BUILD.bazel
+++ b/client/web/BUILD.bazel
@@ -1789,8 +1789,8 @@ ts_project(
"src/enterprise/batches/batch-spec/yaml-util.test.ts",
"src/enterprise/batches/detail/BatchChangeDetailsPage.mock.ts",
"src/enterprise/batches/detail/changesets/BatchChangeChangesets.mock.ts",
+ "src/enterprise/batches/mocks.ts",
"src/enterprise/batches/settings/format.test.ts",
- "src/enterprise/batches/settings/mocks.ts",
"src/enterprise/code-monitoring/CodeMonitoringPage.test.tsx",
"src/enterprise/code-monitoring/CreateCodeMonitorPage.test.tsx",
"src/enterprise/code-monitoring/ManageCodeMonitorPage.test.tsx",
diff --git a/client/web/dev/utils/create-js-context.ts b/client/web/dev/utils/create-js-context.ts
index efbe39bd03ae3..1d52cf0cf6973 100644
--- a/client/web/dev/utils/create-js-context.ts
+++ b/client/web/dev/utils/create-js-context.ts
@@ -75,7 +75,6 @@ export const createJsContext = ({ sourcegraphBaseUrl }: { sourcegraphBaseUrl: st
},
embeddingsEnabled: false,
primaryLoginProvidersCount: 5,
- batchChangesRolloutWindows: null,
// Site-config overrides default JS context
...siteConfig,
}
diff --git a/client/web/src/enterprise/batches/DropdownButton.story.tsx b/client/web/src/enterprise/batches/DropdownButton.story.tsx
index 5d759a3f1c72b..2f3da0d718c01 100644
--- a/client/web/src/enterprise/batches/DropdownButton.story.tsx
+++ b/client/web/src/enterprise/batches/DropdownButton.story.tsx
@@ -1,8 +1,13 @@
import { DecoratorFn, Meta, Story } from '@storybook/react'
+import { getDocumentNode } from '@sourcegraph/http-client'
+import { MockedTestProvider } from '@sourcegraph/shared/src/testing/apollo'
+
import { WebStory } from '../../components/WebStory'
+import { BATCH_CHANGES_SITE_CONFIGURATION } from './backend'
import { Action, DropdownButton } from './DropdownButton'
+import { rolloutWindowConfigMockResult, noRolloutWindowMockResult } from './mocks'
// eslint-disable-next-line @typescript-eslint/require-await
const onTrigger = async (onDone: () => void) => onDone()
@@ -33,6 +38,15 @@ const experimentalAction: Action = {
experimental: true,
}
+const publishAction: Action = {
+ type: 'publish',
+ buttonLabel: 'Publish Changeset',
+ dropdownTitle: 'Publish Changeset',
+ dropdownDescription: 'Attempt to publish all changesets to the code hosts.',
+ onTrigger,
+ experimental: false,
+}
+
const decorator: DecoratorFn = story =>
{story()}
const config: Meta = {
@@ -64,15 +78,64 @@ export const SingleAction: Story = args => {() => (
- {() => }
+
+ {() => (
+
+
+
+ )}
+
)
MultipleActionsWithoutDefault.storyName = 'Multiple actions without default'
export const MultipleActionsWithDefault: Story = args => (
- {() => }
+ {() => (
+
+
+
+ )}
)
MultipleActionsWithDefault.storyName = 'Multiple actions with default'
+
+export const PublishActionWithRolloutWindowConfigured: Story = args => (
+
+ {() => (
+
+
+
+ )}
+
+)
+
+PublishActionWithRolloutWindowConfigured.storyName = 'Publish Action with rollout window configured'
diff --git a/client/web/src/enterprise/batches/DropdownButton.tsx b/client/web/src/enterprise/batches/DropdownButton.tsx
index d64e91974fc5f..fe81562b813eb 100644
--- a/client/web/src/enterprise/batches/DropdownButton.tsx
+++ b/client/web/src/enterprise/batches/DropdownButton.tsx
@@ -18,6 +18,8 @@ import {
Icon,
} from '@sourcegraph/wildcard'
+import { useBatchChangesRolloutWindowConfig } from './backend'
+
import styles from './DropdownButton.module.scss'
export interface Action {
@@ -169,11 +171,11 @@ const DropdownItem: React.FunctionComponent {
+ const { rolloutWindowConfig, loading } = useBatchChangesRolloutWindowConfig()
const onSelect = useCallback(() => {
setSelectedType(action.type)
}, [setSelectedType, action.type])
-
- const { batchChangesRolloutWindows } = window.context
+ const shouldDisplayRolloutInfo = action.type === 'publish' && rolloutWindowConfig && rolloutWindowConfig.length > 0
return (
)
diff --git a/client/web/src/enterprise/batches/backend.ts b/client/web/src/enterprise/batches/backend.ts
index 661fca24b1c58..5e790617cb31c 100644
--- a/client/web/src/enterprise/batches/backend.ts
+++ b/client/web/src/enterprise/batches/backend.ts
@@ -1,8 +1,12 @@
-import { QueryResult } from '@apollo/client'
+import { useMemo } from 'react'
+
+import { ApolloError } from '@apollo/client'
+import * as jsonc from 'jsonc-parser'
import { Observable } from 'rxjs'
import { map } from 'rxjs/operators'
import { dataOrThrowErrors, gql, useQuery } from '@sourcegraph/http-client'
+import { BatchChangeRolloutWindow, SiteConfiguration } from '@sourcegraph/shared/src/schema/site.schema'
import { requestGraphQL } from '../../backend/graphql'
import {
@@ -212,10 +216,27 @@ export const BATCH_CHANGES_SITE_CONFIGURATION = gql`
}
`
-export const useGetBatchChangesSiteConfiguration = (): QueryResult<
- BatchChangesSiteConfigurationResult,
- BatchChangesSiteConfigurationVariables
-> =>
- useQuery(BATCH_CHANGES_SITE_CONFIGURATION, {
+interface useGetBatchChangesSiteConfigurationResult {
+ loading: boolean
+ error: ApolloError | undefined
+ rolloutWindowConfig: BatchChangeRolloutWindow[]
+}
+
+export const useBatchChangesRolloutWindowConfig = (): useGetBatchChangesSiteConfigurationResult => {
+ const { loading, error, data } = useQuery<
+ BatchChangesSiteConfigurationResult,
+ BatchChangesSiteConfigurationVariables
+ >(BATCH_CHANGES_SITE_CONFIGURATION, {
fetchPolicy: 'cache-first',
})
+
+ const rolloutWindowConfig: BatchChangeRolloutWindow[] = useMemo(() => {
+ if (!data) {
+ return []
+ }
+ const siteConfig = jsonc.parse(data.site.configuration.effectiveContents) as SiteConfiguration
+ return siteConfig['batchChanges.rolloutWindows'] || []
+ }, [data])
+
+ return { loading, error, rolloutWindowConfig }
+}
diff --git a/client/web/src/enterprise/batches/settings/mocks.ts b/client/web/src/enterprise/batches/mocks.ts
similarity index 100%
rename from client/web/src/enterprise/batches/settings/mocks.ts
rename to client/web/src/enterprise/batches/mocks.ts
diff --git a/client/web/src/enterprise/batches/settings/BatchChangesSettingsArea.story.tsx b/client/web/src/enterprise/batches/settings/BatchChangesSettingsArea.story.tsx
index 34d1d93156b97..eb8db2559a589 100644
--- a/client/web/src/enterprise/batches/settings/BatchChangesSettingsArea.story.tsx
+++ b/client/web/src/enterprise/batches/settings/BatchChangesSettingsArea.story.tsx
@@ -11,10 +11,10 @@ import {
UserBatchChangesCodeHostsResult,
} from '../../../graphql-operations'
import { BATCH_CHANGES_SITE_CONFIGURATION } from '../backend'
+import { noRolloutWindowMockResult, rolloutWindowConfigMockResult } from '../mocks'
import { USER_CODE_HOSTS } from './backend'
import { BatchChangesSettingsArea } from './BatchChangesSettingsArea'
-import { noRolloutWindowMockResult, rolloutWindowConfigMockResult } from './mocks'
const decorator: DecoratorFn = story => {story()}
diff --git a/client/web/src/enterprise/batches/settings/RolloutWindowsConfiguration.story.tsx b/client/web/src/enterprise/batches/settings/RolloutWindowsConfiguration.story.tsx
index f5a8827a37341..81fae402823ed 100644
--- a/client/web/src/enterprise/batches/settings/RolloutWindowsConfiguration.story.tsx
+++ b/client/web/src/enterprise/batches/settings/RolloutWindowsConfiguration.story.tsx
@@ -5,8 +5,8 @@ import { MockedTestProvider } from '@sourcegraph/shared/src/testing/apollo'
import { WebStory } from '../../../components/WebStory'
import { BATCH_CHANGES_SITE_CONFIGURATION } from '../backend'
+import { noRolloutWindowMockResult, rolloutWindowConfigMockResult } from '../mocks'
-import { noRolloutWindowMockResult, rolloutWindowConfigMockResult } from './mocks'
import { RolloutWindowsConfiguration } from './RolloutWindowsConfiguration'
const decorator: DecoratorFn = story => {story()}
diff --git a/client/web/src/enterprise/batches/settings/RolloutWindowsConfiguration.tsx b/client/web/src/enterprise/batches/settings/RolloutWindowsConfiguration.tsx
index dc5b1470c5c98..31a53a4b5cc1f 100644
--- a/client/web/src/enterprise/batches/settings/RolloutWindowsConfiguration.tsx
+++ b/client/web/src/enterprise/batches/settings/RolloutWindowsConfiguration.tsx
@@ -1,12 +1,10 @@
-import React, { useEffect, useState } from 'react'
+import React from 'react'
import { mdiPulse } from '@mdi/js'
-import * as jsonc from 'jsonc-parser'
-import { BatchChangeRolloutWindow } from '@sourcegraph/shared/src/schema/site.schema'
import { Text, H3, Container, Icon, LoadingSpinner, ErrorAlert, Link } from '@sourcegraph/wildcard'
-import { useGetBatchChangesSiteConfiguration } from '../backend'
+import { useBatchChangesRolloutWindowConfig } from '../backend'
import { formatRate, formatDays } from './format'
@@ -14,22 +12,15 @@ import styles from './RolloutWindowsConfiguration.module.scss'
// Displays the rollout window configuration.
export const RolloutWindowsConfiguration: React.FunctionComponent = () => {
- const [rolloutWindows, setRolloutWindows] = useState([])
- const { loading, error, data } = useGetBatchChangesSiteConfiguration()
- useEffect(() => {
- if (data) {
- const siteConfig = jsonc.parse(data.site.configuration.effectiveContents)
- setRolloutWindows(siteConfig['batchChanges.rolloutWindows'] || [])
- }
- }, [data])
+ const { loading, error, rolloutWindowConfig } = useBatchChangesRolloutWindowConfig()
return (
Rollout Windows
{loading && }
{error && }
{!loading &&
- data &&
- (rolloutWindows.length === 0 ? (
+ rolloutWindowConfig &&
+ (rolloutWindowConfig.length === 0 ? (
No rollout windows configured for changesets. Learn how to configure them in{' '}
@@ -48,7 +39,7 @@ export const RolloutWindowsConfiguration: React.FunctionComponent = () => {
- {rolloutWindows.map((rolloutWindow, index) => (
+ {rolloutWindowConfig.map((rolloutWindow, index) => (
-
, 'e
batchChangesWebhookLogsEnabled: boolean
- batchChangesRolloutWindows: BatchChangeRolloutWindow[] | null
-
/** Whether cody is enabled for the user. */
codyEnabled: boolean
diff --git a/cmd/frontend/internal/app/jscontext/jscontext.go b/cmd/frontend/internal/app/jscontext/jscontext.go
index 9fe00003df0b3..b0de6e5dfc322 100644
--- a/cmd/frontend/internal/app/jscontext/jscontext.go
+++ b/cmd/frontend/internal/app/jscontext/jscontext.go
@@ -176,10 +176,9 @@ type JSContext struct {
// the request is an admin and thus can access batch changes
// It does NOT reflect whether or not the site license has batch changes available.
// Use LicenseInfo for that.
- BatchChangesEnabled bool `json:"batchChangesEnabled"`
- BatchChangesDisableWebhooksWarning bool `json:"batchChangesDisableWebhooksWarning"`
- BatchChangesWebhookLogsEnabled bool `json:"batchChangesWebhookLogsEnabled"`
- BatchChangesRolloutWindows *[]*schema.BatchChangeRolloutWindow `json:"batchChangesRolloutWindows"`
+ BatchChangesEnabled bool `json:"batchChangesEnabled"`
+ BatchChangesDisableWebhooksWarning bool `json:"batchChangesDisableWebhooksWarning"`
+ BatchChangesWebhookLogsEnabled bool `json:"batchChangesWebhookLogsEnabled"`
CodyEnabled bool `json:"codyEnabled"`
@@ -360,7 +359,6 @@ func NewJSContextFromRequest(req *http.Request, db database.DB) JSContext {
BatchChangesEnabled: enterprise.BatchChangesEnabledForUser(ctx, db) == nil,
BatchChangesDisableWebhooksWarning: conf.Get().BatchChangesDisableWebhooksWarning,
BatchChangesWebhookLogsEnabled: webhooks.LoggingEnabled(conf.Get()),
- BatchChangesRolloutWindows: conf.Get().BatchChangesRolloutWindows,
CodyEnabled: cody.IsCodyEnabled(ctx),