@spinnaker/core 0.17.0 → 0.18.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.
@@ -1,8 +1,2 @@
1
- import React from 'react';
2
- export interface IQuietPeriodBadgeProps {
3
- start: Date;
4
- end: Date;
5
- }
6
- export declare class QuietPeriodBadge extends React.Component<IQuietPeriodBadgeProps> {
7
- render(): JSX.Element;
8
- }
1
+ /// <reference types="react" />
2
+ export declare function QuietPeriodBadge(): JSX.Element;
@@ -1,15 +1,6 @@
1
- import React from 'react';
1
+ /// <reference types="react" />
2
2
  import type { IPipeline } from '../../domain/IPipeline';
3
3
  export interface ITriggersTagProps {
4
4
  pipeline: IPipeline;
5
5
  }
6
- export interface ITriggersTagState {
7
- triggerCount: number;
8
- activeTriggerCount: number;
9
- }
10
- export declare class TriggersTag extends React.Component<ITriggersTagProps, ITriggersTagState> {
11
- private quietPeriodStart;
12
- private quietPeriodEnd;
13
- constructor(props: ITriggersTagProps);
14
- render(): React.ReactElement<TriggersTag>;
15
- }
6
+ export declare function TriggersTag(props: ITriggersTagProps): JSX.Element;
@@ -0,0 +1,7 @@
1
+ interface IQuietPeriod {
2
+ currentStatus: 'UNKNOWN' | 'BEFORE_QUIET_PERIOD' | 'DURING_QUIET_PERIOD' | 'AFTER_QUIET_PERIOD' | 'NO_QUIET_PERIOD';
3
+ startTime: number;
4
+ endTime: number;
5
+ }
6
+ export declare function useQuietPeriod(): IQuietPeriod;
7
+ export {};
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@spinnaker/core",
3
3
  "license": "Apache-2.0",
4
- "version": "0.17.0",
4
+ "version": "0.18.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": "fd69b27a052ccb2a170efdbe0b971a8636c96447"
123
+ "gitHead": "8f3171b4918a445dc508fb4baf676baf639de0ab"
124
124
  }
@@ -143,7 +143,6 @@ export interface ISpinnakerSettings {
143
143
  [key: string]: IProviderSettings; // allows custom providers not typed in here (good for testing too)
144
144
  };
145
145
  pubsubProviders: string[];
146
- quietPeriod: [string | number, string | number];
147
146
  resetProvider: (provider: string) => () => void;
148
147
  resetToOriginal: () => void;
149
148
  searchVersion: 1 | 2;
@@ -74,7 +74,7 @@ export class StageFailureMessage extends React.Component<IStageFailureMessagePro
74
74
  const { message, messages, stage } = this.props;
75
75
  const { isFailed, failedTask, failedExecutionId, failedStageName, failedStageId } = this.state;
76
76
 
