@atlaskit/smart-card 17.2.1 → 17.4.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 +28 -0
- package/dist/cjs/constants.js +16 -1
- package/dist/cjs/extractors/flexible/icon/extract-document-type-icon.js +28 -7
- package/dist/cjs/extractors/flexible/icon/extract-file-formatIcon.js +88 -22
- package/dist/cjs/extractors/flexible/icon/extract-jira-task-icon.js +36 -9
- package/dist/cjs/extractors/flexible/icon/extract-jsonld-data-icon.js +33 -9
- package/dist/cjs/extractors/flexible/icon/extract-provider-icon.js +20 -3
- package/dist/cjs/extractors/flexible/icon/extract-url-icon.js +4 -1
- package/dist/cjs/extractors/flexible/icon/index.js +11 -20
- package/dist/cjs/extractors/flexible/index.js +5 -0
- package/dist/cjs/version.json +1 -1
- package/dist/cjs/view/FlexibleCard/components/blocks/metadata-block/index.js +17 -3
- package/dist/cjs/view/FlexibleCard/components/blocks/utils.js +27 -7
- package/dist/cjs/view/FlexibleCard/components/common/atlaskit-icon/index.js +2 -0
- package/dist/cjs/view/FlexibleCard/components/elements/avatar-group/index.js +24 -2
- package/dist/cjs/view/FlexibleCard/components/elements/badge/index.js +2 -4
- package/dist/cjs/view/FlexibleCard/components/elements/index.js +6 -2
- package/dist/cjs/view/FlexibleCard/components/elements/text/index.js +6 -2
- package/dist/cjs/view/FlexibleCard/components/elements/utils.js +64 -39
- package/dist/es2019/constants.js +15 -1
- package/dist/es2019/extractors/flexible/icon/extract-document-type-icon.js +28 -7
- package/dist/es2019/extractors/flexible/icon/extract-file-formatIcon.js +88 -22
- package/dist/es2019/extractors/flexible/icon/extract-jira-task-icon.js +36 -9
- package/dist/es2019/extractors/flexible/icon/extract-jsonld-data-icon.js +33 -9
- package/dist/es2019/extractors/flexible/icon/extract-provider-icon.js +19 -3
- package/dist/es2019/extractors/flexible/icon/extract-url-icon.js +4 -1
- package/dist/es2019/extractors/flexible/icon/index.js +6 -9
- package/dist/es2019/extractors/flexible/index.js +5 -1
- package/dist/es2019/version.json +1 -1
- package/dist/es2019/view/FlexibleCard/components/blocks/metadata-block/index.js +17 -3
- package/dist/es2019/view/FlexibleCard/components/blocks/utils.js +38 -6
- package/dist/es2019/view/FlexibleCard/components/common/atlaskit-icon/index.js +2 -0
- package/dist/es2019/view/FlexibleCard/components/elements/avatar-group/index.js +28 -2
- package/dist/es2019/view/FlexibleCard/components/elements/badge/index.js +2 -4
- package/dist/es2019/view/FlexibleCard/components/elements/index.js +3 -1
- package/dist/es2019/view/FlexibleCard/components/elements/text/index.js +5 -3
- package/dist/es2019/view/FlexibleCard/components/elements/utils.js +66 -37
- package/dist/esm/constants.js +15 -1
- package/dist/esm/extractors/flexible/icon/extract-document-type-icon.js +28 -7
- package/dist/esm/extractors/flexible/icon/extract-file-formatIcon.js +88 -22
- package/dist/esm/extractors/flexible/icon/extract-jira-task-icon.js +36 -9
- package/dist/esm/extractors/flexible/icon/extract-jsonld-data-icon.js +33 -9
- package/dist/esm/extractors/flexible/icon/extract-provider-icon.js +19 -3
- package/dist/esm/extractors/flexible/icon/extract-url-icon.js +4 -1
- package/dist/esm/extractors/flexible/icon/index.js +12 -20
- package/dist/esm/extractors/flexible/index.js +5 -1
- package/dist/esm/version.json +1 -1
- package/dist/esm/view/FlexibleCard/components/blocks/metadata-block/index.js +17 -3
- package/dist/esm/view/FlexibleCard/components/blocks/utils.js +25 -7
- package/dist/esm/view/FlexibleCard/components/common/atlaskit-icon/index.js +2 -0
- package/dist/esm/view/FlexibleCard/components/elements/avatar-group/index.js +24 -2
- package/dist/esm/view/FlexibleCard/components/elements/badge/index.js +2 -4
- package/dist/esm/view/FlexibleCard/components/elements/index.js +3 -1
- package/dist/esm/view/FlexibleCard/components/elements/text/index.js +7 -2
- package/dist/esm/view/FlexibleCard/components/elements/utils.js +64 -39
- package/dist/types/__fixtures__/flexible-ui-data-context.d.ts +3 -0
- package/dist/types/constants.d.ts +3 -1
- package/dist/types/extractors/flexible/icon/extract-provider-icon.d.ts +1 -1
- package/dist/types/extractors/flexible/icon/index.d.ts +3 -3
- package/dist/types/extractors/flexible/icon/types.d.ts +5 -1
- package/dist/types/state/flexible-ui-context/types.d.ts +4 -2
- package/dist/types/view/FlexibleCard/components/blocks/utils.d.ts +4 -2
- package/dist/types/view/FlexibleCard/components/elements/avatar-group/index.d.ts +1 -0
- package/dist/types/view/FlexibleCard/components/elements/avatar-group/types.d.ts +1 -2
- package/dist/types/view/FlexibleCard/components/elements/index.d.ts +2 -0
- package/dist/types/view/FlexibleCard/components/elements/text/types.d.ts +1 -0
- package/package.json +1 -1
|
@@ -3,32 +3,59 @@ import { IconType } from '../../../constants';
|
|
|
3
3
|
const extractJiraTaskIcon = (taskType, label = 'Task') => {
|
|
4
4
|
switch (taskType) {
|
|
5
5
|
case 'JiraBug':
|
|
6
|
-
return
|
|
6
|
+
return {
|
|
7
|
+
icon: IconType.Bug,
|
|
8
|
+
label
|
|
9
|
+
};
|
|
7
10
|
|
|
8
11
|
case 'JiraChange':
|
|
9
|
-
return
|
|
12
|
+
return {
|
|
13
|
+
icon: IconType.Change,
|
|
14
|
+
label
|
|
15
|
+
};
|
|
10
16
|
|
|
11
17
|
case 'JiraEpic':
|
|
12
|
-
return
|
|
18
|
+
return {
|
|
19
|
+
icon: IconType.Epic,
|
|
20
|
+
label
|
|
21
|
+
};
|
|
13
22
|
|
|
14
23
|
case 'JiraIncident':
|
|
15
|
-
return
|
|
24
|
+
return {
|
|
25
|
+
icon: IconType.Incident,
|
|
26
|
+
label
|
|
27
|
+
};
|
|
16
28
|
|
|
17
29
|
case 'JiraProblem':
|
|
18
|
-
return
|
|
30
|
+
return {
|
|
31
|
+
icon: IconType.Problem,
|
|
32
|
+
label
|
|
33
|
+
};
|
|
19
34
|
|
|
20
35
|
case 'JiraServiceRequest':
|
|
21
|
-
return
|
|
36
|
+
return {
|
|
37
|
+
icon: IconType.ServiceRequest,
|
|
38
|
+
label
|
|
39
|
+
};
|
|
22
40
|
|
|
23
41
|
case 'JiraStory':
|
|
24
|
-
return
|
|
42
|
+
return {
|
|
43
|
+
icon: IconType.Story,
|
|
44
|
+
label
|
|
45
|
+
};
|
|
25
46
|
|
|
26
47
|
case 'JiraSubTask':
|
|
27
|
-
return
|
|
48
|
+
return {
|
|
49
|
+
icon: IconType.SubTask,
|
|
50
|
+
label
|
|
51
|
+
};
|
|
28
52
|
|
|
29
53
|
case 'JiraTask':
|
|
30
54
|
default:
|
|
31
|
-
return
|
|
55
|
+
return {
|
|
56
|
+
icon: IconType.Task,
|
|
57
|
+
label
|
|
58
|
+
};
|
|
32
59
|
}
|
|
33
60
|
};
|
|
34
61
|
|
|
@@ -15,7 +15,10 @@ const extractTask = (data, label) => {
|
|
|
15
15
|
icon: url
|
|
16
16
|
} = extractTaskType(data) || {};
|
|
17
17
|
const taskType = id === null || id === void 0 ? void 0 : id.split('#').pop();
|
|
18
|
-
const taskIcon = url ?
|
|
18
|
+
const taskIcon = url ? {
|
|
19
|
+
label,
|
|
20
|
+
url
|
|
21
|
+
} : undefined;
|
|
19
22
|
return {
|
|
20
23
|
taskType,
|
|
21
24
|
taskIcon
|
|
@@ -39,7 +42,7 @@ const extractJsonldDataIcon = data => {
|
|
|
39
42
|
const type = extractType(data);
|
|
40
43
|
const urlIcon = extractUrlIcon(data.icon, label);
|
|
41
44
|
const provider = generator === null || generator === void 0 ? void 0 : generator['@id'];
|
|
42
|
-
const providerIcon = extractProviderIcon(
|
|
45
|
+
const providerIcon = extractProviderIcon(data);
|
|
43
46
|
|
|
44
47
|
switch (type) {
|
|
45
48
|
case 'Document':
|
|
@@ -68,25 +71,46 @@ const extractJsonldDataIcon = data => {
|
|
|
68
71
|
taskType,
|
|
69
72
|
taskIcon
|
|
70
73
|
} = extractTask(data);
|
|
71
|
-
return taskType === 'JiraCustomTaskType' ? taskIcon || urlIcon || providerIcon ||
|
|
74
|
+
return taskType === 'JiraCustomTaskType' ? taskIcon || urlIcon || providerIcon || {
|
|
75
|
+
icon: IconType.Task,
|
|
76
|
+
label: taskLabel
|
|
77
|
+
} : extractJiraTaskIcon(taskType, taskLabel);
|
|
72
78
|
}
|
|
73
79
|
|
|
74
|
-
return
|
|
80
|
+
return {
|
|
81
|
+
icon: IconType.Task,
|
|
82
|
+
label: taskLabel
|
|
83
|
+
};
|
|
75
84
|
|
|
76
85
|
case 'atlassian:Project':
|
|
77
|
-
return urlIcon ||
|
|
86
|
+
return urlIcon || {
|
|
87
|
+
icon: IconType.Project,
|
|
88
|
+
label: label || 'Project'
|
|
89
|
+
};
|
|
78
90
|
|
|
79
91
|
case 'atlassian:SourceCodeCommit':
|
|
80
|
-
return
|
|
92
|
+
return {
|
|
93
|
+
icon: IconType.Commit,
|
|
94
|
+
label: label || 'Commit'
|
|
95
|
+
};
|
|
81
96
|
|
|
82
97
|
case 'atlassian:SourceCodePullRequest':
|
|
83
|
-
return
|
|
98
|
+
return {
|
|
99
|
+
icon: IconType.PullRequest,
|
|
100
|
+
label: label || 'Pull request'
|
|
101
|
+
};
|
|
84
102
|
|
|
85
103
|
case 'atlassian:SourceCodeReference':
|
|
86
|
-
return
|
|
104
|
+
return {
|
|
105
|
+
icon: IconType.Branch,
|
|
106
|
+
label: label || 'Reference'
|
|
107
|
+
};
|
|
87
108
|
|
|
88
109
|
case 'atlassian:SourceCodeRepository':
|
|
89
|
-
return
|
|
110
|
+
return {
|
|
111
|
+
icon: IconType.Repo,
|
|
112
|
+
label: label || 'Repository'
|
|
113
|
+
};
|
|
90
114
|
|
|
91
115
|
default:
|
|
92
116
|
return providerIcon;
|
|
@@ -1,14 +1,30 @@
|
|
|
1
1
|
import { CONFLUENCE_GENERATOR_ID, JIRA_GENERATOR_ID } from '../../constants';
|
|
2
2
|
import { IconType } from '../../../constants';
|
|
3
3
|
import extractUrlIcon from './extract-url-icon';
|
|
4
|
+
import { extractTitle } from '../../common/primitives';
|
|
5
|
+
|
|
6
|
+
const extractProviderIcon = data => {
|
|
7
|
+
if (!data) {
|
|
8
|
+
return undefined;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const generator = data.generator;
|
|
12
|
+
const provider = generator === null || generator === void 0 ? void 0 : generator['@id'];
|
|
13
|
+
const icon = generator === null || generator === void 0 ? void 0 : generator.icon;
|
|
14
|
+
const label = (generator === null || generator === void 0 ? void 0 : generator.name) || extractTitle(data);
|
|
4
15
|
|
|
5
|
-
const extractProviderIcon = (provider, icon, label) => {
|
|
6
16
|
if (provider === CONFLUENCE_GENERATOR_ID) {
|
|
7
|
-
return
|
|
17
|
+
return {
|
|
18
|
+
icon: IconType.Confluence,
|
|
19
|
+
label: label || 'Confluence'
|
|
20
|
+
};
|
|
8
21
|
}
|
|
9
22
|
|
|
10
23
|
if (provider === JIRA_GENERATOR_ID) {
|
|
11
|
-
return
|
|
24
|
+
return {
|
|
25
|
+
icon: IconType.Jira,
|
|
26
|
+
label: label || 'Jira'
|
|
27
|
+
};
|
|
12
28
|
}
|
|
13
29
|
|
|
14
30
|
return extractUrlIcon(icon, label);
|
|
@@ -2,7 +2,10 @@ import { extractUrlFromIconJsonLd } from '../../common/utils';
|
|
|
2
2
|
|
|
3
3
|
const extractUrlIcon = (icon, label) => {
|
|
4
4
|
const url = icon && extractUrlFromIconJsonLd(icon);
|
|
5
|
-
return url ?
|
|
5
|
+
return url ? {
|
|
6
|
+
label,
|
|
7
|
+
url
|
|
8
|
+
} : undefined;
|
|
6
9
|
};
|
|
7
10
|
|
|
8
11
|
export default extractUrlIcon;
|
|
@@ -4,22 +4,19 @@ import { IconType, SmartLinkStatus } from '../../../constants';
|
|
|
4
4
|
import extractIconRenderer from './extract-icon-renderer';
|
|
5
5
|
export const extractLinkIcon = (response, renderers) => {
|
|
6
6
|
const data = response.data;
|
|
7
|
-
const [icon, label, url] = extractJsonldDataIcon(data) || [];
|
|
8
7
|
const render = extractIconRenderer(data, renderers);
|
|
9
|
-
return {
|
|
10
|
-
|
|
11
|
-
label,
|
|
12
|
-
render,
|
|
13
|
-
url
|
|
8
|
+
return { ...extractJsonldDataIcon(data),
|
|
9
|
+
render
|
|
14
10
|
};
|
|
15
11
|
};
|
|
16
12
|
export const extractErrorIcon = (response, status) => {
|
|
17
13
|
// Try to get provider icon first.
|
|
18
14
|
if (response) {
|
|
19
15
|
const data = response.data;
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
|
|
16
|
+
const {
|
|
17
|
+
icon,
|
|
18
|
+
url
|
|
19
|
+
} = extractProviderIcon(data) || {};
|
|
23
20
|
|
|
24
21
|
if (icon || url) {
|
|
25
22
|
return {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { extractLink, extractTitle } from '../common/primitives';
|
|
1
|
+
import { extractLink, extractSummary, extractTitle } from '../common/primitives';
|
|
2
2
|
import { extractLozenge } from '../common/lozenge';
|
|
3
3
|
import { extractLinkIcon } from './icon';
|
|
4
4
|
import { extractCommentCount, extractCreatedBy, extractModifiedBy, extractProgrammingLanguage, extractSubscriberCount } from './utils';
|
|
@@ -7,6 +7,7 @@ import { extractPersonsUpdatedBy } from './collaboratorGroup';
|
|
|
7
7
|
import { extractDateUpdated } from '../common/date/extractDateUpdated';
|
|
8
8
|
import { extractDateCreated } from '../common/date/extractDateCreated';
|
|
9
9
|
import extractPriority from './extract-priority';
|
|
10
|
+
import extractProviderIcon from './icon/extract-provider-icon';
|
|
10
11
|
|
|
11
12
|
const extractFlexibleUiContext = (response, renderers) => {
|
|
12
13
|
if (!response) {
|
|
@@ -26,9 +27,12 @@ const extractFlexibleUiContext = (response, renderers) => {
|
|
|
26
27
|
modifiedOn: extractDateUpdated(data),
|
|
27
28
|
priority: extractPriority(data),
|
|
28
29
|
programmingLanguage: extractProgrammingLanguage(data),
|
|
30
|
+
snippet: extractSummary(data) || undefined,
|
|
31
|
+
// Explicitly set here to remove an empty string
|
|
29
32
|
state: extractLozenge(data),
|
|
30
33
|
subscriberCount: extractSubscriberCount(data),
|
|
31
34
|
title: extractTitle(data) || url,
|
|
35
|
+
provider: extractProviderIcon(data),
|
|
32
36
|
url
|
|
33
37
|
};
|
|
34
38
|
};
|
package/dist/es2019/version.json
CHANGED
|
@@ -13,12 +13,11 @@ const getElementGroupStyles = (size, maxLines) => {
|
|
|
13
13
|
// MetadataBlock allows metadata elements to be displayed in
|
|
14
14
|
// multiple lines, with maximum of 2 lines.
|
|
15
15
|
// a) We need the height of the line to be equal on both left and right
|
|
16
|
-
// sides so they line up nicely.
|
|
17
|
-
// all elements in specific size. This height belongs to AvatarGroup.
|
|
16
|
+
// sides so they line up nicely.
|
|
18
17
|
// b) There is no way to truncate non-text elements nicely. Here
|
|
19
18
|
// it's fix max height of the element group so that anything that is
|
|
20
19
|
// overflown will not be visible.
|
|
21
|
-
const lineHeight =
|
|
20
|
+
const lineHeight = getLineHeight(size);
|
|
22
21
|
const gap = getGapSize(size);
|
|
23
22
|
const gapHeight = gap * (maxLines - 1);
|
|
24
23
|
const height = lineHeight * maxLines + gapHeight;
|
|
@@ -35,6 +34,21 @@ const getElementGroupStyles = (size, maxLines) => {
|
|
|
35
34
|
`;
|
|
36
35
|
};
|
|
37
36
|
|
|
37
|
+
const getLineHeight = size => {
|
|
38
|
+
// The maximum height of all elements in specific size.
|
|
39
|
+
// These heights belongs to AvatarGroup.
|
|
40
|
+
switch (size) {
|
|
41
|
+
case SmartLinkSize.XLarge:
|
|
42
|
+
case SmartLinkSize.Large:
|
|
43
|
+
return 1.75;
|
|
44
|
+
|
|
45
|
+
case SmartLinkSize.Medium:
|
|
46
|
+
case SmartLinkSize.Small:
|
|
47
|
+
default:
|
|
48
|
+
return 1.5;
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
|
|
38
52
|
const getMaxLines = maxLines => {
|
|
39
53
|
if (maxLines > MAXIMUM_MAX_LINES) {
|
|
40
54
|
return DEFAULT_MAX_LINES;
|
|
@@ -1,12 +1,30 @@
|
|
|
1
1
|
import _extends from "@babel/runtime/helpers/extends";
|
|
2
2
|
import React from 'react';
|
|
3
3
|
import { css } from '@emotion/core';
|
|
4
|
-
import { SmartLinkDirection, SmartLinkSize } from '../../../../constants';
|
|
4
|
+
import { ElementName, SmartLinkDirection, SmartLinkSize } from '../../../../constants';
|
|
5
5
|
import * as Elements from '../elements';
|
|
6
6
|
import * as Actions from '../actions';
|
|
7
7
|
import { isFlexibleUiElement } from '../../../../utils/flexible';
|
|
8
8
|
import ActionGroup from './action-group';
|
|
9
|
-
import ElementGroup from './element-group';
|
|
9
|
+
import ElementGroup from './element-group'; // Determine whether the element can be display as inline/block.
|
|
10
|
+
|
|
11
|
+
export const ElementDisplaySchema = {
|
|
12
|
+
[ElementName.AuthorGroup]: ['inline'],
|
|
13
|
+
[ElementName.CollaboratorGroup]: ['inline'],
|
|
14
|
+
[ElementName.CommentCount]: ['inline'],
|
|
15
|
+
[ElementName.CreatedBy]: ['inline'],
|
|
16
|
+
[ElementName.CreatedOn]: ['inline'],
|
|
17
|
+
[ElementName.LinkIcon]: ['inline'],
|
|
18
|
+
[ElementName.ModifiedBy]: ['inline'],
|
|
19
|
+
[ElementName.ModifiedOn]: ['inline'],
|
|
20
|
+
[ElementName.Priority]: ['inline'],
|
|
21
|
+
[ElementName.ProgrammingLanguage]: ['inline'],
|
|
22
|
+
[ElementName.Snippet]: ['block'],
|
|
23
|
+
[ElementName.State]: ['inline'],
|
|
24
|
+
[ElementName.SubscriberCount]: ['inline'],
|
|
25
|
+
[ElementName.Title]: ['inline'],
|
|
26
|
+
[ElementName.Provider]: ['inline']
|
|
27
|
+
};
|
|
10
28
|
|
|
11
29
|
const getDirectionStyles = direction => {
|
|
12
30
|
switch (direction) {
|
|
@@ -62,6 +80,16 @@ export const getBaseStyles = (direction, size) => css`
|
|
|
62
80
|
|
|
63
81
|
const isActionGroup = node => /*#__PURE__*/React.isValidElement(node) && node.type === ActionGroup;
|
|
64
82
|
|
|
83
|
+
const isElementDisplayValid = (name, display) => {
|
|
84
|
+
var _ElementDisplaySchema, _ElementDisplaySchema2;
|
|
85
|
+
|
|
86
|
+
return (_ElementDisplaySchema = (_ElementDisplaySchema2 = ElementDisplaySchema[name]) === null || _ElementDisplaySchema2 === void 0 ? void 0 : _ElementDisplaySchema2.includes(display)) !== null && _ElementDisplaySchema !== void 0 ? _ElementDisplaySchema : false;
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
const isElementNull = children => {
|
|
90
|
+
return Boolean(children.type() === null);
|
|
91
|
+
};
|
|
92
|
+
|
|
65
93
|
const isElementOrElementGroup = node => /*#__PURE__*/React.isValidElement(node) && (isFlexibleUiElement(node) || node.type === ElementGroup);
|
|
66
94
|
|
|
67
95
|
export const renderChildren = (children, size) => React.Children.map(children, child => {
|
|
@@ -77,7 +105,7 @@ export const renderChildren = (children, size) => React.Children.map(children, c
|
|
|
77
105
|
|
|
78
106
|
return child;
|
|
79
107
|
});
|
|
80
|
-
export const renderElementItems = (items = []) => {
|
|
108
|
+
export const renderElementItems = (items = [], display = 'inline') => {
|
|
81
109
|
const elements = items.reduce((acc, curr, idx) => {
|
|
82
110
|
const {
|
|
83
111
|
name,
|
|
@@ -85,10 +113,14 @@ export const renderElementItems = (items = []) => {
|
|
|
85
113
|
} = curr;
|
|
86
114
|
const Element = Elements[name];
|
|
87
115
|
|
|
88
|
-
if (Element) {
|
|
89
|
-
|
|
116
|
+
if (Element && isElementDisplayValid(name, display)) {
|
|
117
|
+
const element = /*#__PURE__*/React.createElement(Element, _extends({
|
|
90
118
|
key: idx
|
|
91
|
-
}, props))
|
|
119
|
+
}, props));
|
|
120
|
+
|
|
121
|
+
if (!isElementNull(element)) {
|
|
122
|
+
return [...acc, element];
|
|
123
|
+
}
|
|
92
124
|
}
|
|
93
125
|
|
|
94
126
|
return acc;
|
|
@@ -217,6 +217,8 @@ const AtlaskitIcon = ({
|
|
|
217
217
|
case IconType.Jira:
|
|
218
218
|
// Logo component has a different prop set from other icon components
|
|
219
219
|
return /*#__PURE__*/React.createElement(ImportedIcon, {
|
|
220
|
+
"data-testId": testId // Confluence and Jira imports don't have native testId prop
|
|
221
|
+
,
|
|
220
222
|
textColor: N700,
|
|
221
223
|
iconColor: B200,
|
|
222
224
|
iconGradientStart: B400,
|
|
@@ -1,8 +1,32 @@
|
|
|
1
|
+
/** @jsx jsx */
|
|
1
2
|
import React from 'react';
|
|
3
|
+
import { css, jsx } from '@emotion/core';
|
|
2
4
|
import AtlaskitAvatarGroup from '@atlaskit/avatar-group';
|
|
3
5
|
import { SmartLinkSize } from '../../../../../constants';
|
|
4
6
|
const MAX_COUNT = 4;
|
|
5
7
|
|
|
8
|
+
const getStyles = size => {
|
|
9
|
+
switch (size) {
|
|
10
|
+
case SmartLinkSize.XLarge:
|
|
11
|
+
case SmartLinkSize.Large:
|
|
12
|
+
// Default AK small size
|
|
13
|
+
return;
|
|
14
|
+
|
|
15
|
+
case SmartLinkSize.Medium:
|
|
16
|
+
case SmartLinkSize.Small:
|
|
17
|
+
default:
|
|
18
|
+
return css`
|
|
19
|
+
li {
|
|
20
|
+
span,
|
|
21
|
+
svg {
|
|
22
|
+
max-height: 1.25rem;
|
|
23
|
+
max-width: 1.25rem;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
`;
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
|
|
6
30
|
const AvatarGroup = ({
|
|
7
31
|
items = [],
|
|
8
32
|
maxCount = MAX_COUNT,
|
|
@@ -13,13 +37,15 @@ const AvatarGroup = ({
|
|
|
13
37
|
return null;
|
|
14
38
|
}
|
|
15
39
|
|
|
16
|
-
return
|
|
40
|
+
return jsx("span", {
|
|
41
|
+
css: getStyles(size)
|
|
42
|
+
}, jsx(AtlaskitAvatarGroup, {
|
|
17
43
|
maxCount: maxCount,
|
|
18
44
|
appearance: "stack",
|
|
19
45
|
size: "small",
|
|
20
46
|
data: items,
|
|
21
47
|
testId: testId
|
|
22
|
-
});
|
|
48
|
+
}));
|
|
23
49
|
};
|
|
24
50
|
|
|
25
51
|
export default AvatarGroup;
|
|
@@ -40,7 +40,7 @@ const messageMapper = {
|
|
|
40
40
|
[IconType.PriorityUndefined]: messages.priority_undefined
|
|
41
41
|
};
|
|
42
42
|
|
|
43
|
-
const
|
|
43
|
+
const getFormattedMessageFromIcon = icon => {
|
|
44
44
|
if (icon) {
|
|
45
45
|
const descriptor = messageMapper[icon];
|
|
46
46
|
|
|
@@ -50,8 +50,6 @@ const getFormattedMessageOrLabel = (icon, content) => {
|
|
|
50
50
|
});
|
|
51
51
|
}
|
|
52
52
|
}
|
|
53
|
-
|
|
54
|
-
return content;
|
|
55
53
|
};
|
|
56
54
|
|
|
57
55
|
const renderAtlaskitIcon = (icon, testId) => {
|
|
@@ -79,7 +77,7 @@ const Badge = ({
|
|
|
79
77
|
label,
|
|
80
78
|
testId = 'smart-element-badge'
|
|
81
79
|
}) => {
|
|
82
|
-
const formattedMessageOrLabel =
|
|
80
|
+
const formattedMessageOrLabel = getFormattedMessageFromIcon(icon) || label;
|
|
83
81
|
const badgeIcon = renderAtlaskitIcon(icon, testId) || renderImageIcon(url, testId);
|
|
84
82
|
|
|
85
83
|
if (!formattedMessageOrLabel || !badgeIcon) {
|
|
@@ -13,6 +13,8 @@ export const ModifiedBy = createElement(ElementName.ModifiedBy);
|
|
|
13
13
|
export const ModifiedOn = createElement(ElementName.ModifiedOn);
|
|
14
14
|
export const Priority = createElement(ElementName.Priority);
|
|
15
15
|
export const ProgrammingLanguage = createElement(ElementName.ProgrammingLanguage);
|
|
16
|
+
export const Snippet = createElement(ElementName.Snippet);
|
|
16
17
|
export const State = createElement(ElementName.State);
|
|
17
18
|
export const SubscriberCount = createElement(ElementName.SubscriberCount);
|
|
18
|
-
export const Title = createElement(ElementName.Title);
|
|
19
|
+
export const Title = createElement(ElementName.Title);
|
|
20
|
+
export const Provider = createElement(ElementName.Provider);
|
|
@@ -3,15 +3,17 @@ import React from 'react';
|
|
|
3
3
|
import { css, jsx } from '@emotion/core';
|
|
4
4
|
import { getFormattedMessage, getTruncateStyles } from '../../utils';
|
|
5
5
|
import { tokens } from '../../../../../utils/token';
|
|
6
|
-
|
|
6
|
+
|
|
7
|
+
const getStyles = maxLines => css`
|
|
7
8
|
color: ${tokens.text};
|
|
8
9
|
font-size: 0.75rem;
|
|
9
10
|
line-height: 1rem;
|
|
10
|
-
${getTruncateStyles(
|
|
11
|
+
${getTruncateStyles(maxLines)}
|
|
11
12
|
`;
|
|
12
13
|
|
|
13
14
|
const Text = ({
|
|
14
15
|
content,
|
|
16
|
+
maxLines = 1,
|
|
15
17
|
message,
|
|
16
18
|
testId = 'smart-element-text'
|
|
17
19
|
}) => {
|
|
@@ -20,7 +22,7 @@ const Text = ({
|
|
|
20
22
|
}
|
|
21
23
|
|
|
22
24
|
return jsx("span", {
|
|
23
|
-
css:
|
|
25
|
+
css: getStyles(maxLines),
|
|
24
26
|
"data-smart-element-text": true,
|
|
25
27
|
"data-testid": testId
|
|
26
28
|
}, getFormattedMessage(message) || content);
|
|
@@ -41,6 +41,12 @@ const elementMappings = {
|
|
|
41
41
|
icon: IconType.ProgrammingLanguage
|
|
42
42
|
}
|
|
43
43
|
},
|
|
44
|
+
[ElementName.Snippet]: {
|
|
45
|
+
component: Text,
|
|
46
|
+
props: {
|
|
47
|
+
maxLines: 3
|
|
48
|
+
}
|
|
49
|
+
},
|
|
44
50
|
[ElementName.State]: {
|
|
45
51
|
component: Lozenge
|
|
46
52
|
},
|
|
@@ -58,6 +64,9 @@ const elementMappings = {
|
|
|
58
64
|
},
|
|
59
65
|
[ElementName.ModifiedOn]: {
|
|
60
66
|
component: DateTime
|
|
67
|
+
},
|
|
68
|
+
[ElementName.Provider]: {
|
|
69
|
+
component: Badge
|
|
61
70
|
}
|
|
62
71
|
};
|
|
63
72
|
|
|
@@ -67,15 +76,6 @@ const getContextKey = name => {
|
|
|
67
76
|
return name.length > 0 ? name.charAt(0).toLowerCase() + name.slice(1) : undefined;
|
|
68
77
|
};
|
|
69
78
|
|
|
70
|
-
const getFormattedMessage = (descriptor, value) => value ? {
|
|
71
|
-
message: {
|
|
72
|
-
descriptor,
|
|
73
|
-
values: {
|
|
74
|
-
context: value
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
} : undefined;
|
|
78
|
-
|
|
79
79
|
const getData = (elementName, contextKey, context) => {
|
|
80
80
|
if (!context) {
|
|
81
81
|
return undefined;
|
|
@@ -84,52 +84,81 @@ const getData = (elementName, contextKey, context) => {
|
|
|
84
84
|
const data = context[contextKey];
|
|
85
85
|
|
|
86
86
|
switch (elementName) {
|
|
87
|
+
case ElementName.AuthorGroup:
|
|
88
|
+
case ElementName.CollaboratorGroup:
|
|
89
|
+
return toAvatarGroupProps(data);
|
|
90
|
+
|
|
87
91
|
case ElementName.CommentCount:
|
|
88
92
|
case ElementName.ProgrammingLanguage:
|
|
89
93
|
case ElementName.SubscriberCount:
|
|
90
|
-
return
|
|
91
|
-
label: data
|
|
92
|
-
};
|
|
93
|
-
|
|
94
|
-
case ElementName.AuthorGroup:
|
|
95
|
-
return {
|
|
96
|
-
items: context.authorGroup
|
|
97
|
-
};
|
|
98
|
-
|
|
99
|
-
case ElementName.CollaboratorGroup:
|
|
100
|
-
return {
|
|
101
|
-
items: context.collaboratorGroup
|
|
102
|
-
};
|
|
94
|
+
return toBadgeProps(data);
|
|
103
95
|
|
|
104
96
|
case ElementName.CreatedBy:
|
|
105
|
-
return
|
|
97
|
+
return toFormattedTextProps(messages.created_by, context.createdBy);
|
|
98
|
+
|
|
99
|
+
case ElementName.CreatedOn:
|
|
100
|
+
return toDateTimeProps('created', context.createdOn);
|
|
106
101
|
|
|
107
102
|
case ElementName.ModifiedBy:
|
|
108
|
-
return
|
|
103
|
+
return toFormattedTextProps(messages.modified_by, context.modifiedBy);
|
|
109
104
|
|
|
110
105
|
case ElementName.ModifiedOn:
|
|
111
|
-
return context.modifiedOn
|
|
112
|
-
date: new Date(context.modifiedOn),
|
|
113
|
-
type: 'modified'
|
|
114
|
-
} : undefined;
|
|
106
|
+
return toDateTimeProps('modified', context.modifiedOn);
|
|
115
107
|
|
|
116
|
-
case ElementName.
|
|
117
|
-
return
|
|
118
|
-
date: new Date(context.createdOn),
|
|
119
|
-
type: 'created'
|
|
120
|
-
} : undefined;
|
|
108
|
+
case ElementName.Snippet:
|
|
109
|
+
return toTextProps(data);
|
|
121
110
|
|
|
122
111
|
case ElementName.Title:
|
|
123
|
-
return
|
|
124
|
-
text: context.title,
|
|
125
|
-
url: context.url
|
|
126
|
-
};
|
|
112
|
+
return toLinkProps(context.title, context.url);
|
|
127
113
|
|
|
128
114
|
default:
|
|
129
115
|
return data;
|
|
130
116
|
}
|
|
131
117
|
};
|
|
132
118
|
|
|
119
|
+
const toAvatarGroupProps = items => {
|
|
120
|
+
return items ? {
|
|
121
|
+
items
|
|
122
|
+
} : undefined;
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
const toBadgeProps = label => {
|
|
126
|
+
return label ? {
|
|
127
|
+
label
|
|
128
|
+
} : undefined;
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
const toDateTimeProps = (type, dateString) => {
|
|
132
|
+
return dateString ? {
|
|
133
|
+
date: new Date(dateString),
|
|
134
|
+
type
|
|
135
|
+
} : undefined;
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
const toFormattedTextProps = (descriptor, context) => {
|
|
139
|
+
return context ? {
|
|
140
|
+
message: {
|
|
141
|
+
descriptor,
|
|
142
|
+
values: {
|
|
143
|
+
context
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
} : undefined;
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
const toLinkProps = (text, url) => {
|
|
150
|
+
return text ? {
|
|
151
|
+
text,
|
|
152
|
+
url
|
|
153
|
+
} : undefined;
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
const toTextProps = content => {
|
|
157
|
+
return content ? {
|
|
158
|
+
content
|
|
159
|
+
} : undefined;
|
|
160
|
+
};
|
|
161
|
+
|
|
133
162
|
export const createElement = name => {
|
|
134
163
|
const {
|
|
135
164
|
component: BaseElement,
|
package/dist/esm/constants.js
CHANGED
|
@@ -48,7 +48,19 @@ export var SmartLinkTheme;
|
|
|
48
48
|
SmartLinkTheme["Link"] = "link";
|
|
49
49
|
})(SmartLinkTheme || (SmartLinkTheme = {}));
|
|
50
50
|
|
|
51
|
-
export var SmartLinkWidth;
|
|
51
|
+
export var SmartLinkWidth; // When adding an element...
|
|
52
|
+
// 1) Create base element if it doesn't already existed.
|
|
53
|
+
// Base element are inside src/view/FlexibleCard/components/elements.
|
|
54
|
+
// E.g. Badge,DateTime, Icon, Lozenge, etc.
|
|
55
|
+
// 2) Update FlexibleUiContext with the new prop for data representing
|
|
56
|
+
// the element, preferably with the same name as the element itself.
|
|
57
|
+
// (src/state/flexible-ui-context/types.ts)
|
|
58
|
+
// 3) Update Flexible UI extractor (src/extractors/flexible/index.ts)
|
|
59
|
+
// 4) Set base element and data mapping.
|
|
60
|
+
// (src/view/FlexibleCard/components/elements/utils.tsx)
|
|
61
|
+
// 5) Create element. (src/view/FlexibleCard/components/elements/index.ts)
|
|
62
|
+
// 6) Update element ElementDisplaySchema for inline/block display
|
|
63
|
+
// (src/view/FlexibleCard/components/blocks/utils.tsx)
|
|
52
64
|
|
|
53
65
|
(function (SmartLinkWidth) {
|
|
54
66
|
SmartLinkWidth["FitToContent"] = "fit-to-content";
|
|
@@ -68,9 +80,11 @@ export var ElementName;
|
|
|
68
80
|
ElementName["ModifiedOn"] = "ModifiedOn";
|
|
69
81
|
ElementName["Priority"] = "Priority";
|
|
70
82
|
ElementName["ProgrammingLanguage"] = "ProgrammingLanguage";
|
|
83
|
+
ElementName["Snippet"] = "Snippet";
|
|
71
84
|
ElementName["State"] = "State";
|
|
72
85
|
ElementName["SubscriberCount"] = "SubscriberCount";
|
|
73
86
|
ElementName["Title"] = "Title";
|
|
87
|
+
ElementName["Provider"] = "Provider";
|
|
74
88
|
})(ElementName || (ElementName = {}));
|
|
75
89
|
|
|
76
90
|
export var ActionName;
|