@teambit/component.ui.version-dropdown 0.0.785 → 0.0.787

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 (33) hide show
  1. package/dist/index.d.ts +3 -1
  2. package/dist/index.js +1 -0
  3. package/dist/index.js.map +1 -1
  4. package/dist/{preview-1686886045563.js → preview-1687362266169.js} +2 -2
  5. package/dist/version-dropdown-placeholder.d.ts +11 -5
  6. package/dist/version-dropdown-placeholder.js +49 -32
  7. package/dist/version-dropdown-placeholder.js.map +1 -1
  8. package/dist/version-dropdown-placeholder.module.scss +21 -71
  9. package/dist/version-dropdown.composition.js +6 -2
  10. package/dist/version-dropdown.composition.js.map +1 -1
  11. package/dist/version-dropdown.d.ts +36 -8
  12. package/dist/version-dropdown.docs.d.ts +3 -4
  13. package/dist/version-dropdown.js +73 -30
  14. package/dist/version-dropdown.js.map +1 -1
  15. package/dist/version-dropdown.module.scss +17 -2
  16. package/dist/version-dropdown.spec.js +9 -9
  17. package/dist/version-dropdown.spec.js.map +1 -1
  18. package/dist/version-info/version-info.d.ts +9 -2
  19. package/dist/version-info/version-info.js +17 -8
  20. package/dist/version-info/version-info.js.map +1 -1
  21. package/dist/version-info/version-info.module.scss +16 -10
  22. package/index.ts +3 -1
  23. package/package-tar/teambit-component.ui.version-dropdown-0.0.787.tgz +0 -0
  24. package/package.json +7 -5
  25. package/version-dropdown-placeholder.module.scss +21 -71
  26. package/version-dropdown-placeholder.tsx +77 -54
  27. package/version-dropdown.composition.tsx +13 -2
  28. package/version-dropdown.module.scss +17 -2
  29. package/version-dropdown.spec.tsx +10 -9
  30. package/version-dropdown.tsx +207 -94
  31. package/version-info/version-info.module.scss +16 -10
  32. package/version-info/version-info.tsx +35 -21
  33. package/package-tar/teambit-component.ui.version-dropdown-0.0.785.tgz +0 -0
@@ -28,10 +28,11 @@
28
28
  margin-bottom: 2px;
29
29
  }
30
30
 
