@spinnaker/core 0.11.7 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +17 -0
- package/dist/config/settings.d.ts +1 -0
- package/dist/index.js +36 -32
- package/dist/index.js.map +1 -1
- package/dist/managed/environmentBaseElements/EnvironmentsRender.d.ts +3 -2
- package/dist/managed/graphql/graphql-sdk.d.ts +4 -0
- package/dist/managed/overview/PreviewEnvironments.d.ts +8 -0
- package/dist/managed/utils/defaults.d.ts +1 -1
- package/package.json +2 -2
- package/src/cloudProvider/providerSelection/ProviderSelectionService.spec.ts +96 -0
- package/src/cloudProvider/providerSelection/ProviderSelectionService.ts +6 -8
- package/src/cluster/allClusters.html +1 -0
- package/src/config/settings.ts +2 -0
- package/src/instance/details/multipleInstances.controller.js +6 -0
- package/src/instance/details/multipleInstances.view.html +1 -0
- package/src/managed/environmentBaseElements/EnvironmentsRender.tsx +7 -1
- package/src/managed/graphql/graphql-sdk.ts +6 -0
- package/src/managed/graphql/schema.graphql +1 -0
- package/src/managed/overview/EnvironmentsOverview.tsx +8 -11
- package/src/managed/overview/PreviewEnvironments.tsx +47 -0
- package/src/managed/overview/queries.graphql +4 -0
- package/src/managed/utils/defaults.ts +1 -1
- package/src/serverGroup/details/multipleServerGroups.controller.js +6 -0
- package/src/serverGroup/details/multipleServerGroups.view.html +1 -0
- package/src/utils/clipboard/CopyToClipboard.tsx +1 -1
|
@@ -10,10 +10,11 @@ interface IEnvironmentsRenderProps {
|
|
|
10
10
|
style?: React.CSSProperties;
|
|
11
11
|
children?: React.ReactNode;
|
|
12
12
|
}
|
|
13
|
-
export
|
|
13
|
+
export interface OrderedEnvironments<T> {
|
|
14
14
|
className?: string;
|
|
15
15
|
style?: React.CSSProperties;
|
|
16
16
|
environments: T[];
|
|
17
|
-
}
|
|
17
|
+
}
|
|
18
|
+
export declare const useOrderedEnvironment: <T extends object>(ref: React.RefObject<HTMLDivElement>, environments: T[]) => OrderedEnvironments<T>;
|
|
18
19
|
export declare const EnvironmentsRender: React.ForwardRefExoticComponent<IEnvironmentsRenderProps & React.RefAttributes<HTMLDivElement>>;
|
|
19
20
|
export {};
|
|
@@ -106,6 +106,7 @@ export interface MdConfig {
|
|
|
106
106
|
updatedAt?: Maybe<Scalars['InstantTime']>;
|
|
107
107
|
rawConfig?: Maybe<Scalars['String']>;
|
|
108
108
|
processedConfig?: Maybe<Scalars['String']>;
|
|
109
|
+
previewEnvironmentsConfigured?: Maybe<Scalars['Boolean']>;
|
|
109
110
|
}
|
|
110
111
|
export interface MdConstraint {
|
|
111
112
|
__typename?: 'MdConstraint';
|
|
@@ -467,6 +468,9 @@ export declare type FetchApplicationQuery = {
|
|
|
467
468
|
application?: Maybe<{
|
|
468
469
|
__typename?: 'MdApplication';
|
|
469
470
|
} & Pick<MdApplication, 'id' | 'name' | 'account'> & {
|
|
471
|
+
config?: Maybe<{
|
|
472
|
+
__typename?: 'MdConfig';
|
|
473
|
+
} & Pick<MdConfig, 'id' | 'previewEnvironmentsConfigured'>>;
|
|
470
474
|
environments: Array<{
|
|
471
475
|
__typename?: 'MdEnvironment';
|
|
472
476
|
} & Pick<MdEnvironment, 'isDeleting'> & {
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { OrderedEnvironments } from '../environmentBaseElements/EnvironmentsRender';
|
|
2
|
+
import { QueryEnvironment } from './types';
|
|
3
|
+
interface IPreviewEnvironmentsProps {
|
|
4
|
+
orderedEnvironments: OrderedEnvironments<QueryEnvironment>;
|
|
5
|
+
isConfigured?: boolean;
|
|
6
|
+
}
|
|
7
|
+
export declare const PreviewEnvironments: ({ orderedEnvironments, isConfigured }: IPreviewEnvironmentsProps) => JSX.Element;
|
|
8
|
+
export {};
|
|
@@ -8,4 +8,4 @@ export declare const MODAL_MAX_WIDTH = 750;
|
|
|
8
8
|
export declare const spinnerProps: ISpinnerProps;
|
|
9
9
|
export declare const ABSOLUTE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss ZZZZ";
|
|
10
10
|
export declare const MD_CATEGORY = "ManagedDelivery";
|
|
11
|
-
export declare const getDocsUrl: (doc: keyof IManagedDeliveryURLs) => string;
|
|
11
|
+
export declare const getDocsUrl: (doc: keyof IManagedDeliveryURLs) => string | undefined;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@spinnaker/core",
|
|
3
3
|
"license": "Apache-2.0",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.12.0",
|
|
5
5
|
"module": "dist/index.js",
|
|
6
6
|
"typings": "dist/index.d.ts",
|
|
7
7
|
"scripts": {
|
|
@@ -120,5 +120,5 @@
|
|
|
120
120
|
"shx": "0.3.3",
|
|
121
121
|
"typescript": "4.3.5"
|
|
122
122
|
},
|
|
123
|
-
"gitHead": "
|
|
123
|
+
"gitHead": "dc5b117bb381113416c21ae8e4c39ec1c526dd2b"
|
|
124
124
|
}
|
|
@@ -266,4 +266,100 @@ describe('ProviderSelectionService: API', () => {
|
|
|
266
266
|
$scope.$digest();
|
|
267
267
|
expect(provider).toBe('modalProvider');
|
|
268
268
|
});
|
|
269
|
+
|
|
270
|
+
// Unit tests for the isDisabled function, used to disable and enable buttons that create infrastructure ad-hoc operations
|
|
271
|
+
// in the core module (Create Server Group, Create Load Balancer, Create Firewall, Create Function)
|
|
272
|
+
describe('Toggle Infrastructure Ad-hoc Operations', function () {
|
|
273
|
+
// If an application is configured to only have kubernetes as a cloud provider and only one account exists, which is a kubernetes account,
|
|
274
|
+
// then show the create infrastructure buttons if kubernetesAdHocInfraWritesEnabled is set to true
|
|
275
|
+
it('create infrastructure buttons are enabled for applications with kubernetes cloud provider when kubernetesAdHocInfraWritesEnabled is set to true', () => {
|
|
276
|
+
let isDisabled_result = false;
|
|
277
|
+
hasValue = true;
|
|
278
|
+
const k8s_account = fakeAccount('kubernetes');
|
|
279
|
+
k8s_account.type = 'kubernetes';
|
|
280
|
+
|
|
281
|
+
accounts = [k8s_account];
|
|
282
|
+
let configuration = {
|
|
283
|
+
name: 'kubernetes',
|
|
284
|
+
kubernetesAdHocInfraWritesEnabled: true,
|
|
285
|
+
};
|
|
286
|
+
CloudProviderRegistry.registerProvider('kubernetes', configuration);
|
|
287
|
+
ProviderSelectionService.isDisabled(application).then((isDisable) => {
|
|
288
|
+
isDisabled_result = isDisable;
|
|
289
|
+
});
|
|
290
|
+
$scope.$digest();
|
|
291
|
+
expect(isDisabled_result).toBe(false);
|
|
292
|
+
});
|
|
293
|
+
|
|
294
|
+
// If an application is configured to only have kubernetes as a cloud provider and only one account exists, which is a kubernetes account,
|
|
295
|
+
// then disable the create infrastructure buttons when kubernetesAdHocInfraWritesEnabled is set to false
|
|
296
|
+
it('disable create infrastructure buttons for kubernetes applications when kubernetesAdHocInfraWritesEnabled is false', () => {
|
|
297
|
+
let isDisabled_result = false;
|
|
298
|
+
hasValue = true;
|
|
299
|
+
const k8s_account = fakeAccount('kubernetes');
|
|
300
|
+
k8s_account.type = 'kubernetes';
|
|
301
|
+
|
|
302
|
+
accounts = [k8s_account];
|
|
303
|
+
let configuration = {
|
|
304
|
+
name: 'kubernetes',
|
|
305
|
+
kubernetesAdHocInfraWritesEnabled: false,
|
|
306
|
+
};
|
|
307
|
+
CloudProviderRegistry.registerProvider('kubernetes', configuration);
|
|
308
|
+
ProviderSelectionService.isDisabled(application).then((isDisable) => {
|
|
309
|
+
isDisabled_result = isDisable;
|
|
310
|
+
});
|
|
311
|
+
$scope.$digest();
|
|
312
|
+
expect(isDisabled_result).toBe(true);
|
|
313
|
+
});
|
|
314
|
+
|
|
315
|
+
// If the application is configured to have multiple cloud providers (kuberentes and gce) and different accounts exist with
|
|
316
|
+
// different cloud providers (kuberentes and gce), then create infrastructure buttons appear even though kubernetesAdHocInfraWritesEnabled is false.
|
|
317
|
+
// This is because the buttons allow for ad-hoc operations for the non-kubernetes provider (GCE in this case)
|
|
318
|
+
it('create infrastructure buttons are enabled for apps with a cloud provider that does not have its ad-hoc operation disabled', () => {
|
|
319
|
+
let provider = '';
|
|
320
|
+
hasValue = true;
|
|
321
|
+
let isDisabled_result = false;
|
|
322
|
+
const k8s_account = fakeAccount('kubernetes');
|
|
323
|
+
k8s_account.type = 'kubernetes';
|
|
324
|
+
accounts = [k8s_account, fakeAccount('gce')];
|
|
325
|
+
let kubernetes_configuration = {
|
|
326
|
+
name: 'Kubernetes',
|
|
327
|
+
kubernetesAdHocInfraWritesEnabled: false,
|
|
328
|
+
};
|
|
329
|
+
CloudProviderRegistry.registerProvider('kubernetes', kubernetes_configuration);
|
|
330
|
+
CloudProviderRegistry.registerProvider('gce', config);
|
|
331
|
+
ProviderSelectionService.selectProvider(application, 'securityGroup').then((_provider) => {
|
|
332
|
+
provider = _provider;
|
|
333
|
+
});
|
|
334
|
+
ProviderSelectionService.isDisabled(application).then((isDisable) => {
|
|
335
|
+
isDisabled_result = isDisable;
|
|
336
|
+
});
|
|
337
|
+
$scope.$digest();
|
|
338
|
+
expect(isDisabled_result).toBe(false);
|
|
339
|
+
expect(provider).toBe('gce');
|
|
340
|
+
});
|
|
341
|
+
|
|
342
|
+
// If an application is configured to have kubernetes as a cloud provider, and there are multiple kubernetes accounts, then the create
|
|
343
|
+
// infrastructure buttons are disabled if kubernetesAdHocInfraWritesEnabled is false
|
|
344
|
+
it('create infrastructure buttons are disabled when all accounts have cloud providers with ad-hoc operations disabled', () => {
|
|
345
|
+
let isDisabled_result = false;
|
|
346
|
+
hasValue = true;
|
|
347
|
+
const k8s_account_1 = fakeAccount('kubernetes');
|
|
348
|
+
k8s_account_1.type = 'kubernetes';
|
|
349
|
+
const k8s_account_2 = fakeAccount('kubernetes');
|
|
350
|
+
k8s_account_2.type = 'kubernetes';
|
|
351
|
+
|
|
352
|
+
accounts = [k8s_account_1, k8s_account_2];
|
|
353
|
+
let configuration = {
|
|
354
|
+
name: 'kubernetes',
|
|
355
|
+
kubernetesAdHocInfraWritesEnabled: false,
|
|
356
|
+
};
|
|
357
|
+
CloudProviderRegistry.registerProvider('kubernetes', configuration);
|
|
358
|
+
ProviderSelectionService.isDisabled(application).then((isDisable) => {
|
|
359
|
+
isDisabled_result = isDisable;
|
|
360
|
+
});
|
|
361
|
+
$scope.$digest();
|
|
362
|
+
expect(isDisabled_result).toBe(true);
|
|
363
|
+
});
|
|
364
|
+
});
|
|
269
365
|
});
|
|
@@ -53,14 +53,12 @@ export class ProviderSelectionService {
|
|
|
53
53
|
public static isDisabled(app: Application): PromiseLike<boolean> {
|
|
54
54
|
return AccountService.applicationAccounts(app).then((accounts: IAccountDetails[]) => {
|
|
55
55
|
let isDisable = false;
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
isDisable = !CloudProviderRegistry.getValue(a.cloudProvider, 'kubernetesAdHocInfraWritesEnabled');
|
|
63
|
-
});
|
|
56
|
+
const cloudProvidersEnabled = accounts.filter((a) => {
|
|
57
|
+
return !CloudProviderRegistry.isDisabled(a.cloudProvider);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
if (cloudProvidersEnabled.length === 0) {
|
|
61
|
+
isDisable = true;
|
|
64
62
|
}
|
|
65
63
|
return isDisable;
|
|
66
64
|
});
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
class="btn btn-xs btn-default"
|
|
7
7
|
ng-class="{active: filterModel.sortFilter.multiselect}"
|
|
8
8
|
ng-click="ctrl.toggleMultiselect()"
|
|
9
|
+
ng-hide="isDisabled"
|
|
9
10
|
>
|
|
10
11
|
<span class="glyphicon glyphicon-list visible-lg-inline"></span>
|
|
11
12
|
<span class="glyphicon glyphicon-list visible-md-inline visible-sm-inline" uib-tooltip="Edit multiple"></span>
|
package/src/config/settings.ts
CHANGED
|
@@ -73,6 +73,7 @@ export interface IManagedDeliveryURLs {
|
|
|
73
73
|
pinning: string;
|
|
74
74
|
resourceStatus: string;
|
|
75
75
|
markAsBad: string;
|
|
76
|
+
previewEnvironments?: string;
|
|
76
77
|
}
|
|
77
78
|
|
|
78
79
|
export interface ISpinnakerSettings {
|
|
@@ -157,6 +158,7 @@ export const SETTINGS: ISpinnakerSettings = (window as any).spinnakerSettings ||
|
|
|
157
158
|
// Make sure to set up some reasonable default settings fields so we do not have to keep checking if they exist everywhere
|
|
158
159
|
SETTINGS.feature = SETTINGS.feature || {};
|
|
159
160
|
SETTINGS.feature.roscoMode = SETTINGS.feature.roscoMode ?? true;
|
|
161
|
+
SETTINGS.kubernetesAdHocInfraWritesEnabled = SETTINGS.kubernetesAdHocInfraWritesEnabled ?? true;
|
|
160
162
|
SETTINGS.analytics = SETTINGS.analytics || {};
|
|
161
163
|
SETTINGS.providers = SETTINGS.providers || {};
|
|
162
164
|
SETTINGS.defaultTimeZone = SETTINGS.defaultTimeZone || 'America/Los_Angeles';
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import UIROUTER_ANGULARJS from '@uirouter/angularjs';
|
|
4
4
|
import { module } from 'angular';
|
|
5
5
|
|
|
6
|
+
import { ProviderSelectionService } from '../../cloudProvider/providerSelection/ProviderSelectionService';
|
|
6
7
|
import { ConfirmationModalService } from '../../confirmationModal';
|
|
7
8
|
import { InstanceWriter } from '../instance.write.service';
|
|
8
9
|
import { CORE_INSTANCE_DETAILS_MULTIPLEINSTANCESERVERGROUP_DIRECTIVE } from './multipleInstanceServerGroup.directive';
|
|
@@ -20,6 +21,11 @@ module(CORE_INSTANCE_DETAILS_MULTIPLEINSTANCES_CONTROLLER, [
|
|
|
20
21
|
'app',
|
|
21
22
|
function ($scope, $state, app) {
|
|
22
23
|
this.selectedGroups = [];
|
|
24
|
+
this.$onInit = () => {
|
|
25
|
+
ProviderSelectionService.isDisabled(app).then((disabled) => {
|
|
26
|
+
$scope.isDisabled = disabled;
|
|
27
|
+
});
|
|
28
|
+
};
|
|
23
29
|
|
|
24
30
|
/**
|
|
25
31
|
* Actions
|
|
@@ -65,10 +65,16 @@ interface IEnvironmentsRenderProps {
|
|
|
65
65
|
children?: React.ReactNode;
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
+
export interface OrderedEnvironments<T> {
|
|
69
|
+
className?: string;
|
|
70
|
+
style?: React.CSSProperties;
|
|
71
|
+
environments: T[];
|
|
72
|
+
}
|
|
73
|
+
|
|
68
74
|
export const useOrderedEnvironment = <T extends object>(
|
|
69
75
|
ref: React.RefObject<HTMLDivElement>,
|
|
70
76
|
environments: T[],
|
|
71
|
-
):
|
|
77
|
+
): OrderedEnvironments<T> => {
|
|
72
78
|
const { direction } = useEnvironmentDirectionState();
|
|
73
79
|
const { width } = useDimensions(ref, { isActive: direction === 'gridView' });
|
|
74
80
|
|
|
@@ -120,6 +120,7 @@ export interface MdConfig {
|
|
|
120
120
|
updatedAt?: Maybe<Scalars['InstantTime']>;
|
|
121
121
|
rawConfig?: Maybe<Scalars['String']>;
|
|
122
122
|
processedConfig?: Maybe<Scalars['String']>;
|
|
123
|
+
previewEnvironmentsConfigured?: Maybe<Scalars['Boolean']>;
|
|
123
124
|
}
|
|
124
125
|
|
|
125
126
|
export interface MdConstraint {
|
|
@@ -545,6 +546,7 @@ export type FetchApplicationQueryVariables = Exact<{
|
|
|
545
546
|
export type FetchApplicationQuery = { __typename?: 'Query' } & {
|
|
546
547
|
application?: Maybe<
|
|
547
548
|
{ __typename?: 'MdApplication' } & Pick<MdApplication, 'id' | 'name' | 'account'> & {
|
|
549
|
+
config?: Maybe<{ __typename?: 'MdConfig' } & Pick<MdConfig, 'id' | 'previewEnvironmentsConfigured'>>;
|
|
548
550
|
environments: Array<
|
|
549
551
|
{ __typename?: 'MdEnvironment' } & Pick<MdEnvironment, 'isDeleting'> & {
|
|
550
552
|
state: { __typename?: 'MdEnvironmentState' } & Pick<MdEnvironmentState, 'id'> & {
|
|
@@ -937,6 +939,10 @@ export const FetchApplicationDocument = gql`
|
|
|
937
939
|
id
|
|
938
940
|
name
|
|
939
941
|
account
|
|
942
|
+
config {
|
|
943
|
+
id
|
|
944
|
+
previewEnvironmentsConfigured
|
|
945
|
+
}
|
|
940
946
|
environments {
|
|
941
947
|
...baseEnvironmentFields
|
|
942
948
|
isDeleting
|
|
@@ -2,6 +2,7 @@ import React from 'react';
|
|
|
2
2
|
|
|
3
3
|
import { ApplicationQueryError } from '../ApplicationQueryError';
|
|
4
4
|
import { EnvironmentOverview } from './EnvironmentOverview';
|
|
5
|
+
import { PreviewEnvironments } from './PreviewEnvironments';
|
|
5
6
|
import { EnvironmentsRender, useOrderedEnvironment } from '../environmentBaseElements/EnvironmentsRender';
|
|
6
7
|
import { useFetchApplicationQuery } from '../graphql/graphql-sdk';
|
|
7
8
|
import { Messages } from '../messages/Messages';
|
|
@@ -25,11 +26,13 @@ export const EnvironmentsOverview = () => {
|
|
|
25
26
|
environments.filter((env) => !env.isPreview),
|
|
26
27
|
);
|
|
27
28
|
|
|
28
|
-
const
|
|
29
|
+
const previewEnvironments = useOrderedEnvironment(
|
|
29
30
|
wrapperRef,
|
|
30
31
|
environments.filter((env) => env.isPreview),
|
|
31
32
|
);
|
|
32
33
|
|
|
34
|
+
const previewEnvironmentsConfigured = data?.application?.config?.previewEnvironmentsConfigured;
|
|
35
|
+
|
|
33
36
|
let content;
|
|
34
37
|
if (loading && !data) {
|
|
35
38
|
content = <Spinner {...spinnerProps} message="Loading environments..." />;
|
|
@@ -46,16 +49,10 @@ export const EnvironmentsOverview = () => {
|
|
|
46
49
|
<EnvironmentOverview key={env.name} environment={env} />
|
|
47
50
|
))}
|
|
48
51
|
</EnvironmentsRender>
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
)}
|
|
54
|
-
<EnvironmentsRender {...previewEnvironmentsProps}>
|
|
55
|
-
{previewEnvironments.map((env) => (
|
|
56
|
-
<EnvironmentOverview key={env.name} environment={env} />
|
|
57
|
-
))}
|
|
58
|
-
</EnvironmentsRender>
|
|
52
|
+
<PreviewEnvironments
|
|
53
|
+
orderedEnvironments={previewEnvironments}
|
|
54
|
+
isConfigured={previewEnvironmentsConfigured}
|
|
55
|
+
/>
|
|
59
56
|
</>
|
|
60
57
|
) : (
|
|
61
58
|
<div className="error-message">No environments found</div>
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
import { EnvironmentOverview } from './EnvironmentOverview';
|
|
4
|
+
import { EnvironmentsRender, OrderedEnvironments } from '../environmentBaseElements/EnvironmentsRender';
|
|
5
|
+
import { QueryEnvironment } from './types';
|
|
6
|
+
import { getDocsUrl } from '../utils/defaults';
|
|
7
|
+
import { useLogEvent } from '../utils/logging';
|
|
8
|
+
|
|
9
|
+
interface IPreviewEnvironmentsProps {
|
|
10
|
+
orderedEnvironments: OrderedEnvironments<QueryEnvironment>;
|
|
11
|
+
isConfigured?: boolean;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export const PreviewEnvironments = ({ orderedEnvironments, isConfigured }: IPreviewEnvironmentsProps) => {
|
|
15
|
+
const { environments: previewEnvironments, ...previewEnvironmentsProps } = orderedEnvironments;
|
|
16
|
+
const logClick = useLogEvent('PreviewEnvironments');
|
|
17
|
+
const docsLink = getDocsUrl('previewEnvironments');
|
|
18
|
+
const hasActivePreviewEnvironments = previewEnvironments.length > 0;
|
|
19
|
+
|
|
20
|
+
return (
|
|
21
|
+
<>
|
|
22
|
+
{(isConfigured || hasActivePreviewEnvironments) && (
|
|
23
|
+
<h4 className="sp-margin-2xl-top sp-margin-m-bottom self-left">
|
|
24
|
+
<b>Preview Environments</b>
|
|
25
|
+
</h4>
|
|
26
|
+
)}
|
|
27
|
+
{isConfigured && !hasActivePreviewEnvironments && (
|
|
28
|
+
<div className="self-left">
|
|
29
|
+
No PRs matching your branch filter were found.
|
|
30
|
+
<br />
|
|
31
|
+
Your preview environments will automatically appear here once you create a PR from a branch matching your
|
|
32
|
+
config definition.{' '}
|
|
33
|
+
{docsLink && (
|
|
34
|
+
<a target="_blank" onClick={() => logClick({ action: 'Learn More' })} href={docsLink}>
|
|
35
|
+
Learn More
|
|
36
|
+
</a>
|
|
37
|
+
)}
|
|
38
|
+
</div>
|
|
39
|
+
)}
|
|
40
|
+
<EnvironmentsRender {...previewEnvironmentsProps}>
|
|
41
|
+
{previewEnvironments.map((env) => (
|
|
42
|
+
<EnvironmentOverview key={env.name} environment={env} />
|
|
43
|
+
))}
|
|
44
|
+
</EnvironmentsRender>
|
|
45
|
+
</>
|
|
46
|
+
);
|
|
47
|
+
};
|
|
@@ -26,6 +26,6 @@ const DOCS_URLS: IManagedDeliveryURLs = {
|
|
|
26
26
|
resourceStatus: 'https://www.spinnaker.io/guides/user/managed-delivery/resource-status/',
|
|
27
27
|
};
|
|
28
28
|
|
|
29
|
-
export const getDocsUrl = (doc: keyof IManagedDeliveryURLs): string => {
|
|
29
|
+
export const getDocsUrl = (doc: keyof IManagedDeliveryURLs): string | undefined => {
|
|
30
30
|
return SETTINGS.managedDelivery?.urls?.[doc] || DOCS_URLS[doc];
|
|
31
31
|
};
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import UIROUTER_ANGULARJS from '@uirouter/angularjs';
|
|
4
4
|
import * as angular from 'angular';
|
|
5
5
|
|
|
6
|
+
import { ProviderSelectionService } from '../../cloudProvider/providerSelection/ProviderSelectionService';
|
|
6
7
|
import { PROVIDER_SERVICE_DELEGATE } from '../../cloudProvider/providerService.delegate';
|
|
7
8
|
import { ConfirmationModalService } from '../../confirmationModal';
|
|
8
9
|
import { CORE_SERVERGROUP_DETAILS_MULTIPLESERVERGROUP_COMPONENT } from './multipleServerGroup.component';
|
|
@@ -27,6 +28,11 @@ angular
|
|
|
27
28
|
'app',
|
|
28
29
|
function ($scope, $state, serverGroupWriter, providerServiceDelegate, app) {
|
|
29
30
|
this.serverGroups = [];
|
|
31
|
+
this.$onInit = () => {
|
|
32
|
+
ProviderSelectionService.isDisabled(app).then((disabled) => {
|
|
33
|
+
$scope.isDisabled = disabled;
|
|
34
|
+
});
|
|
35
|
+
};
|
|
30
36
|
|
|
31
37
|
/**
|
|
32
38
|
* Actions
|
|
@@ -93,7 +93,7 @@ export class CopyToClipboard extends React.Component<ICopyToClipboardProps, ICop
|
|
|
93
93
|
|
|
94
94
|
const persistOverlay = Boolean(tooltipCopy);
|
|
95
95
|
const copy = tooltipCopy || toolTip;
|
|
96
|
-
const id = `clipboardValue-${text.replace(' ', '-')}`;
|
|
96
|
+
const id = `clipboardValue-${text.toString().replace(' ', '-')}`;
|
|
97
97
|
const tooltipComponent = <Tooltip id={id}>{copy}</Tooltip>;
|
|
98
98
|
|
|
99
99
|
// Hack - shouldUpdatePosition is a valid prop, just not declared in typings
|