@atlaskit/editor-plugin-synced-block 17.0.8 → 17.0.9
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.
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import "./SyncedLocationDropdown.compiled.css";
|
|
3
3
|
import * as React from 'react';
|
|
4
4
|
import { ax, ix } from "@compiled/react/runtime";
|
|
5
|
-
import { useCallback, useEffect, useMemo, useState } from 'react';
|
|
5
|
+
import { Fragment, useCallback, useEffect, useMemo, useState } from 'react';
|
|
6
6
|
import { cx } from '@compiled/react';
|
|
7
7
|
import DropdownItem from '@atlaskit/dropdown-menu/dropdown-menu-item';
|
|
8
8
|
import DropdownItemGroup from '@atlaskit/dropdown-menu/dropdown-menu-item-group';
|
|
@@ -27,6 +27,7 @@ import IconTile from '@atlaskit/icon/icon-tile';
|
|
|
27
27
|
import { ConfluenceIcon, JiraIcon } from '@atlaskit/logo';
|
|
28
28
|
import { AtlassianIcon } from '@atlaskit/logo/atlassian-icon';
|
|
29
29
|
import Lozenge from '@atlaskit/lozenge/lozenge';
|
|
30
|
+
import { isExperimentEnabled } from '@atlaskit/platform-feature-experiments/is-experiment-enabled';
|
|
30
31
|
import { Box, Text, Inline, Anchor, Stack } from '@atlaskit/primitives/compiled';
|
|
31
32
|
import Spinner from '@atlaskit/spinner/spinner';
|
|
32
33
|
import { expValEquals } from '@atlaskit/tmp-editor-statsig/exp-val-equals';
|
|
@@ -49,6 +50,8 @@ const styles = {
|
|
|
49
50
|
activationDropdownContent: "_1rjcze3t _1bsb1kdj",
|
|
50
51
|
activationNoResultsContainer: "_vchhusvi _1bsb1kdj _ca0q1ejb _n3td1ejb",
|
|
51
52
|
activationNoResultsContent: "_195g1wug _1bsb12aa _y3gn1h6o",
|
|
53
|
+
fieldAwareDropdownContent: "_1bsb1kdj",
|
|
54
|
+
fieldSecondLine: "_1reo15vq _18m915vq _o5721q9c _1bto1l2s",
|
|
52
55
|
dropdownContent: "_1rjcv77o _1bsbsmdz _c71lko4j _1e0c1txw _1bah1h6o _4cvr1h6o",
|
|
53
56
|
containerWithMinHeight: "_1tkeqkoa",
|
|
54
57
|
contentContainer: "_y44vfmxe _1bsb1osq _1wpz1fhb _18m91wug",
|
|
@@ -57,6 +60,19 @@ const styles = {
|
|
|
57
60
|
learnMoreLink: "_4bfu1r31 _1hmsglyw _ajmmnqa1",
|
|
58
61
|
requestAccess: "_1bsb19n7 _o5721q9c _ahbq12x7 _syaz1rpy"
|
|
59
62
|
};
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* One field-aware dropdown row. Every string the row shows is composed here from the untouched
|
|
66
|
+
* provider `reference`. Only built with `editor_synced_blocks_jira_custom_rich_text` on.
|
|
67
|
+
*/
|
|
68
|
+
|
|
69
|
+
/** Decided once per fetch. The control shape is what the dropdown held before the experiment. */
|
|
70
|
+
|
|
71
|
+
const EMPTY_LOCATIONS = {
|
|
72
|
+
kind: 'control',
|
|
73
|
+
references: []
|
|
74
|
+
};
|
|
75
|
+
const countLocations = locations => locations.kind === 'control' ? locations.references.length : locations.items.length;
|
|
60
76
|
const shouldApplyMinHeight = (fetchStatus, itemCount) => {
|
|
61
77
|
// When there are 1/2 items, dropdown height is less than minHeight 144px
|
|
62
78
|
return !(fetchStatus === 'success' && itemCount > 0);
|
|
@@ -287,6 +303,97 @@ export const processReferenceData = (referenceData, intl) => {
|
|
|
287
303
|
});
|
|
288
304
|
return sortedReferences;
|
|
289
305
|
};
|
|
306
|
+
const isFieldAwareLocationList = references => {
|
|
307
|
+
var _references$some;
|
|
308
|
+
return ((_references$some = references === null || references === void 0 ? void 0 : references.some(reference => (reference === null || reference === void 0 ? void 0 : reference.productType) === 'jira-work-item')) !== null && _references$some !== void 0 ? _references$some : false) && isExperimentEnabled('editor_synced_blocks_jira_custom_rich_text');
|
|
309
|
+
};
|
|
310
|
+
const groupBySourceAri = referenceData => {
|
|
311
|
+
const groups = new Map();
|
|
312
|
+
referenceData === null || referenceData === void 0 ? void 0 : referenceData.forEach(reference => {
|
|
313
|
+
if (!reference) {
|
|
314
|
+
return;
|
|
315
|
+
}
|
|
316
|
+
const group = groups.get(reference.sourceAri);
|
|
317
|
+
if (group) {
|
|
318
|
+
group.push(reference);
|
|
319
|
+
} else {
|
|
320
|
+
groups.set(reference.sourceAri, [reference]);
|
|
321
|
+
}
|
|
322
|
+
});
|
|
323
|
+
return groups;
|
|
324
|
+
};
|
|
325
|
+
|
|
326
|
+
/** Sources first, then accessible locations. `0` leaves the title order to the caller. */
|
|
327
|
+
const compareLocationOrder = (a, b) => {
|
|
328
|
+
if (a.isSource !== b.isSource) {
|
|
329
|
+
return b.isSource ? 1 : -1;
|
|
330
|
+
}
|
|
331
|
+
if (a.hasAccess !== b.hasAccess) {
|
|
332
|
+
return a.hasAccess ? -1 : 1;
|
|
333
|
+
}
|
|
334
|
+
return 0;
|
|
335
|
+
};
|
|
336
|
+
|
|
337
|
+
/** The title alone. The field name is placed by the row and the tooltip, not baked in here. */
|
|
338
|
+
const getBaseTitle = ({
|
|
339
|
+
blockIndex,
|
|
340
|
+
formatMessage,
|
|
341
|
+
reference
|
|
342
|
+
}) => {
|
|
343
|
+
const title = reference.title === '' && reference.hasAccess ? formatMessage(messages.syncedLocationDropdownUntitledPage) : reference.title || reference.url || '';
|
|
344
|
+
return blockIndex === undefined ? title : `${title}: ${formatMessage(messages.syncedLocationDropdownTitleBlockIndex, {
|
|
345
|
+
index: blockIndex
|
|
346
|
+
})}`;
|
|
347
|
+
};
|
|
348
|
+
|
|
349
|
+
/** Jira rows are noted from `locationScope`; other rows keep the pre-experiment `onSameDocument` note. */
|
|
350
|
+
const getFieldAwareNote = (reference, formatMessage) => {
|
|
351
|
+
var _reference$locationSc;
|
|
352
|
+
if (reference.productType !== 'jira-work-item') {
|
|
353
|
+
if (!reference.onSameDocument) {
|
|
354
|
+
return undefined;
|
|
355
|
+
}
|
|
356
|
+
return formatMessage(reference.productType === 'confluence-page' ? messages.syncedLocationDropdownTitleNoteForConfluencePage : messages.syncedLocationDropdownTitleNoteForJiraWorkItem);
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
// A provider that computes no scope still reports `onSameDocument`. It is the same host
|
|
360
|
+
// comparison `getLocationScope` starts with, and in Jira the host document is one field.
|
|
361
|
+
const locationScope = (_reference$locationSc = reference.locationScope) !== null && _reference$locationSc !== void 0 ? _reference$locationSc : reference.onSameDocument ? 'same-document' : undefined;
|
|
362
|
+
switch (locationScope) {
|
|
363
|
+
case 'same-document':
|
|
364
|
+
return formatMessage(messages.syncedLocationDropdownTitleNoteForJiraWorkItemField);
|
|
365
|
+
case 'same-parent-document':
|
|
366
|
+
return formatMessage(messages.syncedLocationDropdownTitleNoteForJiraWorkItem);
|
|
367
|
+
default:
|
|
368
|
+
return undefined;
|
|
369
|
+
}
|
|
370
|
+
};
|
|
371
|
+
export const buildFieldAwareItems = (referenceData, formatMessage) => Array.from(groupBySourceAri(referenceData).values()).flatMap(group => group.map((reference, index) => {
|
|
372
|
+
const fieldName = reference.productType === 'jira-work-item' ? reference.fieldName : undefined;
|
|
373
|
+
const note = getFieldAwareNote(reference, formatMessage);
|
|
374
|
+
return {
|
|
375
|
+
baseTitle: getBaseTitle({
|
|
376
|
+
blockIndex: group.length > 1 ? index + 1 : undefined,
|
|
377
|
+
formatMessage,
|
|
378
|
+
reference
|
|
379
|
+
}),
|
|
380
|
+
...(fieldName !== undefined && {
|
|
381
|
+
fieldName
|
|
382
|
+
}),
|
|
383
|
+
key: `${reference.sourceAri}#${index}`,
|
|
384
|
+
...(note !== undefined && {
|
|
385
|
+
note
|
|
386
|
+
}),
|
|
387
|
+
reference
|
|
388
|
+
};
|
|
389
|
+
})).sort((a, b) => compareLocationOrder(a.reference, b.reference) || a.baseTitle.localeCompare(b.baseTitle));
|
|
390
|
+
const toSyncedLocations = (references, intl) => isFieldAwareLocationList(references) ? {
|
|
391
|
+
kind: 'field-aware',
|
|
392
|
+
items: buildFieldAwareItems(references, intl.formatMessage)
|
|
393
|
+
} : {
|
|
394
|
+
kind: 'control',
|
|
395
|
+
references: processReferenceData(references, intl)
|
|
396
|
+
};
|
|
290
397
|
export const SyncedLocationDropdown = ({
|
|
291
398
|
syncBlockStore,
|
|
292
399
|
resourceId,
|
|
@@ -382,7 +489,7 @@ export const SyncedLocationDropdownWithCount = ({
|
|
|
382
489
|
const [isOpen, setIsOpen] = useState(false);
|
|
383
490
|
const {
|
|
384
491
|
fetchStatus,
|
|
385
|
-
|
|
492
|
+
locations
|
|
386
493
|
} = useReferenceData({
|
|
387
494
|
intl,
|
|
388
495
|
isSource,
|
|
@@ -390,16 +497,25 @@ export const SyncedLocationDropdownWithCount = ({
|
|
|
390
497
|
resourceId,
|
|
391
498
|
syncBlockStore
|
|
392
499
|
});
|
|
393
|
-
const referenceCount = useMemo(() =>
|
|
394
|
-
|
|
395
|
-
|
|
500
|
+
const referenceCount = useMemo(() => {
|
|
501
|
+
switch (locations.kind) {
|
|
502
|
+
case 'control':
|
|
503
|
+
return locations.references.filter(({
|
|
504
|
+
isSource: isSourceItem
|
|
505
|
+
}) => !isSourceItem).length;
|
|
506
|
+
case 'field-aware':
|
|
507
|
+
return locations.items.filter(({
|
|
508
|
+
reference
|
|
509
|
+
}) => !reference.isSource).length;
|
|
510
|
+
}
|
|
511
|
+
}, [locations]);
|
|
396
512
|
const tooltipContent = !isOpen && fetchStatus === 'success' && referenceCount === 0 ? intl.formatMessage(messages.syncedLocationDropdownNoReferencesTooltip) : null;
|
|
397
513
|
const content = isOpen ? /*#__PURE__*/React.createElement(DropdownContentWithReferenceData, {
|
|
398
514
|
resourceId: resourceId,
|
|
399
515
|
intl: intl,
|
|
400
516
|
api: api,
|
|
401
517
|
fetchStatus: fetchStatus,
|
|
402
|
-
|
|
518
|
+
locations: locations
|
|
403
519
|
}) : null;
|
|
404
520
|
const toggleOpen = useCallback(() => {
|
|
405
521
|
setIsOpen(currentIsOpen => !currentIsOpen);
|
|
@@ -462,7 +578,7 @@ const DropdownContent = ({
|
|
|
462
578
|
api
|
|
463
579
|
}) => {
|
|
464
580
|
const [fetchStatus, setFetchStatus] = useState('none');
|
|
465
|
-
const [
|
|
581
|
+
const [locations, setLocations] = useState(EMPTY_LOCATIONS);
|
|
466
582
|
useEffect(() => {
|
|
467
583
|
setFetchStatus('loading');
|
|
468
584
|
const getReferenceData = async () => {
|
|
@@ -471,7 +587,7 @@ const DropdownContent = ({
|
|
|
471
587
|
setFetchStatus('error');
|
|
472
588
|
return;
|
|
473
589
|
}
|
|
474
|
-
|
|
590
|
+
setLocations(toSyncedLocations(response.references, intl));
|
|
475
591
|
setFetchStatus('success');
|
|
476
592
|
};
|
|
477
593
|
void getReferenceData();
|
|
@@ -481,7 +597,7 @@ const DropdownContent = ({
|
|
|
481
597
|
intl: intl,
|
|
482
598
|
api: api,
|
|
483
599
|
fetchStatus: fetchStatus,
|
|
484
|
-
|
|
600
|
+
locations: locations
|
|
485
601
|
});
|
|
486
602
|
};
|
|
487
603
|
const useReferenceData = ({
|
|
@@ -494,13 +610,13 @@ const useReferenceData = ({
|
|
|
494
610
|
const [isNewSourceBlock] = useState(() => isSource && syncBlockStore.sourceManager.isNewSourceBlock(resourceId));
|
|
495
611
|
const [state, setState] = useState(() => ({
|
|
496
612
|
fetchStatus: isNewSourceBlock ? 'success' : 'loading',
|
|
497
|
-
|
|
613
|
+
locations: EMPTY_LOCATIONS
|
|
498
614
|
}));
|
|
499
615
|
useEffect(() => {
|
|
500
616
|
let isCurrentRequest = true;
|
|
501
617
|
setState({
|
|
502
618
|
fetchStatus: isNewSourceBlock ? 'success' : 'loading',
|
|
503
|
-
|
|
619
|
+
locations: EMPTY_LOCATIONS
|
|
504
620
|
});
|
|
505
621
|
const getReferenceData = async () => {
|
|
506
622
|
const response = await syncBlockStore.fetchReferencesSourceInfo(resourceId, localId, isSource);
|
|
@@ -513,13 +629,13 @@ const useReferenceData = ({
|
|
|
513
629
|
if (response.error) {
|
|
514
630
|
setState({
|
|
515
631
|
fetchStatus: 'error',
|
|
516
|
-
|
|
632
|
+
locations: EMPTY_LOCATIONS
|
|
517
633
|
});
|
|
518
634
|
return;
|
|
519
635
|
}
|
|
520
636
|
setState({
|
|
521
637
|
fetchStatus: 'success',
|
|
522
|
-
|
|
638
|
+
locations: toSyncedLocations(response.references, intl)
|
|
523
639
|
});
|
|
524
640
|
};
|
|
525
641
|
void getReferenceData();
|
|
@@ -529,7 +645,7 @@ const useReferenceData = ({
|
|
|
529
645
|
}, [syncBlockStore, resourceId, intl, isSource, localId, isNewSourceBlock]);
|
|
530
646
|
return {
|
|
531
647
|
fetchStatus: state.fetchStatus,
|
|
532
|
-
|
|
648
|
+
locations: state.locations
|
|
533
649
|
};
|
|
534
650
|
};
|
|
535
651
|
const SyncedLocationTriggerContent = ({
|
|
@@ -568,11 +684,12 @@ const DropdownContentWithReferenceData = ({
|
|
|
568
684
|
intl,
|
|
569
685
|
api,
|
|
570
686
|
fetchStatus,
|
|
571
|
-
|
|
687
|
+
locations
|
|
572
688
|
}) => {
|
|
573
689
|
const {
|
|
574
690
|
formatMessage
|
|
575
691
|
} = intl;
|
|
692
|
+
const locationCount = countLocations(locations);
|
|
576
693
|
const handleLocationClick = () => {
|
|
577
694
|
var _api$analytics, _api$analytics$action;
|
|
578
695
|
api === null || api === void 0 ? void 0 : (_api$analytics = api.analytics) === null || _api$analytics === void 0 ? void 0 : (_api$analytics$action = _api$analytics.actions) === null || _api$analytics$action === void 0 ? void 0 : _api$analytics$action.fireAnalyticsEvent({
|
|
@@ -596,41 +713,22 @@ const DropdownContentWithReferenceData = ({
|
|
|
596
713
|
formatMessage: formatMessage
|
|
597
714
|
});
|
|
598
715
|
case 'success':
|
|
599
|
-
if (
|
|
716
|
+
if (locationCount > 0) {
|
|
600
717
|
return /*#__PURE__*/React.createElement("div", {
|
|
601
718
|
"data-testid": "synced-locations-dropdown-content",
|
|
602
719
|
className: ax([styles.contentContainer, "_ku9g126e _18bk1rpy"])
|
|
603
720
|
}, /*#__PURE__*/React.createElement(DropdownItemGroup, {
|
|
604
721
|
title: formatMessage(messages.syncedLocationDropdownHeading, {
|
|
605
|
-
count: `${
|
|
722
|
+
count: `${locationCount > 99 ? '99+' : locationCount}`
|
|
606
723
|
})
|
|
607
|
-
},
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
elemBefore: /*#__PURE__*/React.createElement(ItemIcon, {
|
|
616
|
-
reference: reference,
|
|
617
|
-
intl: intl
|
|
618
|
-
}),
|
|
619
|
-
href: reference.url,
|
|
620
|
-
target: "_blank",
|
|
621
|
-
key: reference.title,
|
|
622
|
-
rel: "noopener noreferrer"
|
|
623
|
-
// eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed)
|
|
624
|
-
,
|
|
625
|
-
onClick: () => handleLocationClick()
|
|
626
|
-
}, /*#__PURE__*/React.createElement(ItemTitle, {
|
|
627
|
-
title: title,
|
|
628
|
-
formatMessage: formatMessage,
|
|
629
|
-
onSameDocument: reference.onSameDocument,
|
|
630
|
-
isSource: reference.isSource,
|
|
631
|
-
hasAccess: reference.hasAccess,
|
|
632
|
-
productType: reference.productType
|
|
633
|
-
}))));
|
|
724
|
+
}, locations.kind === 'field-aware' ? /*#__PURE__*/React.createElement(FieldAwareLocationRows, {
|
|
725
|
+
items: locations.items,
|
|
726
|
+
intl: intl,
|
|
727
|
+
handleLocationClick: handleLocationClick
|
|
728
|
+
}) : /*#__PURE__*/React.createElement(ControlLocationRows, {
|
|
729
|
+
referenceData: locations.references,
|
|
730
|
+
intl: intl,
|
|
731
|
+
handleLocationClick: handleLocationClick
|
|
634
732
|
})));
|
|
635
733
|
} else {
|
|
636
734
|
return /*#__PURE__*/React.createElement(NoResultScreen, {
|
|
@@ -640,9 +738,121 @@ const DropdownContentWithReferenceData = ({
|
|
|
640
738
|
}
|
|
641
739
|
};
|
|
642
740
|
return /*#__PURE__*/React.createElement(Box, {
|
|
643
|
-
xcss: cx(styles.dropdownContent,
|
|
741
|
+
xcss: cx(styles.dropdownContent,
|
|
742
|
+
// Read off the discriminant rather than the experiment, so the control cohort
|
|
743
|
+
// cannot reach this width and no second exposure is fired for a style.
|
|
744
|
+
locations.kind === 'field-aware' && styles.fieldAwareDropdownContent, expValEqualsNoExposure('platform_editor_sync_block_activation', 'isEnabled', true) && fetchStatus === 'success' && locationCount === 0 && styles.activationDropdownContent, shouldApplyMinHeight(fetchStatus, locationCount) && styles.containerWithMinHeight)
|
|
644
745
|
}, content());
|
|
645
746
|
};
|
|
747
|
+
// The pre-experiment rows. This block is master's, moved into a component; remove with the experiment.
|
|
748
|
+
const ControlLocationRows = ({
|
|
749
|
+
referenceData,
|
|
750
|
+
intl,
|
|
751
|
+
handleLocationClick
|
|
752
|
+
}) => {
|
|
753
|
+
const {
|
|
754
|
+
formatMessage
|
|
755
|
+
} = intl;
|
|
756
|
+
return /*#__PURE__*/React.createElement(Fragment, null, referenceData.map(reference => {
|
|
757
|
+
const title = reference.title === '' && reference.hasAccess ? formatMessage(messages.syncedLocationDropdownUntitledPage) : reference.title || reference.url || '';
|
|
758
|
+
return /*#__PURE__*/React.createElement("div", {
|
|
759
|
+
key: reference.title,
|
|
760
|
+
className: ax(["_2ll012x7"])
|
|
761
|
+
}, /*#__PURE__*/React.createElement(Tooltip, {
|
|
762
|
+
content: title
|
|
763
|
+
}, /*#__PURE__*/React.createElement(DropdownItem, {
|
|
764
|
+
elemBefore: /*#__PURE__*/React.createElement(ItemIcon, {
|
|
765
|
+
reference: reference,
|
|
766
|
+
intl: intl
|
|
767
|
+
}),
|
|
768
|
+
href: reference.url,
|
|
769
|
+
target: "_blank",
|
|
770
|
+
key: reference.title,
|
|
771
|
+
rel: "noopener noreferrer"
|
|
772
|
+
// eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed)
|
|
773
|
+
,
|
|
774
|
+
onClick: () => handleLocationClick()
|
|
775
|
+
}, /*#__PURE__*/React.createElement(ItemTitle, {
|
|
776
|
+
title: title,
|
|
777
|
+
formatMessage: formatMessage,
|
|
778
|
+
onSameDocument: reference.onSameDocument,
|
|
779
|
+
isSource: reference.isSource,
|
|
780
|
+
hasAccess: reference.hasAccess,
|
|
781
|
+
productType: reference.productType
|
|
782
|
+
}))));
|
|
783
|
+
}));
|
|
784
|
+
};
|
|
785
|
+
const FieldAwareItemTitle = ({
|
|
786
|
+
item: {
|
|
787
|
+
baseTitle,
|
|
788
|
+
fieldName,
|
|
789
|
+
note,
|
|
790
|
+
reference
|
|
791
|
+
},
|
|
792
|
+
formatMessage
|
|
793
|
+
}) => {
|
|
794
|
+
const titleLine = /*#__PURE__*/React.createElement(Inline, null, /*#__PURE__*/React.createElement(Box, {
|
|
795
|
+
as: "span",
|
|
796
|
+
xcss: styles.title
|
|
797
|
+
}, baseTitle), note && /*#__PURE__*/React.createElement(Box, {
|
|
798
|
+
as: "span",
|
|
799
|
+
xcss: styles.note
|
|
800
|
+
}, "\xA0- ", note), reference.isSource && /*#__PURE__*/React.createElement(Box, {
|
|
801
|
+
as: "span",
|
|
802
|
+
xcss: styles.lozenge
|
|
803
|
+
}, /*#__PURE__*/React.createElement(Lozenge, null, formatMessage(messages.syncedLocationDropdownSourceLozenge))), !reference.hasAccess && /*#__PURE__*/React.createElement(Box, {
|
|
804
|
+
as: "span",
|
|
805
|
+
xcss: styles.requestAccess
|
|
806
|
+
}, formatMessage(messages.syncedLocationDropdownRequestAccess)));
|
|
807
|
+
if (fieldName === undefined) {
|
|
808
|
+
return titleLine;
|
|
809
|
+
}
|
|
810
|
+
|
|
811
|
+
// AGG localises the field name, so it is shown as given rather than wrapped in a message.
|
|
812
|
+
return /*#__PURE__*/React.createElement(Stack, null, titleLine, /*#__PURE__*/React.createElement(Box, {
|
|
813
|
+
as: "span",
|
|
814
|
+
xcss: styles.fieldSecondLine
|
|
815
|
+
}, /*#__PURE__*/React.createElement(Text, {
|
|
816
|
+
size: "small",
|
|
817
|
+
color: "color.text.subtlest"
|
|
818
|
+
}, fieldName)));
|
|
819
|
+
};
|
|
820
|
+
const FieldAwareLocationRows = ({
|
|
821
|
+
items,
|
|
822
|
+
intl,
|
|
823
|
+
handleLocationClick
|
|
824
|
+
}) => {
|
|
825
|
+
const {
|
|
826
|
+
formatMessage
|
|
827
|
+
} = intl;
|
|
828
|
+
return /*#__PURE__*/React.createElement(Fragment, null, items.map(item => /*#__PURE__*/React.createElement("div", {
|
|
829
|
+
key: item.key,
|
|
830
|
+
className: ax(["_2ll012x7"])
|
|
831
|
+
}, /*#__PURE__*/React.createElement(Tooltip, {
|
|
832
|
+
content: item.fieldName ?
|
|
833
|
+
/*#__PURE__*/
|
|
834
|
+
// Two lines in the tooltip's own text flow. Wrapping them in `Text` would
|
|
835
|
+
// default to `font.body` and override the container's `font.body.small`,
|
|
836
|
+
// so the field-aware tooltip would not match every other one.
|
|
837
|
+
React.createElement(Fragment, null, item.baseTitle, /*#__PURE__*/React.createElement("br", null), formatMessage(messages.syncedLocationDropdownTooltipFieldName, {
|
|
838
|
+
fieldName: item.fieldName
|
|
839
|
+
})) : item.baseTitle
|
|
840
|
+
}, /*#__PURE__*/React.createElement(DropdownItem, {
|
|
841
|
+
elemBefore: /*#__PURE__*/React.createElement(ItemIcon, {
|
|
842
|
+
reference: item.reference,
|
|
843
|
+
intl: intl
|
|
844
|
+
}),
|
|
845
|
+
href: item.reference.url,
|
|
846
|
+
target: "_blank",
|
|
847
|
+
rel: "noopener noreferrer"
|
|
848
|
+
// eslint-disable-next-line @atlassian/perf-linting/no-unstable-inline-props -- Ignored via go/ees017 (to be fixed)
|
|
849
|
+
,
|
|
850
|
+
onClick: () => handleLocationClick()
|
|
851
|
+
}, /*#__PURE__*/React.createElement(FieldAwareItemTitle, {
|
|
852
|
+
item: item,
|
|
853
|
+
formatMessage: formatMessage
|
|
854
|
+
}))))));
|
|
855
|
+
};
|
|
646
856
|
const LoadingScreen = ({
|
|
647
857
|
formatMessage
|
|
648
858
|
}) => {
|