31
- .versionContainer {
31
+ .versionContainerRoot {
32
32
  max-height: 240px;
33
33
  overflow-y: scroll;
34
34
  padding-bottom: 8px;
35
+ position: relative;
35
36
  }
36
37
 
37
38
  .versionRow {
@@ -103,5 +104,19 @@
103
104
  }
104
105
 
105
106
  .loading {
106
- color: var(--bit-bg-heavy, #f6f6f6);
107
+ color: var(--bit-bg-dent, #f6f6f6);
108
+ }
109
+
110
+ .loader {
111
+ color: var(--bit-bg-dent, #f6f6f6);
112
+ > div {
113
+ padding: 8px 0px;
114
+ }
115
+ }
116
+
117
+ .versionMenuContainer {
118
+ display: initial;
119
+ &.hide {
120
+ display: none;
121
+ }
107
122
  }
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import { render } from '@testing-library/react';
2
+ import { render, screen } from '@testing-library/react';
3
3
  import { expect } from 'chai';
4
4
  import { VersionDropdownWithOneVersion, VersionDropdownWithMultipleVersions } from './version-dropdown.composition';
5
5
  describe('version dropdown tests', () => {
@@ -15,14 +15,14 @@ describe('version dropdown tests', () => {
15
15
  const textVersion = getByText(/^0.1$/);
16
16
  expect(textVersion).to.exist;
17
17
  });
18
- it('should return multiple versions', () => {
19
- const { getByText, getAllByText } = render(React.createElement(VersionDropdownWithMultipleVersions, null));
20
- const textVersionOne = getByText(/^0.1$/);
21
- const textVersionTwo = getByText(/^0.2$/);
22
- const textVersionThree = getAllByText(/^0.3$/);
23
- expect(textVersionOne).to.exist;
24
- expect(textVersionTwo).to.exist;
25
- expect(textVersionThree).to.exist;
18
+ it('should not return multiple versions when mounted (lazy loading)', () => {
19
+ render(React.createElement(VersionDropdownWithMultipleVersions, null));
20
+ const textVersionOne = screen.queryByText(/^0.1$/);
21
+ const textVersionTwo = screen.queryByText(/^0.2$/);
22
+ const textVersionThree = screen.getAllByText(/^0.3$/);
23
+ expect(textVersionOne).to.be.null;
24
+ expect(textVersionTwo).to.be.null;
25
+ expect(textVersionThree).to.have.lengthOf.at.least(1);
26
26
  });
27
27
  });
28
28
  //# sourceMappingURL=version-dropdown.spec.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"version-dropdown.spec.js","sourceRoot":"","sources":["../version-dropdown.spec.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAChD,OAAO,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAC9B,OAAO,EAAE,6BAA6B,EAAE,mCAAmC,EAAE,MAAM,gCAAgC,CAAC;AAEpH,QAAQ,CAAC,wBAAwB,EAAE,GAAG,EAAE;IACtC;;;SAGK;IACL,UAAU,CAAC,GAAG,EAAE;QACd,OAAO,CAAC,SAAS,CAAC,cAAc,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC;IAC/C,CAAC,CAAC,CAAC;IACH,EAAE,CAAC,2BAA2B,EAAE,GAAG,EAAE;QACnC,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,CAAC,oBAAC,6BAA6B,OAAG,CAAC,CAAC;QAChE,MAAM,WAAW,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC;QACvC,MAAM,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC;IAC/B,CAAC,CAAC,CAAC;IACH,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE;QACzC,MAAM,EAAE,SAAS,EAAE,YAAY,EAAE,GAAG,MAAM,CAAC,oBAAC,mCAAmC,OAAG,CAAC,CAAC;QACpF,MAAM,cAAc,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC;QAC1C,MAAM,cAAc,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC;QAC1C,MAAM,gBAAgB,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC;QAC/C,MAAM,CAAC,cAAc,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC;QAChC,MAAM,CAAC,cAAc,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC;QAChC,MAAM,CAAC,gBAAgB,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC;IACpC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"version-dropdown.spec.js","sourceRoot":"","sources":["../version-dropdown.spec.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAC9B,OAAO,EAAE,6BAA6B,EAAE,mCAAmC,EAAE,MAAM,gCAAgC,CAAC;AAEpH,QAAQ,CAAC,wBAAwB,EAAE,GAAG,EAAE;IACtC;;;SAGK;IACL,UAAU,CAAC,GAAG,EAAE;QACd,OAAO,CAAC,SAAS,CAAC,cAAc,GAAG,IAAI,CAAC,EAAE,EAAE,CAAC;IAC/C,CAAC,CAAC,CAAC;IACH,EAAE,CAAC,2BAA2B,EAAE,GAAG,EAAE;QACnC,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,CAAC,oBAAC,6BAA6B,OAAG,CAAC,CAAC;QAChE,MAAM,WAAW,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC;QACvC,MAAM,CAAC,WAAW,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC;IAC/B,CAAC,CAAC,CAAC;IACH,EAAE,CAAC,iEAAiE,EAAE,GAAG,EAAE;QACzE,MAAM,CAAC,oBAAC,mCAAmC,OAAG,CAAC,CAAC;QAChD,MAAM,cAAc,GAAG,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;QACnD,MAAM,cAAc,GAAG,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;QACnD,MAAM,gBAAgB,GAAG,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;QAEtD,MAAM,CAAC,cAAc,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC;QAClC,MAAM,CAAC,cAAc,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC;QAClC,MAAM,CAAC,gBAAgB,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACxD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -1,4 +1,4 @@
1
- /// <reference types="react" />
1
+ import React from 'react';
2
2
  import { DropdownComponentVersion } from '../version-dropdown';
3
3
  export declare type VersionInfoProps = DropdownComponentVersion & {
4
4
  currentVersion?: string;
@@ -6,4 +6,11 @@ export declare type VersionInfoProps = DropdownComponentVersion & {
6
6
  overrideVersionHref?: (version: string) => string;
7
7
  showDetails?: boolean;
8
8
  };
9
- export declare function VersionInfo({ version, currentVersion, latestVersion, date, username, email, overrideVersionHref, showDetails, message, tag, }: VersionInfoProps): JSX.Element;
9
+ export declare const VersionInfo: React.MemoExoticComponent<React.ForwardRefExoticComponent<Partial<import("@teambit/legacy-component-log").LegacyComponentLog> & {
10
+ version: string;
11
+ } & {
12
+ currentVersion?: string;
13
+ latestVersion?: string;
14
+ overrideVersionHref?: (version: string) => string;
15
+ showDetails?: boolean;
16
+ } & React.RefAttributes<HTMLDivElement>>>;
@@ -6,14 +6,17 @@ import { UserAvatar } from '@teambit/design.ui.avatar';
6
6
  import { Ellipsis } from '@teambit/design.ui.styles.ellipsis';
7
7
  import classNames from 'classnames';
8
8
  import styles from './version-info.module.scss';
9
- export function VersionInfo({ version, currentVersion, latestVersion, date, username, email, overrideVersionHref, showDetails, message, tag, }) {
9
+ export const VersionInfo = React.memo(React.forwardRef(_VersionInfo));
10
+ function _VersionInfo({ version, currentVersion, latestVersion, date, username, displayName, email, overrideVersionHref, showDetails, message, tag, profileImage, }, ref) {
10
11
  const isCurrent = version === currentVersion;
11
12
  const author = useMemo(() => {
12
13
  return {
13
- displayName: username,
14
+ displayName: displayName !== null && displayName !== void 0 ? displayName : '',
14
15
  email,
16
+ name: username !== null && username !== void 0 ? username : '',
17
+ profileImage,
15
18
  };
16
- }, [version]);
19
+ }, [displayName, email, username, profileImage]);
17
20
  const timestamp = useMemo(() => (date ? new Date(parseInt(date)).toString() : new Date().toString()), [date]);
18
21
  const currentVersionRef = useRef(null);
19
22
  useEffect(() => {
@@ -23,17 +26,23 @@ export function VersionInfo({ version, currentVersion, latestVersion, date, user
23
26
  }
24
27
  }, [isCurrent]);
25
28
  const href = overrideVersionHref ? overrideVersionHref(version) : `?version=${version}`;
26
- return (React.createElement("div", { ref: currentVersionRef },
29
+ const formattedVersion = useMemo(() => {
30
+ return tag ? version : version.slice(0, 6);
31
+ }, [tag, version]);
32
+ const isLatest = version === latestVersion;
33
+ return (React.createElement("div", { ref: ref || currentVersionRef },
27
34
  React.createElement(MenuLinkItem, { active: isCurrent, href: href, className: styles.versionRow },
28
35
  React.createElement("div", { className: styles.version },
29
36
  React.createElement(UserAvatar, { size: 24, account: author, className: styles.versionUserAvatar, showTooltip: true }),
30
- React.createElement(Ellipsis, { className: classNames(styles.versionName, tag && styles.tag, !tag && styles.snap) }, version),
31
- version === latestVersion && React.createElement(VersionLabel, { className: styles.label, status: "latest" }),
32
- showDetails && commitMessage(message)),
37
+ React.createElement(Ellipsis, { className: classNames(styles.versionName) }, formattedVersion),
38
+ isLatest && React.createElement(VersionLabel, { status: "latest" }),
39
+ React.createElement(CommitMessage, { message: message, showDetails: showDetails })),
33
40
  React.createElement(Ellipsis, { className: styles.versionTimestamp },
34
41
  React.createElement(TimeAgo, { date: timestamp })))));
35
42
  }
36
- function commitMessage(message) {
43
+ function CommitMessage({ message, showDetails }) {
44
+ if (!showDetails)
45
+ return null;
37
46
  if (!message || message === '')
38
47
  return React.createElement(Ellipsis, { className: styles.emptyMessage }, "No commit message");
39
48
  return React.createElement(Ellipsis, { className: styles.commitMessage }, message);
@@ -1 +1 @@
1
- {"version":3,"file":"version-info.js","sourceRoot":"","sources":["../../version-info/version-info.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"version-info.js","sourceRoot":"","sources":["../../version-info/version-info.tsx"],"names":[],"mappings":"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"}
@@ -4,41 +4,47 @@
4
4
  align-items: center;
5
5
  height: 40px;
6
6
  padding: 0 16px;
7
+ line-height: 24px;
7
8
  }
9
+
8
10
  .versionTimestamp {
9
11
  min-width: fit-content;
10
12
  margin-right: 2px;
11
13
  text-align: right;
12
14
  }
15
+
13
16
  .versionUserAvatar {
17
+ flex: none;
14
18
  padding: 0px 8px;
15
19
  }
20
+
16
21
  .laneIcon {
17
22
  padding: 0px 4px;
18
23
  }
24
+
19
25
  .version {
20
26
  max-width: 70%;
21
27
  display: flex;
22
28
  flex-direction: row;
23
- align-content: space-between;
24
29
  align-items: center;
30
+ justify-content: flex-start;
31
+ overflow: hidden;
25
32
  }
33
+
26
34
  .versionName {
27
35
  padding: 0px 8px;
28
- &.tag {
29
- min-width: fit-content;
30
- }
31
- &.snap {
32
- min-width: 20%;
33
- }
36
+ flex-grow: 1;
37
+ min-width: fit-content;
34
38
  }
35
39
 
36
- .commitMessage,
37
- .emptyMessage {
38
- min-width: 50%;
40
+ .commitMessage {
41
+ flex-grow: 1;
39
42
  padding: 0px 8px;
40
43
  }
44
+
41
45
  .emptyMessage {
42
46
  font-style: italic;
43
47
  color: var(--bit-text-color-light, #6c707c);
48
+ padding: 0px 8px;
49
+ font-size: (var-bit-p-xs, 14px);
44
50
  }
package/index.ts CHANGED
@@ -1,2 +1,4 @@
1
+ export { SimpleVersion, DetailedVersion } from './version-dropdown-placeholder';
2
+ export type { VersionProps } from './version-dropdown-placeholder';
1
3
  export { VersionDropdown } from './version-dropdown';
2
- export type { DropdownComponentVersion } from './version-dropdown';
4
+ export type { DropdownComponentVersion, GetActiveTabIndex } from './version-dropdown';
package/package.json CHANGED
@@ -1,32 +1,34 @@
1
1
  {
2
2
  "name": "@teambit/component.ui.version-dropdown",
3
- "version": "0.0.785",
3
+ "version": "0.0.787",
4
4
  "homepage": "https://bit.cloud/teambit/component/ui/version-dropdown",
5
5
  "main": "dist/index.js",
6
6
  "componentId": {
7
7
  "scope": "teambit.component",
8
8
  "name": "ui/version-dropdown",
9
- "version": "0.0.785"
9
+ "version": "0.0.787"
10
10
  },
11
11
  "dependencies": {
12
12
  "classnames": "2.2.6",
13
+ "semver": "7.3.4",
13
14
  "core-js": "^3.0.0",
15
+ "@teambit/base-ui.loaders.skeleton": "1.0.1",
14
16
  "@teambit/design.ui.avatar": "1.0.16",
15
17
  "@teambit/design.ui.styles.ellipsis": "0.0.357",
16
18
  "@teambit/design.ui.time-ago": "0.0.366",
17
19
  "@teambit/evangelist.elements.icon": "1.0.2",
18
- "@teambit/base-ui.loaders.skeleton": "1.0.1",
19
20
  "@teambit/design.ui.surfaces.menu.link-item": "1.0.0",
20
21
  "@teambit/evangelist.surfaces.dropdown": "1.0.2",
21
22
  "@teambit/ui-foundation.ui.constants.z-indexes": "0.0.499",
22
- "@teambit/lanes.ui.models.lanes-model": "0.0.144",
23
- "@teambit/legacy-component-log": "0.0.399",
23
+ "@teambit/lanes.ui.models.lanes-model": "0.0.145",
24
+ "@teambit/legacy-component-log": "0.0.400",
24
25
  "@teambit/ui-foundation.ui.use-box.tab": "0.0.116",
25
26
  "@teambit/component.ui.version-label": "0.0.504"
26
27
  },
27
28
  "devDependencies": {
28
29
  "@types/classnames": "2.2.11",
29
30
  "@types/react": "^17.0.8",
31
+ "@types/semver": "7.3.4",
30
32
  "@types/chai": "4.2.15",
31
33
  "chai": "4.3.0",
32
34
  "@types/mocha": "9.1.0",
@@ -1,25 +1,22 @@
1
- .simple {
1
+ .simple,
2
+ .detailed {
2
3
  cursor: pointer;
3
4
  border: 1px solid var(--bit-border-color, #babec9);
4
5
  border-radius: 6px;
5
6
  transition: background-color 300ms ease-in-out;
6
7
  height: 30px;
7
- padding: 0 8px;
8
8
  display: flex;
9
9
  align-items: center;
10
10
  box-sizing: border-box;
11
11
  user-select: none;
12
+ flex-wrap: nowrap;
13
+ gap: 8px;
14
+ padding: 8px;
12
15
 
13
- > div {
14
- margin-right: 5px;
15
- }
16
16
  &:hover {
17
17
  background-color: var(--bit-bg-heavy);
18
18
  }
19
19
 
20
- > div {
21
- max-width: 80px;
22
- }
23
20
  &.disabled {
24
21
  cursor: default;
25
22
  background-color: #ededed;
@@ -27,71 +24,24 @@
27
24
  display: none;
28
25
  }
29
26
  }
30
- .versionName {
31
- &.tag {
32
- min-width: fit-content;
33
- }
34
- &.snap {
35
- min-width: 20%;
36
- }
37
- }
27
+ }
28
+ .versionName {
29
+ flex-grow: 1;
30
+ min-width: fit-content;
38
31
  }
39
32
 
40
- .detailed {
41
- display: flex;
42
- align-items: center;
43
- box-sizing: border-box;
44
- padding: 0 8px;
45
- height: 30px;
46
- border-radius: 6px;
47
- user-select: none;
48
- transition: background-color 300ms ease-in-out;
49
- border: 1px solid var(--bit-border-color, #babec9);
33
+ .commitMessage {
34
+ flex-grow: 1;
35
+ }
50
36
 
51
- cursor: pointer;
52
- > div {
53
- margin-right: 5px;
54
- }
55
- &:hover {
56
- background-color: var(--bit-bg-heavy);
57
- }
58
- > div {
59
- max-width: 80px;
60
- }
61
- &.disabled {
62
- cursor: default;
63
- background-color: #ededed;
64
- > span {
65
- display: none;
66
- }
67
- }
68
- .versionName {
69
- &.tag {
70
- min-width: fit-content;
71
- }
72
- &.snap {
73
- min-width: 20%;
74
- }
75
- }
76
- .commitMessage,
77
- .emptyMessage {
78
- max-width: 50%;
79
- padding: 0px 8px;
80
- }
81
- .emptyMessage {
82
- font-style: italic;
83
- color: var(--bit-text-color-light, #6c707c);
84
- }
85
- .author {
86
- text-transform: capitalize;
87
- min-width: fit-content;
88
- }
89
- .versionTimestamp {
90
- min-width: fit-content;
91
- margin-right: 2px;
92
- text-align: right;
93
- }
94
- .versionUserAvatar {
95
- flex: none;
37
+ .versionUserAvatar {
38
+ flex: none;
39
+ margin-right: 5px;
40
+ }
41
+
42
+ .loader {
43
+ color: var(--bit-bg-dent, #f6f6f6);
44
+ > span {
45
+ padding: 4px;
96
46
  }
97
47
  }
@@ -1,85 +1,108 @@
1
- import React, { HTMLAttributes, useMemo } from 'react';
1
+ import React, { HTMLAttributes } from 'react';
2
2
  import { Ellipsis } from '@teambit/design.ui.styles.ellipsis';
3
3
  import classNames from 'classnames';
4
+ import * as semver from 'semver';
4
5
  import { Icon } from '@teambit/evangelist.elements.icon';
5
6
  import { TimeAgo } from '@teambit/design.ui.time-ago';
6
7
  import { UserAvatar } from '@teambit/design.ui.avatar';
8
+ import { WordSkeleton } from '@teambit/base-ui.loaders.skeleton';
7
9
  import { DropdownComponentVersion } from './version-dropdown';
8
10
 
9
11
  import styles from './version-dropdown-placeholder.module.scss';
10
12
 
11
13
  export type VersionProps = {
12
- tags: DropdownComponentVersion[];
13
- snaps?: DropdownComponentVersion[];
14
- currentVersion: string;
14
+ currentVersion?: string;
15
+ isTag?: (version?: string) => boolean;
15
16
  disabled?: boolean;
17
+ hasMoreVersions?: boolean;
18
+ showFullVersion?: boolean;
19
+ loading?: boolean;
20
+ useCurrentVersionLog?: (props: { skip?: boolean; version?: string }) => DropdownComponentVersion | undefined;
16
21
  } & HTMLAttributes<HTMLDivElement>;
17
22
 
18
- const getVersionDetailFromTags = (version, tags) => tags.find((tag) => tag.tag === version);
19
- const getVersionDetailFromSnaps = (version, snaps) => (snaps || []).find((snap) => snap.hash === version);
20
- const getVersionDetails = (version, tags, snaps) => {
21
- if (version === 'workspace' || version === 'new') return { version };
22
- return getVersionDetailFromTags(version, tags) || getVersionDetailFromSnaps(version, snaps);
23
- };
24
-
25
- export function SimpleVersion({ currentVersion, className, disabled, tags, snaps }: VersionProps) {
26
- const showArrowDown = useMemo(() => (snaps || []).concat(tags).length > 1, [tags, snaps]);
27
- const versionDetails = useMemo(() => getVersionDetails(currentVersion, tags, snaps), [currentVersion, tags, snaps]);
23
+ export function SimpleVersion({
24
+ currentVersion,
25
+ className,
26
+ disabled,
27
+ hasMoreVersions,
28
+ isTag = (version) => semver.valid(version) !== null,
29
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
30
+ useCurrentVersionLog,
31
+ showFullVersion,
32
+ loading,
33
+ ...rest
34
+ }: VersionProps) {
35
+ if (loading) return <WordSkeleton className={styles.loader} length={9} />;
36
+ const formattedVersion = showFullVersion || isTag(currentVersion) ? currentVersion : currentVersion?.slice(0, 6);
28
37
 
29
38
  return (
30
- <div className={classNames(styles.simple, className, disabled && styles.disabled)}>
31
- <Ellipsis
32
- className={classNames(
33
- styles.versionName,
34
- versionDetails?.tag && styles.tag,
35
- !versionDetails?.tag && styles.snap
36
- )}
37
- >
38
- {currentVersion}
39
+ <div {...rest} className={classNames(styles.simple, className, disabled && styles.disabled)}>
40
+ <Ellipsis className={classNames(styles.versionName)} onClick={rest.onClick}>
41
+ {formattedVersion}
39
42
  </Ellipsis>
40
- {showArrowDown && <Icon of="fat-arrow-down" />}
43
+ {hasMoreVersions && <Icon of="fat-arrow-down" onClick={rest.onClick} />}
41
44
  </div>
42
45
  );
43
46
  }
44
47
 
45
- export function DetailedVersion({ currentVersion, className, disabled, snaps, tags }: VersionProps) {
46
- const showArrowDown = useMemo(() => (snaps || []).concat(tags).length > 1, [tags, snaps]);
47
- const versionDetails = useMemo(() => getVersionDetails(currentVersion, tags, snaps), [currentVersion, tags, snaps]);
48
-
49
- const timestamp = useMemo(
50
- () => (versionDetails?.date ? new Date(parseInt(versionDetails.date)).toString() : new Date().toString()),
51
- [versionDetails?.date]
52
- );
53
-
54
- const author = useMemo(() => {
48
+ export function DetailedVersion({
49
+ currentVersion,
50
+ className,
51
+ disabled,
52
+ hasMoreVersions,
53
+ isTag = (version) => semver.valid(version) !== null,
54
+ loading,
55
+ useCurrentVersionLog,
56
+ showFullVersion,
57
+ ...rest
58
+ }: VersionProps) {
59
+ const currentVersionLog = useCurrentVersionLog?.({ skip: loading, version: currentVersion });
60
+ const { displayName, message, username, email, date: _date, profileImage } = currentVersionLog || {};
61
+ const author = React.useMemo(() => {
55
62
  return {
56
- displayName: versionDetails?.username,
57
- email: versionDetails?.email,
63
+ displayName: displayName ?? '',
64
+ email,
65
+ name: username ?? '',
66
+ profileImage,
58
67
  };
59
- }, [versionDetails]);
68
+ }, [displayName, email, username, profileImage]);
69
+ const formattedVersion = showFullVersion || isTag(currentVersion) ? currentVersion : currentVersion?.slice(0, 6);
70
+
71
+ const date = _date ? new Date(+_date) : undefined;
72
+ const timestamp = React.useMemo(() => (date ? new Date(+date).toString() : new Date().toString()), [date]);
73
+ if (loading) return <WordSkeleton className={styles.loader} length={9} />;
60
74
 
61
75
  return (
62
- <div className={classNames(styles.detailed, className, disabled && styles.disabled)}>
63
- <UserAvatar size={24} account={author} className={styles.versionUserAvatar} showTooltip={true} />
64
- <Ellipsis
65
- className={classNames(
66
- styles.versionName,
67
- versionDetails?.tag && styles.tag,
68
- !versionDetails?.tag && styles.snap
69
- )}
70
- >
71
- {currentVersion}
76
+ <div {...rest} className={classNames(styles.detailed, className, disabled && styles.disabled)}>
77
+ <UserAvatar
78
+ size={24}
79
+ account={author ?? {}}
80
+ className={styles.versionUserAvatar}
81
+ showTooltip={true}
82
+ onClick={rest.onClick}
83
+ />
84
+ <Ellipsis className={classNames(styles.versionName)} onClick={rest.onClick}>
85
+ {formattedVersion}
72
86
  </Ellipsis>
73
- {commitMessage(versionDetails?.message)}
74
- <Ellipsis className={styles.versionTimestamp}>
75
- <TimeAgo date={timestamp} />
87
+ {commitMessage(message, rest.onClick)}
88
+ <Ellipsis className={styles.versionTimestamp} onClick={rest.onClick}>
89
+ <TimeAgo date={timestamp} onClick={rest.onClick} />
76
90
  </Ellipsis>
77
- {showArrowDown && <Icon of="fat-arrow-down" />}
91
+ {hasMoreVersions && <Icon of="fat-arrow-down" onClick={rest.onClick} />}
78
92
  </div>
79
93
  );
80
94
  }
81
95
 
82
- function commitMessage(message?: string) {
83
- if (!message || message === '') return <Ellipsis className={styles.emptyMessage}>No commit message</Ellipsis>;
84
- return <Ellipsis className={styles.commitMessage}>{message}</Ellipsis>;
96
+ function commitMessage(message?: string, onClick?: React.MouseEventHandler<HTMLDivElement> | undefined) {
97
+ if (!message || message === '')
98
+ return (
99
+ <Ellipsis className={styles.emptyMessage} onClick={onClick}>
100
+ No commit message
101
+ </Ellipsis>
102
+ );
103
+ return (
104
+ <Ellipsis className={styles.commitMessage} onClick={onClick}>
105
+ {message}
106
+ </Ellipsis>
107
+ );
85
108
  }
@@ -8,17 +8,28 @@ const style = { display: 'flex', justifyContent: 'center', alignContent: 'center
8
8
  export const VersionDropdownWithOneVersion = () => {
9
9
  return (
10
10
  <ThemeCompositions style={style}>
11
- <VersionDropdown tags={[{ version: '0.1' }]} currentVersion="0.1" />
11
+ <VersionDropdown
12
+ useComponentVersions={() => ({
13
+ tags: [{ version: '0.1' }],
14
+ })}
15
+ currentVersion="0.1"
16
+ />
12
17
  </ThemeCompositions>
13
18
  );
14
19
  };
15
20
 
16
21
  export const VersionDropdownWithMultipleVersions = () => {
17
22
  const versions = ['0.3', '0.2', '0.1'].map((version) => ({ version }));
23
+
18
24
  return (
19
25
  <ThemeCompositions style={style}>
20
26
  <MemoryRouter>
21
- <VersionDropdown tags={versions} currentVersion={versions[0].version} />
27
+ <VersionDropdown
28
+ useComponentVersions={() => ({
29
+ tags: [{ version: '0.1' }],
30
+ })}
31
+ currentVersion={versions[0].version}
32
+ />
22
33
  </MemoryRouter>
23
34
  </ThemeCompositions>
24
35
  );
@@ -28,10 +28,11 @@
28
28
  margin-bottom: 2px;
29
29
  }
30
30
 
31
- .versionContainer {
31
+ .versionContainerRoot {
32
32
  max-height: 240px;
33
33
  overflow-y: scroll;
34
34
  padding-bottom: 8px;
35
+ position: relative;
35
36
  }
36
37
 
37
38
  .versionRow {
@@ -103,5 +104,19 @@
103
104
  }
104
105
 
105
106
  .loading {
106
- color: var(--bit-bg-heavy, #f6f6f6);
107
+ color: var(--bit-bg-dent, #f6f6f6);
108
+ }
109
+
110
+ .loader {
111
+ color: var(--bit-bg-dent, #f6f6f6);
112
+ > div {
113
+ padding: 8px 0px;
114
+ }
115
+ }
116
+
117
+ .versionMenuContainer {
118
+ display: initial;
119
+ &.hide {
120
+ display: none;
121
+ }
107
122
  }
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import { render } from '@testing-library/react';
2
+ import { render, screen } from '@testing-library/react';
3
3
  import { expect } from 'chai';
4
4
  import { VersionDropdownWithOneVersion, VersionDropdownWithMultipleVersions } from './version-dropdown.composition';
5
5
 
@@ -16,13 +16,14 @@ describe('version dropdown tests', () => {
16
16
  const textVersion = getByText(/^0.1$/);
17
17
  expect(textVersion).to.exist;
18
18
  });
19
- it('should return multiple versions', () => {
20
- const { getByText, getAllByText } = render(<VersionDropdownWithMultipleVersions />);
21
- const textVersionOne = getByText(/^0.1$/);
22
- const textVersionTwo = getByText(/^0.2$/);
23
- const textVersionThree = getAllByText(/^0.3$/);
24
- expect(textVersionOne).to.exist;
25
- expect(textVersionTwo).to.exist;
26
- expect(textVersionThree).to.exist;
19
+ it('should not return multiple versions when mounted (lazy loading)', () => {
20
+ render(<VersionDropdownWithMultipleVersions />);
21
+ const textVersionOne = screen.queryByText(/^0.1$/);
22
+ const textVersionTwo = screen.queryByText(/^0.2$/);
23
+ const textVersionThree = screen.getAllByText(/^0.3$/);
24
+
25
+ expect(textVersionOne).to.be.null;
26
+ expect(textVersionTwo).to.be.null;
27
+ expect(textVersionThree).to.have.lengthOf.at.least(1);
27
28
  });
28
29
  });