@spinnaker/core 0.14.1 → 0.16.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.
Files changed (224) hide show
  1. package/CHANGELOG.md +59 -0
  2. package/dist/config/settings.d.ts +1 -1
  3. package/dist/core.module.d.ts +1 -1
  4. package/dist/index.js +89 -47
  5. package/dist/index.js.map +1 -1
  6. package/dist/instance/instanceType.service.d.ts +3 -2
  7. package/dist/managed/artifactActions/ArtifactActions.d.ts +24 -0
  8. package/dist/managed/constraints/registry.d.ts +13 -2
  9. package/dist/managed/environmentBaseElements/EnvironmentItem.d.ts +3 -2
  10. package/dist/managed/graphql/graphql-sdk.d.ts +123 -11
  11. package/dist/managed/overview/Resource.d.ts +5 -2
  12. package/dist/managed/overview/artifact/Artifact.d.ts +2 -1
  13. package/dist/managed/overview/artifact/ArtifactActionModal.d.ts +20 -9
  14. package/dist/managed/overview/artifact/ArtifactCollapsibleSection.d.ts +7 -0
  15. package/dist/managed/overview/artifact/ArtifactVersions.d.ts +9 -0
  16. package/dist/managed/overview/artifact/CurrentVersion.d.ts +7 -6
  17. package/dist/managed/overview/artifact/VersionTitle.d.ts +9 -0
  18. package/dist/managed/overview/artifact/hooks.d.ts +6 -11
  19. package/dist/managed/overview/artifact/useCreateRollbackActions.hook.d.ts +3 -0
  20. package/dist/managed/overview/artifact/utils.d.ts +15 -14
  21. package/dist/managed/overview/useIsUpdatingResources.hook.d.ts +1 -0
  22. package/dist/managed/resources/ResourceTitle.d.ts +3 -3
  23. package/dist/managed/resources/resourceRegistry.d.ts +1 -1
  24. package/dist/managed/utils/ActionModal.d.ts +1 -0
  25. package/dist/managed/utils/defaults.d.ts +1 -0
  26. package/dist/managed/versionMetadata/MetadataComponents.d.ts +18 -19
  27. package/dist/managed/versionMetadata/VersionMetadata.d.ts +6 -2
  28. package/dist/search/infrastructure/infrastructureSearch.service.d.ts +2 -1
  29. package/dist/securityGroup/index.d.ts +2 -1
  30. package/package.json +6 -6
  31. package/src/account/AccountSelectInput.spec.tsx +9 -4
  32. package/src/account/AccountService.spec.ts +6 -6
  33. package/src/api/ApiService.spec.ts +2 -2
  34. package/src/api/ApiServiceDeprecated.spec.ts +5 -2
  35. package/src/application/application.model.spec.ts +78 -79
  36. package/src/application/applications.state.provider.ts +1 -1
  37. package/src/application/config/applicationAttributes.directive.html +6 -2
  38. package/src/application/config/applicationAttributes.directive.js +4 -0
  39. package/src/application/config/applicationConfig.view.html +14 -1
  40. package/src/application/config/customBanner/CustomBannerConfig.spec.tsx +3 -3
  41. package/src/application/config/dataSources/applicationDataSourceEditor.component.spec.ts +4 -3
  42. package/src/application/config/footer/configSectionFooter.component.spec.ts +2 -1
  43. package/src/application/listExtractor/AppListExtractor.spec.ts +4 -4
  44. package/src/application/modal/PermissionsConfigurer.spec.tsx +3 -2
  45. package/src/application/modal/createApplication.modal.controller.js +7 -6
  46. package/src/application/modal/createApplication.modal.controller.spec.js +1 -0
  47. package/src/application/modal/editApplication.controller.modal.js +1 -0
  48. package/src/application/modal/editApplication.html +2 -2
  49. package/src/application/modal/validation/ApplicationNameValidator.spec.ts +2 -1
  50. package/src/application/modal/validation/validateApplicationName.directive.spec.ts +3 -2
  51. package/src/application/nav/ApplicationNavigation.spec.tsx +12 -11
  52. package/src/application/nav/NavItem.spec.tsx +7 -5
  53. package/src/application/nav/NavSection.spec.tsx +3 -2
  54. package/src/application/search/Applications.tsx +48 -0
  55. package/src/application/service/ApplicationReader.spec.ts +13 -8
  56. package/src/application/service/ApplicationWriter.spec.ts +4 -2
  57. package/src/application/service/InferredApplicationWarningService.spec.ts +2 -3
  58. package/src/artifact/expectedArtifact.service.spec.ts +2 -1
  59. package/src/artifact/react/ExpectedArtifactSelector.spec.tsx +2 -3
  60. package/src/authentication/AuthenticationInitializer.spec.ts +2 -1
  61. package/src/authentication/AuthenticationService.spec.ts +2 -1
  62. package/src/authentication/authentication.interceptor.spec.ts +4 -2
  63. package/src/cache/cacheInitializer.service.spec.ts +7 -4
  64. package/src/cache/infrastructureCaches.spec.ts +4 -4
  65. package/src/chaosMonkey/chaosMonkeyExceptions.component.spec.ts +4 -2
  66. package/src/cloudProvider/providerSelection/ProviderSelectionService.spec.ts +23 -21
  67. package/src/cluster/ClusterRuleMatcher.spec.ts +2 -1
  68. package/src/cluster/cluster.service.spec.ts +7 -7
  69. package/src/cluster/filter/ClusterFilterService.spec.ts +15 -14
  70. package/src/cluster/filter/LabelFilter.spec.tsx +3 -3
  71. package/src/cluster/filter/MultiselectModel.spec.ts +2 -2
  72. package/src/cluster/filter/labelFilterUtils.spec.ts +3 -7
  73. package/src/config/settings.ts +1 -3
  74. package/src/core.module.ts +1 -1
  75. package/src/filterModel/dependentFilter/DependentFilterService.spec.ts +1 -1
  76. package/src/function/filter/FunctionFilterService.spec.ts +5 -3
  77. package/src/function/function.read.service.spec.ts +4 -3
  78. package/src/header/customBanner/CustomBanner.spec.tsx +3 -4
  79. package/src/healthCounts/HealthCounts.spec.tsx +2 -2
  80. package/src/history/recentHistory.service.spec.ts +2 -1
  81. package/src/insight/InsightMenu.spec.tsx +9 -6
  82. package/src/insight/InsightMenu.tsx +3 -0
  83. package/src/instance/instance.write.service.spec.ts +8 -7
  84. package/src/instance/instanceType.service.ts +12 -2
  85. package/src/instance/instanceTypeService.spec.ts +2 -1
  86. package/src/loadBalancer/LoadBalancersTag.spec.tsx +8 -6
  87. package/src/loadBalancer/filter/LoadBalancerFilterService.spec.ts +2 -2
  88. package/src/managed/Environments.less +4 -4
  89. package/src/managed/Environments.tsx +1 -1
  90. package/src/managed/RelativeTimestamp.tsx +8 -6
  91. package/src/managed/artifactActions/ArtifactActions.tsx +77 -0
  92. package/src/managed/constraints/AllowedTimes.spec.ts +2 -1
  93. package/src/managed/constraints/registry.tsx +27 -1
  94. package/src/managed/environmentBaseElements/BaseEnvironment.less +3 -3
  95. package/src/managed/environmentBaseElements/EnvironmentItem.tsx +11 -4
  96. package/src/managed/graphql/graphql-sdk.ts +218 -29
  97. package/src/managed/graphql/schema.graphql +14 -1
  98. package/src/managed/overview/EnvironmentOverview.tsx +12 -15
  99. package/src/managed/overview/EnvironmentsOverview.less +6 -5
  100. package/src/managed/overview/PreviewEnvironments.tsx +0 -3
  101. package/src/managed/overview/Resource.less +1 -1
  102. package/src/managed/overview/Resource.tsx +62 -47
  103. package/src/managed/overview/artifact/Artifact.less +27 -52
  104. package/src/managed/overview/artifact/Artifact.tsx +86 -22
  105. package/src/managed/overview/artifact/ArtifactActionModal.less +19 -0
  106. package/src/managed/overview/artifact/ArtifactActionModal.tsx +150 -68
  107. package/src/managed/overview/artifact/ArtifactCollapsibleSection.tsx +32 -0
  108. package/src/managed/overview/artifact/ArtifactVersionTasks.tsx +2 -0
  109. package/src/managed/overview/artifact/{PendingVersion.tsx → ArtifactVersions.tsx} +35 -25
  110. package/src/managed/overview/artifact/Constraints.tsx +61 -21
  111. package/src/managed/overview/artifact/CurrentVersion.tsx +42 -27
  112. package/src/managed/overview/artifact/VersionTitle.tsx +18 -0
  113. package/src/managed/overview/artifact/hooks.ts +71 -34
  114. package/src/managed/overview/artifact/useCreateRollbackActions.hook.ts +75 -0
  115. package/src/managed/overview/artifact/utils.spec.ts +1 -1
  116. package/src/managed/overview/artifact/utils.ts +47 -80
  117. package/src/managed/overview/baseStyles.less +124 -88
  118. package/src/managed/overview/queries.graphql +54 -13
  119. package/src/managed/overview/useIsUpdatingResources.hook.ts +9 -0
  120. package/src/managed/resources/ResourceTitle.tsx +12 -5
  121. package/src/managed/utils/ActionModal.tsx +4 -1
  122. package/src/managed/utils/defaults.ts +3 -0
  123. package/src/managed/utils/useNotifyOnError.hook.ts +1 -1
  124. package/src/managed/versionMetadata/MetadataComponents.tsx +102 -70
  125. package/src/managed/versionMetadata/VersionMetadata.less +17 -18
  126. package/src/managed/versionMetadata/VersionMetadata.tsx +23 -31
  127. package/src/managed/versionsHistory/VersionContent.tsx +20 -13
  128. package/src/managed/versionsHistory/VersionHeading.tsx +2 -1
  129. package/src/managed/versionsHistory/VersionsHistory.less +11 -3
  130. package/src/manifest/PodNameProvider.spec.ts +1 -1
  131. package/src/navigation/customParamTypes.spec.ts +1 -1
  132. package/src/pagerDuty/pagerDuty.read.service.spec.ts +4 -2
  133. package/src/pagerDuty/pagerDutyTag.component.spec.ts +7 -3
  134. package/src/pipeline/config/PipelineRegistry.spec.ts +38 -37
  135. package/src/pipeline/config/actions/templateJson/ShowPipelineTemplateJsonModal.spec.tsx +3 -3
  136. package/src/pipeline/config/pipelineConfigurer.controller.spec.ts +3 -3
  137. package/src/pipeline/config/services/PipelineConfigService.spec.ts +4 -3
  138. package/src/pipeline/config/stages/bakeManifest/helm/BakeHelmConfigForm.spec.tsx +51 -8
  139. package/src/pipeline/config/stages/bakeManifest/helm/BakeHelmConfigForm.tsx +36 -6
  140. package/src/pipeline/config/stages/findArtifactFromExecution/findArtifactFromExecution.controller.spec.ts +2 -1
  141. package/src/pipeline/config/stages/manualJudgment/manualJudgment.service.spec.ts +6 -4
  142. package/src/pipeline/config/stages/travis/travisExecutionDetails.controller.spec.ts +5 -2
  143. package/src/pipeline/config/stages/travis/travisStage.controller.spec.ts +3 -2
  144. package/src/pipeline/config/stages/unmatchedStageTypeStage/unmatchedStageTypeStage.controller.spec.ts +2 -1
  145. package/src/pipeline/config/stages/wait/SkipWait.tsx +3 -1
  146. package/src/pipeline/config/stages/wercker/werckerExecutionDetails.controller.spec.ts +5 -2
  147. package/src/pipeline/config/stages/wercker/werckerStage.controller.spec.ts +3 -2
  148. package/src/pipeline/config/templates/Variable.spec.tsx +6 -5
  149. package/src/pipeline/config/templates/configurePipelineTemplateModal.controller.spec.ts +7 -8
  150. package/src/pipeline/config/templates/v2/configurePipelineTemplateModalV2.controller.spec.ts +7 -8
  151. package/src/pipeline/config/templates/v2/pipelineTemplateV2.service.spec.ts +1 -1
  152. package/src/pipeline/config/triggers/TriggersPageContent.spec.tsx +4 -4
  153. package/src/pipeline/config/triggers/TriggersPageContent.tsx +1 -2
  154. package/src/pipeline/config/triggers/artifacts/docker/defaultDocker.artifact.spec.ts +1 -2
  155. package/src/pipeline/config/validation/pipelineConfig.validator.spec.ts +14 -15
  156. package/src/pipeline/create/CreatePipelineModal.spec.tsx +9 -7
  157. package/src/pipeline/details/executionDetailsSection.service.spec.ts +3 -2
  158. package/src/pipeline/executions/Executions.spec.tsx +9 -6
  159. package/src/pipeline/executions/executionAction/ExecutionAction.spec.tsx +1 -1
  160. package/src/pipeline/executions/executionGroup/ExecutionGroup.tsx +2 -1
  161. package/src/pipeline/filter/executionFilter.service.spec.ts +1 -1
  162. package/src/pipeline/pipeline.dataSource.spec.ts +8 -7
  163. package/src/pipeline/service/ExecutionsTransformer.spec.ts +2 -2
  164. package/src/pipeline/service/execution.service.spec.ts +7 -5
  165. package/src/pipeline/status/Artifact.spec.tsx +7 -6
  166. package/src/pipeline/status/ArtifactList.spec.tsx +7 -6
  167. package/src/pipeline/status/ExecutionParameters.spec.tsx +5 -4
  168. package/src/pipeline/status/ResolvedArtifactList.spec.tsx +7 -6
  169. package/src/plugins/deck.plugin.spec.ts +4 -2
  170. package/src/plugins/plugin.registry.spec.ts +6 -4
  171. package/src/presentation/forms/SpinFormik.spec.tsx +3 -2
  172. package/src/presentation/forms/fields/FormikFormField.spec.tsx +3 -3
  173. package/src/presentation/forms/hooks/useSaveRestoreMutuallyExclusiveFields.hook.spec.tsx +4 -3
  174. package/src/presentation/forms/inputs/ChecklistInput.spec.tsx +1 -1
  175. package/src/presentation/forms/inputs/RadioButtonInput.spec.tsx +2 -1
  176. package/src/presentation/forms/inputs/SelectInput.spec.tsx +2 -1
  177. package/src/presentation/forms/inputs/hooks/useInternalValidator.hook.spec.tsx +4 -3
  178. package/src/presentation/forms/validation/FormValidator.spec.ts +2 -2
  179. package/src/presentation/forms/validation/useValidationData.spec.tsx +4 -3
  180. package/src/presentation/hooks/useContainerClassNames.hook.spec.tsx +2 -1
  181. package/src/presentation/hooks/useData.hook.spec.tsx +3 -2
  182. package/src/presentation/hooks/useDebouncedValue.hook.spec.tsx +1 -1
  183. package/src/presentation/hooks/useDeepObjectDiff.hook.spec.tsx +2 -1
  184. package/src/presentation/hooks/useEventListener.hook.spec.tsx +2 -1
  185. package/src/presentation/hooks/useForceUpdate.hook.spec.tsx +2 -1
  186. package/src/presentation/hooks/useInterval.hook.spec.tsx +2 -1
  187. package/src/presentation/hooks/useIsMountedRef.hook.spec.tsx +1 -1
  188. package/src/presentation/hooks/useLatestCallback.hook.spec.tsx +2 -1
  189. package/src/presentation/hooks/useLatestPromise.hook.spec.tsx +9 -3
  190. package/src/presentation/hooks/useMountStatusRef.hook.spec.tsx +3 -1
  191. package/src/presentation/hooks/usePollingData.hook.spec.tsx +3 -2
  192. package/src/presentation/hooks/usePrevious.hook.spec.tsx +2 -1
  193. package/src/presentation/navigation/pageNavigator.component.spec.ts +6 -6
  194. package/src/presentation/spel/SpelInput.spec.tsx +9 -4
  195. package/src/presentation/spel/SpelService.spec.ts +1 -1
  196. package/src/scheduler/SchedulerFactory.spec.ts +2 -1
  197. package/src/search/infrastructure/infrastructure.controller.js +3 -0
  198. package/src/search/infrastructure/infrastructureSearch.service.ts +3 -2
  199. package/src/search/widgets/Filter.spec.tsx +5 -3
  200. package/src/search/widgets/Filters.spec.tsx +5 -3
  201. package/src/search/widgets/Search.spec.tsx +4 -2
  202. package/src/securityGroup/index.ts +2 -1
  203. package/src/securityGroup/securityGroupReader.service.spec.ts +8 -10
  204. package/src/serverGroup/configure/common/deployInitializer.component.spec.ts +7 -3
  205. package/src/serverGroup/configure/common/v2instanceArchetypeSelector.component.ts +1 -1
  206. package/src/serverGroup/details/capacity/CapacityDetailsSection.spec.tsx +1 -1
  207. package/src/serverGroup/details/scalingActivities/ScalingActivitiesModal.spec.ts +2 -1
  208. package/src/serverGroup/details/serverGroupWarningMessage.service.spec.ts +4 -4
  209. package/src/serverGroup/serverGroupWriter.service.spec.ts +10 -8
  210. package/src/slack/SlackReader.spec.ts +2 -1
  211. package/src/subnet/subnet.read.service.spec.ts +4 -3
  212. package/src/task/monitor/taskMonitor.spec.ts +6 -5
  213. package/src/task/task.dataSource.spec.ts +5 -4
  214. package/src/task/task.write.service.spec.ts +3 -1
  215. package/src/utils/clipboard/CopyToClipboard.spec.tsx +2 -1
  216. package/src/utils/json/json.utility.service.spec.ts +2 -1
  217. package/src/utils/timeFormatters.spec.ts +3 -2
  218. package/src/utils/workerPool.spec.ts +2 -1
  219. package/src/widgets/ApplicationsPickerInput.spec.tsx +3 -2
  220. package/src/widgets/spelText/SpelAutocompleteService.spec.ts +4 -3
  221. package/src/widgets/tags/Tag.spec.tsx +4 -2
  222. package/src/widgets/tags/TagList.spec.tsx +5 -3
  223. package/src/yamlEditor/yamlEditorUtils.spec.ts +1 -1
  224. package/dist/managed/overview/artifact/PendingVersion.d.ts +0 -7