77
- let stageMessages = message || !messages.length ? [message] : messages;
77
+ let stageMessages = message && !messages.length ? [message] : messages;
78
78
  if (stageMessages.length > 0) {
79
79
  const exceptionTitle = isFailed ? (messages.length ? 'Exceptions' : 'Exception') : 'Warning';
80
80
 
@@ -2,11 +2,7 @@ import type { DateTimeFormatOptions } from 'luxon';
2
2
  import React from 'react';
3
3
 
4
4
  import { Tooltip } from '../../presentation';
5
-
6
- export interface IQuietPeriodBadgeProps {
7
- start: Date;
8
- end: Date;
9
- }
5
+ import { useQuietPeriod } from './useQuietPeriod.hook';
10
6
 
11
7
  const locale = 'en-US';
12
8
  const dateOptions: DateTimeFormatOptions = {
@@ -18,37 +14,30 @@ const dateOptions: DateTimeFormatOptions = {
18
14
  minute: '2-digit',
19
15
  };
20
16
 
21
- export class QuietPeriodBadge extends React.Component<IQuietPeriodBadgeProps> {
22
- public render() {
23
- const { start, end } = this.props;
24
-
25
- if (!start || !end) {
26
- return null;
27
- }
17
+ export function QuietPeriodBadge() {
18
+ const quietPeriod = useQuietPeriod();
19
+ if (quietPeriod.currentStatus === 'NO_QUIET_PERIOD' || quietPeriod.currentStatus === 'UNKNOWN') {
20
+ return null;
21
+ }
28
22
 
29
- const now = new Date();
30
- const afterQuietPeriod = now > end;
31
- if (afterQuietPeriod) {
32
- return null;
33
- }
23
+ const start = new Date(quietPeriod.startTime);
24
+ const end = new Date(quietPeriod.endTime);
34
25
 
35
- const inQuietPeriod = start < now && !afterQuietPeriod;
26
+ const message =
27
+ quietPeriod.currentStatus === 'DURING_QUIET_PERIOD'
28
+ ? 'This pipeline will not be automatically triggered until the end of the quiet period. '
29
+ : 'This pipeline will not be automatically triggered during the quiet period. ';
36
30
 
37
- const quietPeriodRange = (
31
+ const template = (
32
+ <span>
33
+ {message}
38
34
  <span>{`(${start.toLocaleString(locale, dateOptions)} - ${end.toLocaleString(locale, dateOptions)})`}</span>
39
- );
40
- const tooltipTemplate = inQuietPeriod ? (
41
- <span>
42
- This pipeline will not be automatically triggered until the end of the quiet period. {quietPeriodRange}
43
- </span>
44
- ) : (
45
- <span>This pipeline will not be automatically triggered during the quiet period. {quietPeriodRange}</span>
46
- );
47
-
48
- return (
49
- <Tooltip template={tooltipTemplate}>
50
- <i className="fa icon-calendar-warning" style={{ color: 'red' }} />
51
- </Tooltip>
52
- );
53
- }
35
+ </span>
36
+ );
37
+
38
+ return (
39
+ <Tooltip template={template}>
40
+ <i className="fa icon-calendar-warning" style={{ color: 'red' }} />
41
+ </Tooltip>
42
+ );
54
43
  }
@@ -1,79 +1,49 @@
1
- import { filter } from 'lodash';
2
- import React from 'react';
1
+ import * as React from 'react';
3
2
 
4
3
  import { QuietPeriodBadge } from './QuietPeriodBadge';
5
- import { SETTINGS } from '../../config';
4
+ import type { ITrigger } from '../../domain';
6
5
  import type { IPipeline } from '../../domain/IPipeline';
6
+ import { useQuietPeriod } from './useQuietPeriod.hook';
7
7
 
8
8
  export interface ITriggersTagProps {
9
9
  pipeline: IPipeline;
10
10
  }
11
11
 
12
- export interface ITriggersTagState {
13
- triggerCount: number;
14
- activeTriggerCount: number;
15
- }
16
-
17
- export class TriggersTag extends React.Component<ITriggersTagProps, ITriggersTagState> {
18
- private quietPeriodStart: Date;
19
- private quietPeriodEnd: Date;
20
-
21
- constructor(props: ITriggersTagProps) {
22
- super(props);
23
-
24
- let triggerCount = 0;
25
- let activeTriggerCount = 0;
26
- let quietPeriodEnabled = false;
27
-
28
- const pipeline = this.props.pipeline;
29
- if (pipeline && pipeline.triggers && pipeline.triggers.length) {
30
- triggerCount = pipeline.triggers.length;
31
- activeTriggerCount = filter(pipeline.triggers, { enabled: true }).length;
32
- quietPeriodEnabled = Boolean(pipeline.respectQuietPeriod);
33
- }
34
-
35
- const hasQuietPeriod = SETTINGS.feature.quietPeriod && SETTINGS.quietPeriod && SETTINGS.quietPeriod.length === 2;
36
-
37
- if (hasQuietPeriod && quietPeriodEnabled) {
38
- this.quietPeriodStart = new Date(SETTINGS.quietPeriod[0]);
39
- this.quietPeriodEnd = new Date(SETTINGS.quietPeriod[1]);
40
- }
41
-
42
- this.state = {
43
- triggerCount,
44
- activeTriggerCount,
45
- };
12
+ function getTriggerLabel(totalTriggers: number, activeTriggers: number) {
13
+ if (totalTriggers === 1) {
14
+ return `Trigger: ${activeTriggers ? 'enabled' : 'disabled'}`;
15
+ } else if (totalTriggers === activeTriggers) {
16
+ return `All triggers: enabled`;
17
+ } else if (activeTriggers === 0) {
18
+ return `All triggers: disabled`;
19
+ } else {
20
+ return `Some triggers: enabled`;
46
21
  }
22
+ }
47
23
 
48
- public render(): React.ReactElement<TriggersTag> {
49
- const { pipeline } = this.props;
50
- const { triggerCount, activeTriggerCount } = this.state;
51
-
52
- if (triggerCount > 0) {
53
- const now = new Date();
54
- const inQuietPeriod = this.quietPeriodStart < now && now < this.quietPeriodEnd;
24
+ export function TriggersTag(props: ITriggersTagProps) {
25
+ const quietPeriod = useQuietPeriod();
55
26
 
56
- const triggers =
57
- triggerCount === 1
58
- ? 'Trigger'
59
- : activeTriggerCount === triggerCount || inQuietPeriod
60
- ? 'All triggers'
61
- : 'Some triggers';
62
- const displayTriggers = `${triggers}: ${activeTriggerCount === 0 || inQuietPeriod ? 'disabled' : 'enabled'}`;
27
+ const { pipeline } = props;
28
+ const triggers = pipeline?.triggers ?? [];
29
+ const isTriggerDisabled = (t: ITrigger) =>
30
+ !t.enabled ||
31
+ (pipeline.respectQuietPeriod && quietPeriod.currentStatus === 'DURING_QUIET_PERIOD' && t.type !== 'pipeline');
32
+ const activeTriggers = triggers.filter((t: ITrigger) => !isTriggerDisabled(t));
63
33
 
64
- return (
65
- <div
66
- className={`triggers-toggle ${activeTriggerCount ? '' : 'disabled'}`}
67
- style={{ visibility: pipeline.disabled ? 'hidden' : 'visible' }}
68
- >
69
- <span>
70
- <span>
71
- <QuietPeriodBadge start={this.quietPeriodStart} end={this.quietPeriodEnd} /> {displayTriggers}
72
- </span>
73
- </span>
74
- </div>
75
- );
76
- }
34
+ if (triggers.length === 0) {
77
35
  return <div />;
78
36
  }
37
+
38
+ return (
39
+ <div
40
+ className={`triggers-toggle ${activeTriggers.length > 0 ? '' : 'disabled'}`}
41
+ style={{ visibility: pipeline.disabled ? 'hidden' : 'visible' }}
42
+ >
43
+ <span className="flex-container-h margin-between-sm baseline">
44
+ {pipeline.respectQuietPeriod && <QuietPeriodBadge />}
45
+ <span>{getTriggerLabel(triggers.length, activeTriggers.length)}</span>
46
+ </span>
47
+ </div>
48
+ );
79
49
  }
@@ -0,0 +1,43 @@
1
+ import { REST } from '../../api';
2
+ import { useLatestPromise } from '../../presentation';
3
+
4
+ // Shape from back end
5
+ interface IQuietPeriodConfig {
6
+ startTime: number;
7
+ endTime: number;
8
+ enabled: boolean;
9
+ // Do not use in UI -- point-in-time data from back-end
10
+ inQuietPeriod: boolean;
11
+ }
12
+
13
+ class QuietPeriodService {
14
+ private static _quietPeriodConfig: PromiseLike<IQuietPeriodConfig>;
15
+ static async quietPeriodConfig(): Promise<IQuietPeriodConfig> {
16
+ this._quietPeriodConfig = this._quietPeriodConfig ?? REST('/capabilities/quietPeriod').get<IQuietPeriodConfig>();
17
+ return await this._quietPeriodConfig;
18
+ }
19
+ }
20
+
21
+ interface IQuietPeriod {
22
+ currentStatus: 'UNKNOWN' | 'BEFORE_QUIET_PERIOD' | 'DURING_QUIET_PERIOD' | 'AFTER_QUIET_PERIOD' | 'NO_QUIET_PERIOD';
23
+ startTime: number;
24
+ endTime: number;
25
+ }
26
+
27
+ export function useQuietPeriod(): IQuietPeriod {
28
+ const result = useLatestPromise(() => QuietPeriodService.quietPeriodConfig(), []);
29
+ if (result.status !== 'RESOLVED') {
30
+ return { currentStatus: 'UNKNOWN', startTime: undefined, endTime: undefined };
31
+ }
32
+
33
+ const { startTime, endTime, enabled } = result.result;
34
+ if (!enabled || !startTime || startTime < 0 || !endTime || endTime < 0) {
35
+ return { currentStatus: 'NO_QUIET_PERIOD', startTime: undefined, endTime: undefined };
36
+ }
37
+
38
+ const now = Date.now();
39
+ const currentStatus =
40
+ now < startTime ? 'BEFORE_QUIET_PERIOD' : now > endTime ? 'AFTER_QUIET_PERIOD' : 'DURING_QUIET_PERIOD';
41
+
42
+ return { currentStatus, startTime, endTime };
43
+ }