@atlaskit/link-datasource 2.11.1 → 2.11.3

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 CHANGED
@@ -1,5 +1,22 @@
1
1
  # @atlaskit/link-datasource
2
2
 
3
+ ## 2.11.3
4
+
5
+ ### Patch Changes
6
+
7
+ - [#131211](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/131211)
8
+ [`35d5f222a8212`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/35d5f222a8212) -
9
+ Prevents inline-edit to fire execute callback on blur or with an empty string
10
+ - Updated dependencies
11
+
12
+ ## 2.11.2
13
+
14
+ ### Patch Changes
15
+
16
+ - [#131099](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/131099)
17
+ [`9762a9622c0a9`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/9762a9622c0a9) -
18
+ [ux] Add error flag on update inline edit fails
19
+
3
20
  ## 2.11.1
4
21
 
5
22
  ### Patch Changes
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.getResourceUrl = void 0;
8
+ var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
9
+ var isLink = function isLink(data) {
10
+ return (0, _typeof2.default)(data) === 'object' && 'url' in data;
11
+ };
12
+ var getLinkTypeUrl = function getLinkTypeUrl(data) {
13
+ return isLink(data) ? data.url : undefined;
14
+ };
15
+ var getResourceUrl = exports.getResourceUrl = function getResourceUrl(data) {
16
+ var _data$key, _data$title;
17
+ return getLinkTypeUrl(data === null || data === void 0 || (_data$key = data['key']) === null || _data$key === void 0 ? void 0 : _data$key.data) || getLinkTypeUrl(data === null || data === void 0 || (_data$title = data['title']) === null || _data$title === void 0 ? void 0 : _data$title.data);
18
+ };
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ var _typeof = require("@babel/runtime/helpers/typeof");
5
+ Object.defineProperty(exports, "__esModule", {
6
+ value: true
7
+ });
8
+ exports.useDatasourceTableFlag = void 0;
9
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
10
+ var _react = _interopRequireWildcard(require("react"));
11
+ var _reactIntlNext = require("react-intl-next");
12
+ var _uuid = _interopRequireDefault(require("uuid"));
13
+ var _flag = require("@atlaskit/flag");
14
+ var _crossCircle = _interopRequireDefault(require("@atlaskit/icon/glyph/cross-circle"));
15
+ var _messages = require("../ui/issue-like-table/messages");
16
+ function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); }
17
+ function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
18
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
19
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
20
+ var useDatasourceTableFlag = exports.useDatasourceTableFlag = function useDatasourceTableFlag(options) {
21
+ var _useFlags = (0, _flag.useFlags)(),
22
+ showFlag = _useFlags.showFlag;
23
+ var actions = (0, _react.useMemo)(function () {
24
+ var resourceLink = (options === null || options === void 0 ? void 0 : options.url) && {
25
+ content: /*#__PURE__*/_react.default.createElement(_reactIntlNext.FormattedMessage, _messages.issueLikeTableMessages.goToResourceLink),
26
+ href: options === null || options === void 0 ? void 0 : options.url,
27
+ target: '_blank'
28
+ };
29
+ return resourceLink ? [resourceLink] : undefined;
30
+ }, [options === null || options === void 0 ? void 0 : options.url]);
31
+ var showErrorFlag = (0, _react.useCallback)(function (args) {
32
+ showFlag(_objectSpread({
33
+ actions: actions,
34
+ description: /*#__PURE__*/_react.default.createElement(_reactIntlNext.FormattedMessage, _messages.issueLikeTableMessages.updateErrorGenericDescription),
35
+ // We need IconTile (currently in beta) in order to scale the new icon to 24px
36
+ // eslint-disable-next-line @atlaskit/design-system/no-legacy-icons
37
+ icon: /*#__PURE__*/_react.default.createElement(_crossCircle.default, {
38
+ label: "Error",
39
+ primaryColor: "var(--ds-icon-danger, #C9372C)"
40
+ }),
41
+ id: (0, _uuid.default)(),
42
+ isAutoDismiss: true,
43
+ title: /*#__PURE__*/_react.default.createElement(_reactIntlNext.FormattedMessage, _messages.issueLikeTableMessages.updateErrorGenericTitle)
44
+ }, args));
45
+ }, [actions, showFlag]);
46
+ return {
47
+ showErrorFlag: showErrorFlag
48
+ };
49
+ };
@@ -16,6 +16,7 @@ var _styled = _interopRequireDefault(require("@emotion/styled"));
16
16
  var _debounce = _interopRequireDefault(require("lodash/debounce"));