@@ -3,14 +3,14 @@ import classnames from 'classnames';
3
3
  import { sortBy } from 'lodash';
4
4
  import type { DateTime } from 'luxon';
5
5
  import React from 'react';
6
- import { Dropdown, MenuItem } from 'react-bootstrap';
7
6
 
8
7
  import type { IconNames } from '@spinnaker/presentation';
9
8
  import { Icon } from '@spinnaker/presentation';
10
9
 
11
- import { RelativeTimestamp } from '../RelativeTimestamp';
10
+ import { formatToRelativeTimestamp, RelativeTimestamp } from '../RelativeTimestamp';
12
11
  import type { LifecycleEventSummary } from '../overview/artifact/utils';
13
- import { Tooltip } from '../../presentation';
12
+ import { HoverablePopover, IconTooltip, LabeledValue, Tooltip } from '../../presentation';
13
+ import { copyTextToClipboard } from '../../utils/clipboard/copyTextToClipboard';
14
14
  import { ABSOLUTE_TIME_FORMAT, TOOLTIP_DELAY_SHOW } from '../utils/defaults';
15
15
  import { useLogEvent } from '../utils/logging';
16
16
 
@@ -20,12 +20,7 @@ export const MetadataElement: React.FC<{ className?: string }> = ({ className, c
20
20
  return <span className={classnames('delimited-element horizontal middle', className)}>{children}</span>;
21
21
  };
22
22
 
23
- export interface VersionAction {
24
- onClick?: () => void;
25
- href?: string;
26
- content: string;
27
- disabled?: boolean;
28
- }
23
+ export const METADATA_TEXT_COLOR = 'nobel';
29
24
 
30
25
  export interface VersionMessageData {
31
26
  by?: string;
@@ -33,6 +28,11 @@ export interface VersionMessageData {
33
28
  comment?: string;
34
29
  }
35
30
 
31
+ export interface ICompareLinks {
32
+ previous?: string;
33
+ current?: string;
34
+ }
35
+
36
36
  export const toPinnedMetadata = (data: {
37
37
  pinnedAt?: string;
38
38
  pinnedBy?: string;
@@ -54,59 +54,28 @@ export const toVetoedMetadata = (data: {
54
54
  });
55
55
 
56
56
  export interface IVersionMetadataProps {
57
- build?: IVersionBuildProps['build'] & Partial<LifecycleEventSummary>;
58
- version: string;
59
- sha?: string;
57
+ build?: IVersionBuildProps['build'];
60
58
  author?: string;
61
59
  deployedAt?: string;
62
- createdAt?: IVersionCreatedAtProps['createdAt'];
63
60
  buildsBehind?: number;
64
61
  isDeploying?: boolean;
62
+ isPending?: boolean;
65
63
  bake?: LifecycleEventSummary;
66
64
  pinned?: VersionMessageData;
67
65
  vetoed?: VersionMessageData;
68
- actions?: VersionAction[];
66
+ isCurrent?: boolean;
69
67
  }
70
68
 
71
- export interface IVersionMetadataActionsProps {
72
- id: string;
73
- actions: VersionAction[];
74
- }
75
-
76
- export const VersionMetadataActions = ({ id, actions }: IVersionMetadataActionsProps) => {
77
- const logEvent = useLogEvent('ArtifactActions');
78
- return (
79
- <MetadataElement>
80
- <Dropdown id={id}>
81
- <Dropdown.Toggle className="element-actions-menu-toggle">Actions</Dropdown.Toggle>
82
- <Dropdown.Menu>
83
- {actions.map((action, index) => (
84
- <MenuItem
85
- key={index}
86
- disabled={action.disabled}
87
- onClick={() => {
88
- action.onClick?.();
89
- logEvent({ action: `OpenModal - ${action.content}` });
90
- }}
91
- href={action.href}
92
- target="_blank"
93
- >
94
- {action.content}
95
- </MenuItem>
96
- ))}
97
- </Dropdown.Menu>
98
- </Dropdown>
99
- </MetadataElement>
100
- );
69
+ const useCreateVersionLink = (linkProps: IVersionCreatedAtProps['linkProps']) => {
70
+ return useSref('home.applications.application.environments.history', linkProps);
101
71
  };
102
-
103
72
  interface IVersionCreatedAtProps {
104
73
  createdAt?: string | DateTime;
105
74
  linkProps: Record<string, string>;
106
75
  }
107
76
 
108
77
  export const VersionCreatedAt = ({ createdAt, linkProps }: IVersionCreatedAtProps) => {
109
- const { href, onClick } = useSref('home.applications.application.environments.history', linkProps);
78
+ const { href } = useCreateVersionLink(linkProps);
110
79
  if (!createdAt) return null;
111
80
 
112
81
  return (
@@ -114,7 +83,13 @@ export const VersionCreatedAt = ({ createdAt, linkProps }: IVersionCreatedAtProp
114
83
  <Tooltip delayShow={TOOLTIP_DELAY_SHOW} value="Created at">
115
84
  <i className="far fa-calendar-alt metadata-icon" />
116
85
  </Tooltip>
117
- <a href={href} onClick={onClick}>
86
+ <a
87
+ href={href}
88
+ onClick={(e) => {
89
+ href && copyTextToClipboard([window.location.origin, href].join('/'));
90
+ e.stopPropagation();
91
+ }}
92
+ >
118
93
  <RelativeTimestamp timestamp={createdAt} delayShow={TOOLTIP_DELAY_SHOW} removeStyles withSuffix />
119
94
  </a>
120
95
  </MetadataElement>
@@ -124,6 +99,7 @@ export const VersionCreatedAt = ({ createdAt, linkProps }: IVersionCreatedAtProp
124
99
  const badgeTypeToDetails = {
125
100
  deploying: { className: 'version-deploying', text: 'Deploying' },
126
101
  baking: { className: 'version-baking', text: 'Baking' },
102
+ deployed: { className: 'version-deployed', text: 'Live' },
127
103
  };
128
104
 
129
105
  interface IMetadataBadgeProps {
@@ -168,7 +144,7 @@ const versionTypeProps: { [key in IVersionMessage['type']]: { text: string; clas
168
144
  icon: 'pin',
169
145
  },
170
146
  vetoed: {
171
- text: 'Marked as bad by',
147
+ text: 'Rejected by',
172
148
  className: 'version-vetoed',
173
149
  icon: 'artifactBad',
174
150
  },
@@ -180,7 +156,7 @@ export const VersionMessage = ({ data, type, newRow = true }: IVersionMessage) =
180
156
  <>
181
157
  {newRow && <div className="flex-break sp-margin-s-top" />}
182
158
  <div className={classnames('version-message', typeProps.className)}>
183
- <Icon name={typeProps.icon} size="14px" color="black" className="sp-margin-2xs-top" />
159
+ <Icon name={typeProps.icon} size="14px" color={METADATA_TEXT_COLOR} className="sp-margin-2xs-top" />
184
160
  <div>
185
161
  <div>
186
162
  {typeProps.text} {data.by},{' '}
@@ -212,21 +188,21 @@ export const VersionBranch = ({ branch }: IVersionBranchProps) => {
212
188
  if (!branch) return null;
213
189
  return (
214
190
  <MetadataElement>
215
- <Icon name="spCIBranch" size="11px" className="sp-margin-xs-right" color="concrete" /> {branch}
191
+ <Icon name="spCIBranch" size="11px" className="sp-margin-xs-right" color={METADATA_TEXT_COLOR} /> {branch}
216
192
  </MetadataElement>
217
193
  );
218
194
  };
219
195
 
220
196
  interface IVersionBuildProps {
221
- build: { buildNumber?: string; buildLink?: string; version?: string };
197
+ build: { buildNumber?: string; version?: string } & Partial<LifecycleEventSummary>;
222
198
  withPrefix?: boolean;
223
199
  }
224
200
 
225
201
  export const VersionBuild = ({ build, withPrefix }: IVersionBuildProps) => {
226
202
  const logEvent = useLogEvent('ArtifactBuild', 'OpenBuild');
227
203
  const text = `${withPrefix ? `Build ` : ''}#${build.buildNumber}`;
228
- const content = build.buildLink ? (
229
- <a href={build.buildLink} onClick={() => logEvent({ data: { build: build.buildNumber } })}>
204
+ const content = build.link ? (
205
+ <a href={build.link} onClick={() => logEvent({ data: { build: build.buildNumber } })}>
230
206
  {text}
231
207
  </a>
232
208
  ) : (
@@ -234,9 +210,12 @@ export const VersionBuild = ({ build, withPrefix }: IVersionBuildProps) => {
234
210
  );
235
211
 
236
212
  return build.version ? (
237
- <Tooltip value={build.version} delayShow={TOOLTIP_DELAY_SHOW}>
213
+ <HoverablePopover
214
+ Component={() => <LifecycleEventDetails {...build} title="Build" showLink={false} />}
215
+ delayShow={TOOLTIP_DELAY_SHOW}
216
+ >
238
217
  <span>{content}</span>
239
- </Tooltip>
218
+ </HoverablePopover>
240
219
  ) : (
241
220
  <>{content}</>
242
221
  );
@@ -274,30 +253,83 @@ export const BaseVersionMetadata: React.FC = ({ children }) => {
274
253
 
275
254
  interface ILifecycleEventDetailsProps extends Partial<LifecycleEventSummary> {
276
255
  title: string;
256
+ showLink?: boolean;
257
+ version?: string;
277
258
  }
278
259
 
279
- export const LifecycleEventDetails = ({ duration, link, startedAt, title }: ILifecycleEventDetailsProps) => {
260
+ export const LifecycleEventDetails = ({
261
+ version,
262
+ duration,
263
+ link,
264
+ startedAt,
265
+ title,
266
+ showLink = true,
267
+ }: ILifecycleEventDetailsProps) => {
280
268
  return (
281
269
  <div className="LifecycleEventDetails">
282
270
  <div>
283
271
  <div className="title sp-margin-xs-bottom">{title}</div>
284
272
  <dl className="details sp-margin-s-bottom">
285
- <dt>Started at</dt>
286
- <dd>{startedAt?.toFormat(ABSOLUTE_TIME_FORMAT) || 'N/A'}</dd>
287
-
288
- <dt>Duration</dt>
289
- <dd>{duration || 'N/A'}</dd>
290
-
291
- {link && (
292
- <>
293
- <dt>Link</dt>
294
- <dd>
295
- <a href={link}>Open</a>
296
- </dd>
297
- </>
298
- )}
273
+ {version && <LabeledValue label="Version" value={version} />}
274
+ <LabeledValue
275
+ label="Started at"
276
+ value={
277
+ `${startedAt?.toFormat(ABSOLUTE_TIME_FORMAT) || 'N/A'}` +
278
+ ` ` +
279
+ `${startedAt ? ` (${formatToRelativeTimestamp(startedAt, true)})` : ''}`
280
+ }
281
+ />
282
+ <LabeledValue label="Duration" value={duration || 'N/A'} />
283
+ {showLink && link && <LabeledValue label="Link" value={<a href={link}>Open</a>} />}
299
284
  </dl>
300
285
  </div>
301
286
  </div>
302
287
  );
303
288
  };
289
+
290
+ type IDeploymentStatusProps = Pick<IVersionMetadataProps, 'deployedAt' | 'isPending' | 'isCurrent' | 'isDeploying'>;
291
+
292
+ const statusToProps = {
293
+ CURRENT: {
294
+ icon: 'cloudDeployed',
295
+ tooltip: 'Deployed at',
296
+ },
297
+ PENDING: {
298
+ icon: 'cloudWaiting',
299
+ tooltip: 'Deployment pending',
300
+ },
301
+ PREVIOUS: {
302
+ icon: 'cloudDecommissioned',
303
+ tooltip: 'Replaced by another version',
304
+ },
305
+ SKIPPED: {
306
+ icon: 'artifactSkipped',
307
+ tooltip: 'Deployment skipped',
308
+ },
309
+ } as const;
310
+
311
+ export const DeploymentStatus = ({ deployedAt, isCurrent, isPending, isDeploying }: IDeploymentStatusProps) => {
312
+ if (!deployedAt && isDeploying) return null; // We'll show the deploying badge so no reason to show this component if this version is being deployed for the first time
313
+ const props = statusToProps[deployedAt ? (isCurrent ? 'CURRENT' : 'PREVIOUS') : isPending ? 'PENDING' : 'SKIPPED'];
314
+ return (
315
+ <MetadataElement>
316
+ <IconTooltip
317
+ tooltip={props.tooltip}
318
+ name={props.icon}
319
+ size="14px"
320
+ wrapperClassName="metadata-icon"
321
+ delayShow={TOOLTIP_DELAY_SHOW}
322
+ color={METADATA_TEXT_COLOR}
323
+ />
324
+ {deployedAt ? (
325
+ <>
326
+ Deployed <RelativeTimestamp timestamp={deployedAt} delayShow={TOOLTIP_DELAY_SHOW} removeStyles withSuffix />
327
+ </>
328
+ ) : isPending ? (
329
+ 'Pending'
330
+ ) : (
331
+ 'Not deployed'
332
+ )}
333
+ </MetadataElement>
334
+ );
335
+ };
@@ -1,15 +1,18 @@
1
+ @textColor: var(--color-nobel);
2
+
1
3
  .VersionMetadata {
2
4
  display: flex;
3
5
  flex-direction: row;
4
6
  align-items: center;
5
- margin-top: var(--xs-spacing);
6
- color: var(--color-concrete);
7
+ margin-top: 6px;
8
+ color: @textColor;
7
9
  white-space: pre-wrap;
8
10
  font-size: 13px;
9
11
  flex-wrap: wrap;
12
+ line-height: 1.6;
10
13
 
11
14
  i {
12
- color: var(--color-concrete);
15
+ color: @textColor;
13
16
  }
14
17
 
15
18
  .HoverablePopover {
@@ -29,25 +32,17 @@
29
32
  font-size: 12px;
30
33
  }
31
34
 
32
- .element-actions-menu-toggle {
33
- padding: 0 var(--xs-spacing);
34
- border: none;
35
- font-size: inherit;
36
- &:not(:hover) {
37
- background-color: transparent;
38
- }
39
- }
40
-
41
35
  .version-badge {
42
36
  border-radius: 3px;
43
- padding: 0 var(--s-spacing);
37
+ padding: 1px var(--s-spacing) 0;
44
38
  display: flex;
45
- min-width: 60px;
39
+ min-width: 50px;
46
40
  justify-content: center;
47
41
  flex-direction: row;
48
- & > svg {
49
- margin-right: 4px;
50
- }
42
+ text-transform: uppercase;
43
+ font-weight: 700;
44
+ font-size: 12px;
45
+ letter-spacing: 0.4px;
51
46
  }
52
47
 
53
48
  .version-deploying {
@@ -60,6 +55,11 @@
60
55
  color: var(--color-black);
61
56
  }
62
57
 
58
+ .version-deployed {
59
+ background-color: var(--color-status-success);
60
+ color: var(--color-white);
61
+ }
62
+
63
63
  .version-pinned {
64
64
  background-color: var(--color-status-warning-light);
65
65
  }
@@ -99,7 +99,6 @@
99
99
  align-items: baseline;
100
100
 
101
101
  dt {
102
- font-weight: normal;
103
102
  text-transform: uppercase;
104
103
  font-size: 13px;
105
104
  color: var(--color-concrete);
@@ -1,38 +1,45 @@
1
1
  import React from 'react';
2
2
 
3
3
  import type { IVersionMetadataProps } from './MetadataComponents';
4
+ import { METADATA_TEXT_COLOR } from './MetadataComponents';
4
5
  import {
5
6
  BaseVersionMetadata,
7
+ DeploymentStatus,
6
8
  LifecycleEventDetails,
7
9
  MetadataBadge,
8
10
  MetadataElement,
9
11
  toVetoedMetadata,
10
12
  VersionAuthor,
11
13
  VersionBuilds,
12
- VersionCreatedAt,
13
14
  VersionMessage,
14
- VersionMetadataActions,
15
15
  } from './MetadataComponents';
16
- import { formatToRelativeTimestamp, RelativeTimestamp } from '../RelativeTimestamp';
17
- import { getLifecycleEventSummary } from '../overview/artifact/utils';
16
+ import { formatToRelativeTimestamp } from '../RelativeTimestamp';
17
+ import { getLifecycleEventSummary, isVersionPending } from '../overview/artifact/utils';
18
18
  import type { QueryArtifactVersion } from '../overview/types';
19
- import { HoverablePopover, IconTooltip } from '../../presentation';
20
- import { TOOLTIP_DELAY_SHOW } from '../utils/defaults';
19
+ import { HoverablePopover, Icon } from '../../presentation';
21
20
  import type { SingleVersionArtifactVersion } from '../versionsHistory/types';
22
21
 
22
+ export const getVersionCompareLinks = (version: QueryArtifactVersion | SingleVersionArtifactVersion) => {
23
+ return {
24
+ current: version.gitMetadata?.comparisonLinks?.toCurrentVersion,
25
+ previous: version.gitMetadata?.comparisonLinks?.toPreviousVersion,
26
+ };
27
+ };
28
+
23
29
  export const getBaseMetadata = (
24
30
  version: QueryArtifactVersion | SingleVersionArtifactVersion,
25
- ): Omit<Partial<IVersionMetadataProps>, 'version'> & Pick<IVersionMetadataProps, 'version'> => {
31
+ ): Partial<IVersionMetadataProps> => {
32
+ // The return type above makes everything optional except for the version
26
33
  return {
27
- version: version.version,
28
- sha: version.gitMetadata?.commit,
29
34
  build: {
30
35
  buildNumber: version.buildNumber,
31
36
  version: version.version,
32
37
  ...getLifecycleEventSummary(version, 'BUILD'),
33
38
  },
34
39
  author: version.gitMetadata?.author,
40
+ isPending: isVersionPending(version),
35
41
  deployedAt: version.deployedAt,
42
+ isCurrent: version.isCurrent,
36
43
  isDeploying: version.status === 'DEPLOYING',
37
44
  bake: getLifecycleEventSummary(version, 'BAKE'),
38
45
  vetoed: version.veto ? toVetoedMetadata(version.veto) : undefined,
@@ -40,21 +47,20 @@ export const getBaseMetadata = (
40
47
  };
41
48
 
42
49
  export const VersionMetadata = ({
43
- version,
44
- sha,
45
50
  build,
46
51
  author,
47
52
  deployedAt,
48
- createdAt,
53
+ isPending,
54
+ isCurrent,
55
+ isDeploying,
49
56
  buildsBehind,
50
57
  bake,
51
- isDeploying,
52
58
  pinned,
53
59
  vetoed,
54
- actions,
55
60
  }: IVersionMetadataProps) => {
56
61
  return (
57
62
  <BaseVersionMetadata>
63
+ {isCurrent && <MetadataBadge type="deployed" />}
58
64
  {isDeploying && <MetadataBadge type="deploying" />}
59
65
  {bake?.isRunning && (
60
66
  <MetadataBadge
@@ -65,20 +71,8 @@ export const VersionMetadata = ({
65
71
  )}
66
72
  {build?.buildNumber && <VersionBuilds builds={[build]} />}
67
73
  <VersionAuthor author={author} />
68
- <VersionCreatedAt createdAt={createdAt} linkProps={sha ? { sha } : { version }} />
69
- {deployedAt && (
70
- <MetadataElement>
71
- <IconTooltip
72
- tooltip="Deployed at"
73
- name="cloudDeployed"
74
- size="12px"
75
- wrapperClassName="metadata-icon"
76
- delayShow={TOOLTIP_DELAY_SHOW}
77
- />
78
- <RelativeTimestamp timestamp={deployedAt} delayShow={TOOLTIP_DELAY_SHOW} removeStyles withSuffix />
79
- </MetadataElement>
80
- )}
81
- {(build?.duration || bake?.duration) && (
74
+ <DeploymentStatus {...{ deployedAt, isCurrent, isPending, isDeploying }} />
75
+ {bake?.duration && (
82
76
  <MetadataElement>
83
77
  <HoverablePopover
84
78
  delayShow={200}
@@ -86,11 +80,10 @@ export const VersionMetadata = ({
86
80
  Component={() => (
87
81
  <>
88
82
  <LifecycleEventDetails title="Bake" {...bake} />
89
- <LifecycleEventDetails title="Build" {...build} />
90
83
  </>
91
84
  )}
92
85
  >
93
- <i className="fas fa-info-circle " />
86
+ <Icon name="bake" size="13px" color={METADATA_TEXT_COLOR} />
94
87
  </HoverablePopover>
95
88
  </MetadataElement>
96
89
  )}
@@ -99,7 +92,6 @@ export const VersionMetadata = ({
99
92
  {buildsBehind} build{buildsBehind > 1 ? 's' : ''} behind
100
93
  </MetadataElement>
101
94
  ) : null}
102
- {actions && <VersionMetadataActions id={`${build?.buildNumber}-actions`} actions={actions} />}
103
95
  {pinned && <VersionMessage type="pinned" data={pinned} />}
104
96
  {vetoed && <VersionMessage type="vetoed" data={vetoed} />}
105
97
  </BaseVersionMetadata>
@@ -1,6 +1,7 @@
1
1
  import { flatten, omit, uniq } from 'lodash';
2
2
  import React from 'react';
3
3
 
4
+ import { ArtifactActions } from '../artifactActions/ArtifactActions';
4
5
  import { BaseEnvironment } from '../environmentBaseElements/BaseEnvironment';
5
6
  import { EnvironmentItem } from '../environmentBaseElements/EnvironmentItem';
6
7
  import { EnvironmentsRender, useOrderedEnvironment } from '../environmentBaseElements/EnvironmentsRender';
@@ -9,7 +10,8 @@ import { useFetchVersionQuery } from '../graphql/graphql-sdk';
9
10
  import type { ITaskArtifactVersionProps } from '../overview/artifact/ArtifactVersionTasks';
10
11
  import { ArtifactVersionTasks } from '../overview/artifact/ArtifactVersionTasks';
11
12
  import { Constraints } from '../overview/artifact/Constraints';
12
- import { useCreateVersionActions } from '../overview/artifact/utils';
13
+ import { useCreateVersionRollbackActions } from '../overview/artifact/useCreateRollbackActions.hook';
14
+ import { extractVersionRollbackDetails, isVersionVetoed } from '../overview/artifact/utils';
13
15
  import { useApplicationContextSafe } from '../../presentation';
14
16
  import { LoadingAnimation } from '../../presentation/LoadingAnimation';
15
17
  import type {
@@ -20,12 +22,13 @@ import type {
20
22
  } from './types';
21
23
  import type { VersionMessageData } from '../versionMetadata/MetadataComponents';
22
24
  import { toPinnedMetadata } from '../versionMetadata/MetadataComponents';
23
- import { getBaseMetadata, VersionMetadata } from '../versionMetadata/VersionMetadata';
25
+ import { getBaseMetadata, getVersionCompareLinks, VersionMetadata } from '../versionMetadata/VersionMetadata';
24
26
 
25
27
  import './VersionsHistory.less';
26
28
 
27
29
  interface IVersionInEnvironmentProps {
28
30
  environment: string;
31
+ isPreview?: boolean;
29
32
  version: HistoryArtifactVersionExtended;
30
33
  envPinnedVersions?: PinnedVersions[keyof PinnedVersions];
31
34
  loading: boolean;
@@ -35,6 +38,7 @@ interface IVersionInEnvironmentProps {
35
38
  const VersionInEnvironment = ({
36
39
  environment,
37
40
  version,
41
+ isPreview,
38
42
  envPinnedVersions,
39
43
  detailedVersionData,
40
44
  loading,
@@ -45,18 +49,14 @@ const VersionInEnvironment = ({
45
49
  pinnedData = toPinnedMetadata(currentPinnedVersion);
46
50
  }
47
51
 
48
- const actions = useCreateVersionActions({
52
+ const actions = useCreateVersionRollbackActions({
49
53
  environment,
50
54
  reference: version.reference,
51
55
  version: version.version,
52
- buildNumber: version.buildNumber,
53
- status: version.status,
54
- commitMessage: version.gitMetadata?.commitInfo?.message,
56
+ isVetoed: isVersionVetoed(version),
55
57
  isPinned: Boolean(pinnedData),
56
- compareLinks: {
57
- previous: detailedVersionData?.gitMetadata?.comparisonLinks?.toPreviousVersion,
58
- current: detailedVersionData?.gitMetadata?.comparisonLinks?.toCurrentVersion,
59
- },
58
+ isCurrent: version.isCurrent,
59
+ selectedVersion: extractVersionRollbackDetails(version),
60
60
  });
61
61
 
62
62
  const versionProps: ITaskArtifactVersionProps = {
@@ -75,12 +75,18 @@ const VersionInEnvironment = ({
75
75
  >
76
76
  <VersionMetadata
77
77
  key={version.id}
78
- version={version.version}
79
78
  {...(detailedVersionData ? omit(getBaseMetadata(detailedVersionData), 'author', 'buildDuration') : undefined)}
80
- actions={actions}
81
79
  pinned={pinnedData}
82
80
  />
83
-
81
+ {!isPreview && (
82
+ <ArtifactActions
83
+ buildNumber={version.buildNumber}
84
+ version={version.version}
85
+ actions={actions}
86
+ compareLinks={detailedVersionData ? getVersionCompareLinks(detailedVersionData) : undefined}
87
+ className="sp-margin-s-yaxis"
88
+ />
89
+ )}
84
90
  {loading && <LoadingAnimation />}
85
91
  <Constraints
86
92
  constraints={detailedVersionData?.constraints}
@@ -144,6 +150,7 @@ export const VersionContent = ({ versionData, pinnedVersions }: IVersionContentP
144
150
  environment={env}
145
151
  key={version.id}
146
152
  version={version}
153
+ isPreview={isPreview}
147
154
  envPinnedVersions={pinnedVersions?.[env]}
148
155
  loading={loading}
149
156
  detailedVersionData={getDetailedVersionData({ environment: env, version, versionsDetails })}
@@ -73,7 +73,7 @@ const statusToText: { [key in VersionStatus]: string } = {
73
73
  VETOED: `Marked as bad`,
74
74
  PREVIOUS: `Previously deployed`,
75
75
  DEPLOYING: `Deploying`,
76
- SKIPPED: 'Skipped',
76
+ SKIPPED: 'Not deployed',
77
77
  };
78
78
 
79
79
  const secondaryStatusToIcon: { [key in VersionStatus]?: string } = {
@@ -137,6 +137,7 @@ const EnvironmentBadge = ({ name, data: { isPreview, versions, gitMetadata, isPi
137
137
  const isCurrent = getIsCurrent(versions);
138
138
  const statusClassName = statusToClassName[isCurrent ? 'CURRENT' : statusSummary];
139
139
  const statusText = statusToText[statusSummary];
140
+
140
141
  // In case that the status is different than CURRENT (e.g. when you veto the CURRENT version), we want to show that as well
141
142
  const hasSecondaryStatus = Boolean(isCurrent && statusSummary !== 'CURRENT');
142
143
  const secondaryIcon = hasSecondaryStatus ? secondaryStatusToIcon[statusSummary] : undefined;
@@ -117,15 +117,23 @@
117
117
  }
118
118
 
119
119
  &.skipped {
120
+ @stripesColor: var(--color-silver);
121
+ @baseColor: var(--color-white);
120
122
  border: 1px solid var(--color-silver);
123
+ background-image: linear-gradient(
124
+ to top right,
125
+ @baseColor calc(50% - 1px),
126
+ @stripesColor,
127
+ @baseColor calc(50% + 1px)
128
+ );
121
129
  }
122
130
 
123
131
  &.approved {
124
- background-color: var(--color-status-progress);
132
+ background-color: var(--color-status-progress-light);
125
133
  }
126
134
 
127
135
  &.pending {
128
- background-color: var(--color-status-progress);
136
+ background-color: var(--color-status-progress-light);
129
137
  }
130
138
 
131
139
  &.vetoed {
@@ -137,7 +145,7 @@
137
145
  }
138
146
 
139
147
  &.previous {
140
- background-color: var(--color-status-neutral);
148
+ background-color: rgba(43%, 84%, 43%, 0.2);
141
149
  }
142
150
 
143
151
  &.deploying {
@@ -1,5 +1,5 @@
1
1
  import { DefaultPodNameProvider, JobEventBasedPodNameProvider } from './PodNameProvider';
2
- import { IManifest, IManifestEvent } from '../domain';
2
+ import type { IManifest, IManifestEvent } from '../domain';
3
3
 
4
4
  describe('PodNameProvider', function () {
5
5
  describe('DefaultPodNameProvider', function () {
@@ -1,4 +1,4 @@
1
- import { trueKeyObjectParamType, booleanParamType, inverseBooleanParamType, sortKeyParamType } from './state.provider';
1
+ import { booleanParamType, inverseBooleanParamType, sortKeyParamType, trueKeyObjectParamType } from './state.provider';
2
2
 
3
3
  describe('custom param types', () => {
4
4
  describe('trueKeyObject', () => {
@@ -1,6 +1,8 @@
1
- import { mockHttpClient } from '../api/mock/jasmine';
2
1
  import { mock } from 'angular';
3
- import { IPagerDutyService, PagerDutyReader } from './pagerDuty.read.service';
2
+
3
+ import { mockHttpClient } from '../api/mock/jasmine';
4
+ import type { IPagerDutyService } from './pagerDuty.read.service';
5
+ import { PagerDutyReader } from './pagerDuty.read.service';
4
6
 
5
7
  describe('PagerDutyReader', () => {
6
8
  beforeEach(mock.module());
@@ -1,7 +1,11 @@
1
+ import type { IComponentControllerService } from 'angular';
2
+ import { mock } from 'angular';
1
3
  import { of as observableOf } from 'rxjs';
2
- import { IComponentControllerService, mock } from 'angular';
3
- import { IPagerDutyService, PagerDutyReader } from './pagerDuty.read.service';
4
- import { PAGER_DUTY_TAG_COMPONENT, PagerDutyTagComponentController } from './pagerDutyTag.component';
4
+
5
+ import type { IPagerDutyService } from './pagerDuty.read.service';
6
+ import { PagerDutyReader } from './pagerDuty.read.service';
7
+ import type { PagerDutyTagComponentController } from './pagerDutyTag.component';
8
+ import { PAGER_DUTY_TAG_COMPONENT } from './pagerDutyTag.component';
5
9
 
6
10
  describe('PagerDutyTagComponent', () => {
7
11
  let $componentController: IComponentControllerService, $ctrl: PagerDutyTagComponentController;