17
17
  var _reactIntlNext = require("react-intl-next");
18
18
  var _tinyInvariant = _interopRequireDefault(require("tiny-invariant"));
19
+ var _flag = require("@atlaskit/flag");
19
20
  var _linkingCommon = require("@atlaskit/linking-common");
20
21
  var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
21
22
  var _closestEdge = require("@atlaskit/pragmatic-drag-and-drop-hitbox/closest-edge");
@@ -592,7 +593,7 @@ var IssueLikeDataTableView = exports.IssueLikeDataTableView = function IssueLike
592
593
  }, _callee, null, [[3, 9]]);
593
594
  })), [experienceId, extensionKey, hasFullSchema, onLoadDatasourceDetails]);
594
595
  var isEditable = onVisibleColumnKeysChange && hasData;
595
- return (0, _react2.jsx)("div", {
596
+ var view = (0, _react2.jsx)("div", {
596
597
  /* There is required contentEditable={true} in editor-card-plugin
597
598
  * But this brakes how DND works. We set contentEditable={false} to allow DND to work
598
599
  * when dragging is initiated on top of a column label.
@@ -738,5 +739,6 @@ var IssueLikeDataTableView = exports.IssueLikeDataTableView = function IssueLike
738
739
  }
739
740
  }));
740
741
  }))));
742
+ return (0, _platformFeatureFlags.fg)('platform-datasources-enable-two-way-sync') ? (0, _react2.jsx)(_flag.FlagsProvider, null, view) : view;
741
743
  };
742
744
  var EmptyState = exports.EmptyState = _emptyState.default;
@@ -6,6 +6,21 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.issueLikeTableMessages = void 0;
7
7
  var _reactIntlNext = require("react-intl-next");
8
8
  var issueLikeTableMessages = exports.issueLikeTableMessages = (0, _reactIntlNext.defineMessages)({
9
+ goToResourceLink: {
10
+ id: 'linkDataSource.issue-line-table.go-to-resource.nonfinal',
11
+ description: 'Link to navigate to the resource page',
12
+ defaultMessage: 'Go to item'
13
+ },
14
+ updateErrorGenericDescription: {
15
+ id: 'linkDataSource.issue-line-table.error-generic-description.nonfinal',
16
+ description: 'Generic error message description shown when updating issue field fails',
17
+ defaultMessage: 'We had an issue trying to complete the update. Refresh the page and try again.'
18
+ },
19
+ updateErrorGenericTitle: {
20
+ id: 'linkDataSource.issue-line-table.error-generic-title.nonfinal',
21
+ description: 'Generic error message title shown when updating issue field fails',
22
+ defaultMessage: 'Something went wrong'
23
+ },
9
24
  wrapText: {
10
25
  id: 'linkDataSource.issue-line-table.wrap-text',
11
26
  description: 'Table header Dropdown item for making whole column to wrap text',
@@ -12,6 +12,8 @@ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/de
12
12
  var _react = _interopRequireWildcard(require("react"));
13
13
  var _inlineEdit = _interopRequireDefault(require("@atlaskit/inline-edit"));
14
14
  var _primitives = require("@atlaskit/primitives");
15
+ var _responseItem = require("../../../common/utils/response-item");
16
+ var _useDatasourceTableFlag = require("../../../hooks/useDatasourceTableFlag");
15
17
  var _state = require("../../../state");
16
18
  var _editType = require("../edit-type");
17
19
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); }
@@ -31,6 +33,9 @@ var mapUpdatedItem = function mapUpdatedItem(type, existingItem, columnKey, newV
31
33
  }
32
34
  return null;
33
35
  };
36
+ var isNewValue = function isNewValue(columnKey, newItem, existingData) {
37
+ return newItem[columnKey].data && newItem[columnKey].data !== existingData[columnKey].data;
38
+ };
34
39
  var InlineEdit = exports.InlineEdit = function InlineEdit(_ref) {
35
40
  var ari = _ref.ari,
36
41
  execute = _ref.execute,
@@ -44,6 +49,11 @@ var InlineEdit = exports.InlineEdit = function InlineEdit(_ref) {
44
49
  var item = (0, _state.useDatasourceItem)({
45
50
  id: ari
46
51
  });
52
+ var url = (0, _responseItem.getResourceUrl)(item === null || item === void 0 ? void 0 : item.data);
53
+ var _useDatasourceTableFl = (0, _useDatasourceTableFlag.useDatasourceTableFlag)({
54
+ url: url
55
+ }),
56
+ showErrorFlag = _useDatasourceTableFl.showErrorFlag;
47
57
  var _useDatasourceActions = (0, _state.useDatasourceActions)(),
48
58
  onUpdateItem = _useDatasourceActions.onUpdateItem;
49
59
  var onCommitUpdate = (0, _react.useCallback)(function (value) {
@@ -53,18 +63,17 @@ var InlineEdit = exports.InlineEdit = function InlineEdit(_ref) {
53
63
  }
54
64
  var existingData = item.data;
55
65
  var newItem = mapUpdatedItem(datasourceTypeWithValues.type, item.data, columnKey, value);
56
- if (!newItem) {
66
+ if (!newItem || !isNewValue(columnKey, newItem, existingData)) {
57
67
  setIsEditing(false);
58
68
  return;
59
69
  }
60
70
  onUpdateItem(ari, newItem);
61
71
  execute(value).catch(function (error) {
62
- // eslint-disable-next-line no-console
63
- console.error(error);
72
+ showErrorFlag();
64
73
  onUpdateItem(ari, existingData);
65
74
  });
66
75
  setIsEditing(false);
67
- }, [ari, execute, datasourceTypeWithValues, item, columnKey, onUpdateItem]);
76
+ }, [ari, execute, datasourceTypeWithValues, item, columnKey, onUpdateItem, showErrorFlag]);
68
77
  return /*#__PURE__*/_react.default.createElement(_primitives.Box, {
69
78
  xcss: containerStyles
70
79
  }, /*#__PURE__*/_react.default.createElement(_inlineEdit.default, (0, _extends2.default)({}, (0, _editType.editType)(datasourceTypeWithValues), {
@@ -0,0 +1,6 @@
1
+ const isLink = data => typeof data === 'object' && 'url' in data;
2
+ const getLinkTypeUrl = data => isLink(data) ? data.url : undefined;
3
+ export const getResourceUrl = data => {
4
+ var _data$key, _data$title;
5
+ return getLinkTypeUrl(data === null || data === void 0 ? void 0 : (_data$key = data['key']) === null || _data$key === void 0 ? void 0 : _data$key.data) || getLinkTypeUrl(data === null || data === void 0 ? void 0 : (_data$title = data['title']) === null || _data$title === void 0 ? void 0 : _data$title.data);
6
+ };
@@ -0,0 +1,38 @@
1
+ import React, { useCallback, useMemo } from 'react';
2
+ import { FormattedMessage } from 'react-intl-next';
3
+ import uuid from 'uuid';
4
+ import { useFlags } from '@atlaskit/flag';
5
+ import CrossCircleIcon from '@atlaskit/icon/glyph/cross-circle';
6
+ import { issueLikeTableMessages } from '../ui/issue-like-table/messages';
7
+ export const useDatasourceTableFlag = options => {
8
+ const {
9
+ showFlag
10
+ } = useFlags();
11
+ const actions = useMemo(() => {
12
+ const resourceLink = (options === null || options === void 0 ? void 0 : options.url) && {
13
+ content: /*#__PURE__*/React.createElement(FormattedMessage, issueLikeTableMessages.goToResourceLink),
14
+ href: options === null || options === void 0 ? void 0 : options.url,
15
+ target: '_blank'
16
+ };
17
+ return resourceLink ? [resourceLink] : undefined;
18
+ }, [options === null || options === void 0 ? void 0 : options.url]);
19
+ const showErrorFlag = useCallback(args => {
20
+ showFlag({
21
+ actions,
22
+ description: /*#__PURE__*/React.createElement(FormattedMessage, issueLikeTableMessages.updateErrorGenericDescription),
23
+ // We need IconTile (currently in beta) in order to scale the new icon to 24px
24
+ // eslint-disable-next-line @atlaskit/design-system/no-legacy-icons
25
+ icon: /*#__PURE__*/React.createElement(CrossCircleIcon, {
26
+ label: "Error",
27
+ primaryColor: "var(--ds-icon-danger, #C9372C)"
28
+ }),
29
+ id: uuid(),
30
+ isAutoDismiss: true,
31
+ title: /*#__PURE__*/React.createElement(FormattedMessage, issueLikeTableMessages.updateErrorGenericTitle),
32
+ ...args
33
+ });
34
+ }, [actions, showFlag]);
35
+ return {
36
+ showErrorFlag
37
+ };
38
+ };
@@ -11,6 +11,7 @@ import styled from '@emotion/styled';
11
11
  import debounce from 'lodash/debounce';
12
12
  import { useIntl } from 'react-intl-next';
13
13
  import invariant from 'tiny-invariant';
14
+ import { FlagsProvider } from '@atlaskit/flag';
14
15
  import { Skeleton } from '@atlaskit/linking-common';
15
16
  import { fg } from '@atlaskit/platform-feature-flags';
16
17
  import { extractClosestEdge } from '@atlaskit/pragmatic-drag-and-drop-hitbox/closest-edge';
@@ -563,7 +564,7 @@ export const IssueLikeDataTableView = ({
563
564
  }
564
565
  }, [experienceId, extensionKey, hasFullSchema, onLoadDatasourceDetails]);
565
566
  const isEditable = onVisibleColumnKeysChange && hasData;
566
- return jsx("div", {
567
+ const view = jsx("div", {
567
568
  /* There is required contentEditable={true} in editor-card-plugin
568
569
  * But this brakes how DND works. We set contentEditable={false} to allow DND to work
569
570
  * when dragging is initiated on top of a column label.
@@ -711,5 +712,6 @@ export const IssueLikeDataTableView = ({
711
712
  }, content);
712
713
  }
713
714
  }))))));
715
+ return fg('platform-datasources-enable-two-way-sync') ? jsx(FlagsProvider, null, view) : view;
714
716
  };
715
717
  export const EmptyState = TableEmptyState;
@@ -1,5 +1,20 @@
1
1
  import { defineMessages } from 'react-intl-next';
2
2
  export const issueLikeTableMessages = defineMessages({
3
+ goToResourceLink: {
4
+ id: 'linkDataSource.issue-line-table.go-to-resource.nonfinal',
5
+ description: 'Link to navigate to the resource page',
6
+ defaultMessage: 'Go to item'
7
+ },
8
+ updateErrorGenericDescription: {
9
+ id: 'linkDataSource.issue-line-table.error-generic-description.nonfinal',
10
+ description: 'Generic error message description shown when updating issue field fails',
11
+ defaultMessage: 'We had an issue trying to complete the update. Refresh the page and try again.'
12
+ },
13
+ updateErrorGenericTitle: {
14
+ id: 'linkDataSource.issue-line-table.error-generic-title.nonfinal',
15
+ description: 'Generic error message title shown when updating issue field fails',
16
+ defaultMessage: 'Something went wrong'
17
+ },
3
18
  wrapText: {
4
19
  id: 'linkDataSource.issue-line-table.wrap-text',
5
20
  description: 'Table header Dropdown item for making whole column to wrap text',
@@ -2,6 +2,8 @@ import _extends from "@babel/runtime/helpers/extends";
2
2
  import React, { useCallback, useState } from 'react';
3
3
  import AKInlineEdit from '@atlaskit/inline-edit';
4
4
  import { Box, xcss } from '@atlaskit/primitives';
5
+ import { getResourceUrl } from '../../../common/utils/response-item';
6
+ import { useDatasourceTableFlag } from '../../../hooks/useDatasourceTableFlag';
5
7
  import { useDatasourceActions, useDatasourceItem } from '../../../state';
6
8
  import { editType } from '../edit-type';
7
9
  const containerStyles = xcss({
@@ -20,6 +22,9 @@ const mapUpdatedItem = (type, existingItem, columnKey, newValue) => {
20
22
  }
21
23
  return null;
22
24
  };
25
+ const isNewValue = (columnKey, newItem, existingData) => {
26
+ return newItem[columnKey].data && newItem[columnKey].data !== existingData[columnKey].data;
27
+ };
23
28
  export const InlineEdit = ({
24
29
  ari,
25
30
  execute,
@@ -31,6 +36,12 @@ export const InlineEdit = ({
31
36
  const item = useDatasourceItem({
32
37
  id: ari
33
38
  });
39
+ const url = getResourceUrl(item === null || item === void 0 ? void 0 : item.data);
40
+ const {
41
+ showErrorFlag
42
+ } = useDatasourceTableFlag({
43
+ url
44
+ });
34
45
  const {
35
46
  onUpdateItem
36
47
  } = useDatasourceActions();
@@ -41,18 +52,17 @@ export const InlineEdit = ({
41
52
  }
42
53
  const existingData = item.data;
43
54
  const newItem = mapUpdatedItem(datasourceTypeWithValues.type, item.data, columnKey, value);
44
- if (!newItem) {
55
+ if (!newItem || !isNewValue(columnKey, newItem, existingData)) {
45
56
  setIsEditing(false);
46
57
  return;
47
58
  }
48
59
  onUpdateItem(ari, newItem);
49
60
  execute(value).catch(error => {
50
- // eslint-disable-next-line no-console
51
- console.error(error);
61
+ showErrorFlag();
52
62
  onUpdateItem(ari, existingData);
53
63
  });
54
64
  setIsEditing(false);
55
- }, [ari, execute, datasourceTypeWithValues, item, columnKey, onUpdateItem]);
65
+ }, [ari, execute, datasourceTypeWithValues, item, columnKey, onUpdateItem, showErrorFlag]);
56
66
  return /*#__PURE__*/React.createElement(Box, {
57
67
  xcss: containerStyles
58
68
  }, /*#__PURE__*/React.createElement(AKInlineEdit, _extends({}, editType(datasourceTypeWithValues), {
@@ -0,0 +1,11 @@
1
+ import _typeof from "@babel/runtime/helpers/typeof";
2
+ var isLink = function isLink(data) {
3
+ return _typeof(data) === 'object' && 'url' in data;
4
+ };
5
+ var getLinkTypeUrl = function getLinkTypeUrl(data) {
6
+ return isLink(data) ? data.url : undefined;
7
+ };
8
+ export var getResourceUrl = function getResourceUrl(data) {
9
+ var _data$key, _data$title;
10
+ return getLinkTypeUrl(data === null || data === void 0 || (_data$key = data['key']) === null || _data$key === void 0 ? void 0 : _data$key.data) || getLinkTypeUrl(data === null || data === void 0 || (_data$title = data['title']) === null || _data$title === void 0 ? void 0 : _data$title.data);
11
+ };
@@ -0,0 +1,39 @@
1
+ import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
3
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
4
+ import React, { useCallback, useMemo } from 'react';
5
+ import { FormattedMessage } from 'react-intl-next';
6
+ import uuid from 'uuid';
7
+ import { useFlags } from '@atlaskit/flag';
8
+ import CrossCircleIcon from '@atlaskit/icon/glyph/cross-circle';
9
+ import { issueLikeTableMessages } from '../ui/issue-like-table/messages';
10
+ export var useDatasourceTableFlag = function useDatasourceTableFlag(options) {
11
+ var _useFlags = useFlags(),
12
+ showFlag = _useFlags.showFlag;
13
+ var actions = useMemo(function () {
14
+ var resourceLink = (options === null || options === void 0 ? void 0 : options.url) && {
15
+ content: /*#__PURE__*/React.createElement(FormattedMessage, issueLikeTableMessages.goToResourceLink),
16
+ href: options === null || options === void 0 ? void 0 : options.url,
17
+ target: '_blank'
18
+ };
19
+ return resourceLink ? [resourceLink] : undefined;
20
+ }, [options === null || options === void 0 ? void 0 : options.url]);
21
+ var showErrorFlag = useCallback(function (args) {
22
+ showFlag(_objectSpread({
23
+ actions: actions,
24
+ description: /*#__PURE__*/React.createElement(FormattedMessage, issueLikeTableMessages.updateErrorGenericDescription),
25
+ // We need IconTile (currently in beta) in order to scale the new icon to 24px
26
+ // eslint-disable-next-line @atlaskit/design-system/no-legacy-icons
27
+ icon: /*#__PURE__*/React.createElement(CrossCircleIcon, {
28
+ label: "Error",
29
+ primaryColor: "var(--ds-icon-danger, #C9372C)"
30
+ }),
31
+ id: uuid(),
32
+ isAutoDismiss: true,
33
+ title: /*#__PURE__*/React.createElement(FormattedMessage, issueLikeTableMessages.updateErrorGenericTitle)
34
+ }, args));
35
+ }, [actions, showFlag]);
36
+ return {
37
+ showErrorFlag: showErrorFlag
38
+ };
39
+ };
@@ -18,6 +18,7 @@ import styled from '@emotion/styled';
18
18
  import debounce from 'lodash/debounce';
19
19
  import { useIntl } from 'react-intl-next';
20
20
  import invariant from 'tiny-invariant';
21
+ import { FlagsProvider } from '@atlaskit/flag';
21
22
  import { Skeleton } from '@atlaskit/linking-common';
22
23
  import { fg } from '@atlaskit/platform-feature-flags';
23
24
  import { extractClosestEdge } from '@atlaskit/pragmatic-drag-and-drop-hitbox/closest-edge';
@@ -588,7 +589,7 @@ export var IssueLikeDataTableView = function IssueLikeDataTableView(_ref5) {
588
589
  }, _callee, null, [[3, 9]]);
589
590
  })), [experienceId, extensionKey, hasFullSchema, onLoadDatasourceDetails]);
590
591
  var isEditable = onVisibleColumnKeysChange && hasData;
591
- return jsx("div", {
592
+ var view = jsx("div", {
592
593
  /* There is required contentEditable={true} in editor-card-plugin
593
594
  * But this brakes how DND works. We set contentEditable={false} to allow DND to work
594
595
  * when dragging is initiated on top of a column label.
@@ -734,5 +735,6 @@ export var IssueLikeDataTableView = function IssueLikeDataTableView(_ref5) {
734
735
  }
735
736
  }));
736
737
  }))));
738
+ return fg('platform-datasources-enable-two-way-sync') ? jsx(FlagsProvider, null, view) : view;
737
739
  };
738
740
  export var EmptyState = TableEmptyState;
@@ -1,5 +1,20 @@
1
1
  import { defineMessages } from 'react-intl-next';
2
2
  export var issueLikeTableMessages = defineMessages({
3
+ goToResourceLink: {
4
+ id: 'linkDataSource.issue-line-table.go-to-resource.nonfinal',
5
+ description: 'Link to navigate to the resource page',
6
+ defaultMessage: 'Go to item'
7
+ },
8
+ updateErrorGenericDescription: {
9
+ id: 'linkDataSource.issue-line-table.error-generic-description.nonfinal',
10
+ description: 'Generic error message description shown when updating issue field fails',
11
+ defaultMessage: 'We had an issue trying to complete the update. Refresh the page and try again.'
12
+ },
13
+ updateErrorGenericTitle: {
14
+ id: 'linkDataSource.issue-line-table.error-generic-title.nonfinal',
15
+ description: 'Generic error message title shown when updating issue field fails',
16
+ defaultMessage: 'Something went wrong'
17
+ },
3
18
  wrapText: {
4
19
  id: 'linkDataSource.issue-line-table.wrap-text',
5
20
  description: 'Table header Dropdown item for making whole column to wrap text',
@@ -6,6 +6,8 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
6
6
  import React, { useCallback, useState } from 'react';
7
7
  import AKInlineEdit from '@atlaskit/inline-edit';
8
8
  import { Box, xcss } from '@atlaskit/primitives';
9
+ import { getResourceUrl } from '../../../common/utils/response-item';
10
+ import { useDatasourceTableFlag } from '../../../hooks/useDatasourceTableFlag';
9
11
  import { useDatasourceActions, useDatasourceItem } from '../../../state';
10
12
  import { editType } from '../edit-type';
11
13
  var containerStyles = xcss({
@@ -21,6 +23,9 @@ var mapUpdatedItem = function mapUpdatedItem(type, existingItem, columnKey, newV
21
23
  }
22
24
  return null;
23
25
  };
26
+ var isNewValue = function isNewValue(columnKey, newItem, existingData) {
27
+ return newItem[columnKey].data && newItem[columnKey].data !== existingData[columnKey].data;
28
+ };
24
29
  export var InlineEdit = function InlineEdit(_ref) {
25
30
  var ari = _ref.ari,
26
31
  execute = _ref.execute,
@@ -34,6 +39,11 @@ export var InlineEdit = function InlineEdit(_ref) {
34
39
  var item = useDatasourceItem({
35
40
  id: ari
36
41
  });
42
+ var url = getResourceUrl(item === null || item === void 0 ? void 0 : item.data);
43
+ var _useDatasourceTableFl = useDatasourceTableFlag({
44
+ url: url
45
+ }),
46
+ showErrorFlag = _useDatasourceTableFl.showErrorFlag;
37
47
  var _useDatasourceActions = useDatasourceActions(),
38
48
  onUpdateItem = _useDatasourceActions.onUpdateItem;
39
49
  var onCommitUpdate = useCallback(function (value) {
@@ -43,18 +53,17 @@ export var InlineEdit = function InlineEdit(_ref) {
43
53
  }
44
54
  var existingData = item.data;
45
55
  var newItem = mapUpdatedItem(datasourceTypeWithValues.type, item.data, columnKey, value);
46
- if (!newItem) {
56
+ if (!newItem || !isNewValue(columnKey, newItem, existingData)) {
47
57
  setIsEditing(false);
48
58
  return;
49
59
  }
50
60
  onUpdateItem(ari, newItem);
51
61
  execute(value).catch(function (error) {
52
- // eslint-disable-next-line no-console
53
- console.error(error);
62
+ showErrorFlag();
54
63
  onUpdateItem(ari, existingData);
55
64
  });
56
65
  setIsEditing(false);
57
- }, [ari, execute, datasourceTypeWithValues, item, columnKey, onUpdateItem]);
66
+ }, [ari, execute, datasourceTypeWithValues, item, columnKey, onUpdateItem, showErrorFlag]);
58
67
  return /*#__PURE__*/React.createElement(Box, {
59
68
  xcss: containerStyles
60
69
  }, /*#__PURE__*/React.createElement(AKInlineEdit, _extends({}, editType(datasourceTypeWithValues), {
@@ -0,0 +1,2 @@
1
+ import type { DatasourceDataResponseItem } from '@atlaskit/linking-types';
2
+ export declare const getResourceUrl: (data?: DatasourceDataResponseItem) => string | undefined;
@@ -0,0 +1,8 @@
1
+ import { type CreateFlagArgs } from '@atlaskit/flag';
2
+ interface DatasourceTableFlagOptions {
3
+ url?: string;
4
+ }
5
+ export declare const useDatasourceTableFlag: (options?: DatasourceTableFlagOptions) => {
6
+ showErrorFlag: (args?: Partial<CreateFlagArgs>) => void;
7
+ };
8
+ export {};
@@ -1,4 +1,19 @@
1
1
  export declare const issueLikeTableMessages: {
2
+ goToResourceLink: {
3
+ id: string;
4
+ description: string;
5
+ defaultMessage: string;
6
+ };
7
+ updateErrorGenericDescription: {
8
+ id: string;
9
+ description: string;
10
+ defaultMessage: string;
11
+ };
12
+ updateErrorGenericTitle: {
13
+ id: string;
14
+ description: string;
15
+ defaultMessage: string;
16
+ };
2
17
  wrapText: {
3
18
  id: string;
4
19
  description: string;
@@ -0,0 +1,2 @@
1
+ import type { DatasourceDataResponseItem } from '@atlaskit/linking-types';
2
+ export declare const getResourceUrl: (data?: DatasourceDataResponseItem) => string | undefined;
@@ -0,0 +1,8 @@
1
+ import { type CreateFlagArgs } from '@atlaskit/flag';
2
+ interface DatasourceTableFlagOptions {
3
+ url?: string;
4
+ }
5
+ export declare const useDatasourceTableFlag: (options?: DatasourceTableFlagOptions) => {
6
+ showErrorFlag: (args?: Partial<CreateFlagArgs>) => void;
7
+ };
8
+ export {};
@@ -1,4 +1,19 @@
1
1
  export declare const issueLikeTableMessages: {
2
+ goToResourceLink: {
3
+ id: string;
4
+ description: string;
5
+ defaultMessage: string;
6
+ };
7
+ updateErrorGenericDescription: {
8
+ id: string;
9
+ description: string;
10
+ defaultMessage: string;
11
+ };
12
+ updateErrorGenericTitle: {
13
+ id: string;
14
+ description: string;
15
+ defaultMessage: string;
16
+ };
2
17
  wrapText: {
3
18
  id: string;
4
19
  description: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/link-datasource",
3
- "version": "2.11.1",
3
+ "version": "2.11.3",
4
4
  "description": "UI Components to support linking platform dataset feature",
5
5
  "author": "Atlassian Pty Ltd",
6
6
  "license": "Apache-2.0",
@@ -41,11 +41,12 @@
41
41
  "@atlaskit/avatar": "^21.15.0",
42
42
  "@atlaskit/avatar-group": "^9.11.0",
43
43
  "@atlaskit/badge": "^16.4.0",
44
- "@atlaskit/button": "^20.0.0",
44
+ "@atlaskit/button": "^20.1.0",
45
45
  "@atlaskit/datetime-picker": "^13.11.0",
46
46
  "@atlaskit/dropdown-menu": "^12.17.0",
47
47
  "@atlaskit/editor-prosemirror": "5.0.1",
48
48
  "@atlaskit/empty-state": "^7.11.0",
49
+ "@atlaskit/flag": "^15.8.0",
49
50
  "@atlaskit/form": "^10.5.0",
50
51
  "@atlaskit/heading": "^2.4.0",
51
52
  "@atlaskit/icon": "^22.13.0",