@atlaskit/jql-editor 5.9.0 → 5.9.2
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 +13 -0
- package/dist/cjs/analytics/util.js +1 -1
- package/dist/cjs/plugins/rich-inline-nodes/util/replace-nodes-transaction.js +112 -28
- package/dist/cjs/state/hydration/util.js +16 -3
- package/dist/es2019/analytics/util.js +1 -1
- package/dist/es2019/plugins/rich-inline-nodes/util/replace-nodes-transaction.js +93 -23
- package/dist/es2019/state/hydration/util.js +13 -2
- package/dist/esm/analytics/util.js +1 -1
- package/dist/esm/plugins/rich-inline-nodes/util/replace-nodes-transaction.js +112 -28
- package/dist/esm/state/hydration/util.js +16 -3
- package/dist/types/state/hydration/util.d.ts +2 -1
- package/dist/types-ts4.5/state/hydration/util.d.ts +2 -1
- package/package.json +7 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
# @atlaskit/jql-editor
|
|
2
2
|
|
|
3
|
+
## 5.9.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies
|
|
8
|
+
|
|
9
|
+
## 5.9.1
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- [`965e86d051f6d`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/965e86d051f6d) -
|
|
14
|
+
[ux] Lozenege support(avatar + disaply name) added for membersOf(id:<team_id>) in JQL
|
|
15
|
+
|
|
3
16
|
## 5.9.0
|
|
4
17
|
|
|
5
18
|
### Minor Changes
|
|
@@ -6,5 +6,5 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
exports.useJqlEditorAnalytics = void 0;
|
|
7
7
|
var _jqlEditorCommon = require("@atlaskit/jql-editor-common");
|
|
8
8
|
var useJqlEditorAnalytics = exports.useJqlEditorAnalytics = function useJqlEditorAnalytics(analyticsSource) {
|
|
9
|
-
return (0, _jqlEditorCommon.useJqlPackageAnalytics)(analyticsSource, "@atlaskit/jql-editor", "5.
|
|
9
|
+
return (0, _jqlEditorCommon.useJqlPackageAnalytics)(analyticsSource, "@atlaskit/jql-editor", "5.9.1", _jqlEditorCommon.ANALYTICS_CHANNEL);
|
|
10
10
|
};
|
|
@@ -34,7 +34,13 @@ var replaceRichInlineNodes = exports.replaceRichInlineNodes = function replaceRi
|
|
|
34
34
|
values = _ref2[1];
|
|
35
35
|
values.forEach(function (value) {
|
|
36
36
|
if (value.type === 'user' || value.type === 'team' && (0, _platformFeatureFlags.fg)('jira_update_jql_teams')) {
|
|
37
|
+
// First try to find as direct value operand (e.g., Team[Team] = uuid)
|
|
37
38
|
var astNodes = getValueNodes(ast, fieldName, value.id);
|
|
39
|
+
|
|
40
|
+
// If not found as direct value and it's a team, try to find in membersOf function arguments
|
|
41
|
+
if (astNodes.length === 0 && value.type === 'team' && (0, _platformFeatureFlags.fg)('jira_update_jql_membersof_teams')) {
|
|
42
|
+
astNodes = getMembersOfArgumentNodes(ast, value.id);
|
|
43
|
+
}
|
|
38
44
|
astNodes.forEach(function (astNode) {
|
|
39
45
|
if (astNode.position) {
|
|
40
46
|
var _astNode$position = (0, _slicedToArray2.default)(astNode.position, 2),
|
|
@@ -85,11 +91,25 @@ var getValueNodes = function getValueNodes(ast, field, value) {
|
|
|
85
91
|
}
|
|
86
92
|
return ast.query.accept(new FindValuesVisitor(field, value));
|
|
87
93
|
};
|
|
88
|
-
var
|
|
89
|
-
|
|
94
|
+
var getMembersOfArgumentNodes = function getMembersOfArgumentNodes(ast, teamId) {
|
|
95
|
+
if (!ast.query) {
|
|
96
|
+
return [];
|
|
97
|
+
}
|
|
98
|
+
return ast.query.accept(new FindMembersOfArgumentsVisitor(teamId));
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Base visitor class for traversing JQL AST to find specific nodes.
|
|
103
|
+
* Provides common traversal logic - subclasses implement specific matching.
|
|
104
|
+
*/
|
|
105
|
+
var BaseAstNodeFinder = /*#__PURE__*/function (_AbstractJastVisitor) {
|
|
106
|
+
function BaseAstNodeFinder() {
|
|
90
107
|
var _this;
|
|
91
|
-
(0, _classCallCheck2.default)(this,
|
|
92
|
-
|
|
108
|
+
(0, _classCallCheck2.default)(this, BaseAstNodeFinder);
|
|
109
|
+
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
110
|
+
args[_key] = arguments[_key];
|
|
111
|
+
}
|
|
112
|
+
_this = _callSuper(this, BaseAstNodeFinder, [].concat(args));
|
|
93
113
|
(0, _defineProperty2.default)(_this, "visitQuery", function (query) {
|
|
94
114
|
if (query.where === undefined) {
|
|
95
115
|
return [];
|
|
@@ -97,39 +117,22 @@ var FindValuesVisitor = /*#__PURE__*/function (_AbstractJastVisitor) {
|
|
|
97
117
|
return query.where.accept(_this);
|
|
98
118
|
});
|
|
99
119
|
(0, _defineProperty2.default)(_this, "visitCompoundClause", function (compoundClause) {
|
|
100
|
-
return compoundClause.clauses.reduce(function (
|
|
101
|
-
return [].concat((0, _toConsumableArray2.default)(
|
|
120
|
+
return compoundClause.clauses.reduce(function (results, clause) {
|
|
121
|
+
return [].concat((0, _toConsumableArray2.default)(results), (0, _toConsumableArray2.default)(clause.accept(_this)));
|
|
102
122
|
}, []);
|
|
103
123
|
});
|
|
104
|
-
(0, _defineProperty2.default)(_this, "visitTerminalClause", function (terminalClause) {
|
|
105
|
-
if (!_this.equalsIgnoreCase(terminalClause.field.value, _this.field)) {
|
|
106
|
-
return [];
|
|
107
|
-
}
|
|
108
|
-
if (terminalClause.operand === undefined) {
|
|
109
|
-
return [];
|
|
110
|
-
}
|
|
111
|
-
return terminalClause.operand.accept(_this);
|
|
112
|
-
});
|
|
113
124
|
(0, _defineProperty2.default)(_this, "visitNotClause", function (notClause) {
|
|
114
125
|
return notClause.clause.accept(_this);
|
|
115
126
|
});
|
|
116
|
-
(0, _defineProperty2.default)(_this, "visitValueOperand", function (valueOperand) {
|
|
117
|
-
if (!_this.equalsIgnoreCase(valueOperand.value, _this.value)) {
|
|
118
|
-
return [];
|
|
119
|
-
}
|
|
120
|
-
return [valueOperand];
|
|
121
|
-
});
|
|
122
127
|
(0, _defineProperty2.default)(_this, "visitListOperand", function (listOperand) {
|
|
123
|
-
return listOperand.values.reduce(function (
|
|
124
|
-
return [].concat((0, _toConsumableArray2.default)(
|
|
128
|
+
return listOperand.values.reduce(function (results, operand) {
|
|
129
|
+
return [].concat((0, _toConsumableArray2.default)(results), (0, _toConsumableArray2.default)(operand.accept(_this)));
|
|
125
130
|
}, []);
|
|
126
131
|
});
|
|
127
|
-
_this.field = field;
|
|
128
|
-
_this.value = value;
|
|
129
132
|
return _this;
|
|
130
133
|
}
|
|
131
|
-
(0, _inherits2.default)(
|
|
132
|
-
return (0, _createClass2.default)(
|
|
134
|
+
(0, _inherits2.default)(BaseAstNodeFinder, _AbstractJastVisitor);
|
|
135
|
+
return (0, _createClass2.default)(BaseAstNodeFinder, [{
|
|
133
136
|
key: "aggregateResult",
|
|
134
137
|
value: function aggregateResult(aggregate, nextResult) {
|
|
135
138
|
return [].concat((0, _toConsumableArray2.default)(aggregate), (0, _toConsumableArray2.default)(nextResult));
|
|
@@ -147,4 +150,85 @@ var FindValuesVisitor = /*#__PURE__*/function (_AbstractJastVisitor) {
|
|
|
147
150
|
}) === 0;
|
|
148
151
|
}
|
|
149
152
|
}]);
|
|
150
|
-
}(_jqlAst.AbstractJastVisitor);
|
|
153
|
+
}(_jqlAst.AbstractJastVisitor);
|
|
154
|
+
/**
|
|
155
|
+
* Visitor that finds value operands matching a specific field and value.
|
|
156
|
+
* Used for direct value queries like "assignee = john-doe" or "Team[team] = uuid".
|
|
157
|
+
*/
|
|
158
|
+
var FindValuesVisitor = /*#__PURE__*/function (_BaseAstNodeFinder2) {
|
|
159
|
+
function FindValuesVisitor(field, value) {
|
|
160
|
+
var _this2;
|
|
161
|
+
(0, _classCallCheck2.default)(this, FindValuesVisitor);
|
|
162
|
+
_this2 = _callSuper(this, FindValuesVisitor);
|
|
163
|
+
(0, _defineProperty2.default)(_this2, "visitTerminalClause", function (terminalClause) {
|
|
164
|
+
if (!_this2.equalsIgnoreCase(terminalClause.field.value, _this2.field)) {
|
|
165
|
+
return [];
|
|
166
|
+
}
|
|
167
|
+
if (terminalClause.operand === undefined) {
|
|
168
|
+
return [];
|
|
169
|
+
}
|
|
170
|
+
return terminalClause.operand.accept(_this2);
|
|
171
|
+
});
|
|
172
|
+
(0, _defineProperty2.default)(_this2, "visitValueOperand", function (valueOperand) {
|
|
173
|
+
if (!_this2.equalsIgnoreCase(valueOperand.value, _this2.value)) {
|
|
174
|
+
return [];
|
|
175
|
+
}
|
|
176
|
+
return [valueOperand];
|
|
177
|
+
});
|
|
178
|
+
_this2.field = field;
|
|
179
|
+
_this2.value = value;
|
|
180
|
+
return _this2;
|
|
181
|
+
}
|
|
182
|
+
(0, _inherits2.default)(FindValuesVisitor, _BaseAstNodeFinder2);
|
|
183
|
+
return (0, _createClass2.default)(FindValuesVisitor);
|
|
184
|
+
}(BaseAstNodeFinder);
|
|
185
|
+
/**
|
|
186
|
+
* Visitor that finds membersOf function arguments matching a specific team ID.
|
|
187
|
+
* Used for queries like "assignee in membersOf("id: <uuid>")".
|
|
188
|
+
*/
|
|
189
|
+
var FindMembersOfArgumentsVisitor = /*#__PURE__*/function (_BaseAstNodeFinder3) {
|
|
190
|
+
function FindMembersOfArgumentsVisitor(teamId) {
|
|
191
|
+
var _this3;
|
|
192
|
+
(0, _classCallCheck2.default)(this, FindMembersOfArgumentsVisitor);
|
|
193
|
+
_this3 = _callSuper(this, FindMembersOfArgumentsVisitor);
|
|
194
|
+
(0, _defineProperty2.default)(_this3, "visitTerminalClause", function (terminalClause) {
|
|
195
|
+
if (terminalClause.operand === undefined) {
|
|
196
|
+
return [];
|
|
197
|
+
}
|
|
198
|
+
return terminalClause.operand.accept(_this3);
|
|
199
|
+
});
|
|
200
|
+
(0, _defineProperty2.default)(_this3, "visitFunctionOperand", function (functionOperand) {
|
|
201
|
+
var functionName = functionOperand.function.value.toLowerCase();
|
|
202
|
+
|
|
203
|
+
// Only process membersOf function
|
|
204
|
+
if (functionName !== 'membersof') {
|
|
205
|
+
return [];
|
|
206
|
+
}
|
|
207
|
+
var matchingArgs = [];
|
|
208
|
+
functionOperand.arguments.forEach(function (arg) {
|
|
209
|
+
// Normalize both values by removing extra whitespace for comparison
|
|
210
|
+
// This handles both "id: uuid" and "id:uuid" formats
|
|
211
|
+
var normalizedArgValue = _this3.normalizeValue(arg.value);
|
|
212
|
+
var normalizedTeamId = _this3.normalizeValue(_this3.teamId);
|
|
213
|
+
if (_this3.equalsIgnoreCase(normalizedArgValue, normalizedTeamId)) {
|
|
214
|
+
matchingArgs.push(arg);
|
|
215
|
+
}
|
|
216
|
+
});
|
|
217
|
+
return matchingArgs;
|
|
218
|
+
});
|
|
219
|
+
_this3.teamId = teamId;
|
|
220
|
+
return _this3;
|
|
221
|
+
}
|
|
222
|
+
(0, _inherits2.default)(FindMembersOfArgumentsVisitor, _BaseAstNodeFinder3);
|
|
223
|
+
return (0, _createClass2.default)(FindMembersOfArgumentsVisitor, [{
|
|
224
|
+
key: "normalizeValue",
|
|
225
|
+
value:
|
|
226
|
+
/**
|
|
227
|
+
* Normalize value by removing extra whitespace around colons and trimming.
|
|
228
|
+
* This handles variations like "id: uuid" vs "id:uuid" vs "id: uuid".
|
|
229
|
+
*/
|
|
230
|
+
function normalizeValue(value) {
|
|
231
|
+
return value.replace(/\s*:\s*/g, ':').trim();
|
|
232
|
+
}
|
|
233
|
+
}]);
|
|
234
|
+
}(BaseAstNodeFinder);
|
|
@@ -12,6 +12,7 @@ var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/ge
|
|
|
12
12
|
var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits"));
|
|
13
13
|
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
14
14
|
var _jqlAst = require("@atlaskit/jql-ast");
|
|
15
|
+
var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
|
|
15
16
|
function _callSuper(t, o, e) { return o = (0, _getPrototypeOf2.default)(o), (0, _possibleConstructorReturn2.default)(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], (0, _getPrototypeOf2.default)(t).constructor) : o.apply(t, e)); }
|
|
16
17
|
function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
|
|
17
18
|
/**
|
|
@@ -31,10 +32,10 @@ var ValidQueryVisitor = exports.ValidQueryVisitor = /*#__PURE__*/function (_Abst
|
|
|
31
32
|
function ValidQueryVisitor() {
|
|
32
33
|
var _this;
|
|
33
34
|
(0, _classCallCheck2.default)(this, ValidQueryVisitor);
|
|
34
|
-
for (var _len = arguments.length,
|
|
35
|
-
|
|
35
|
+
for (var _len = arguments.length, _args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
36
|
+
_args[_key] = arguments[_key];
|
|
36
37
|
}
|
|
37
|
-
_this = _callSuper(this, ValidQueryVisitor, [].concat(
|
|
38
|
+
_this = _callSuper(this, ValidQueryVisitor, [].concat(_args));
|
|
38
39
|
(0, _defineProperty2.default)(_this, "visitQuery", function (query) {
|
|
39
40
|
if (!query.where) {
|
|
40
41
|
return '';
|
|
@@ -74,6 +75,18 @@ var ValidQueryVisitor = exports.ValidQueryVisitor = /*#__PURE__*/function (_Abst
|
|
|
74
75
|
return !!value;
|
|
75
76
|
}).join(', '), ")");
|
|
76
77
|
});
|
|
78
|
+
(0, _defineProperty2.default)(_this, "visitFunctionOperand", function (functionOperand) {
|
|
79
|
+
// Only include membersOf function as it has arguments that need hydration
|
|
80
|
+
// Other functions like currentUser() don't have hydratable arguments
|
|
81
|
+
var functionName = functionOperand.function.value.toLowerCase();
|
|
82
|
+
if (functionName !== 'membersof' || !(0, _platformFeatureFlags.fg)('jira_update_jql_membersof_teams')) {
|
|
83
|
+
return '';
|
|
84
|
+
}
|
|
85
|
+
var args = functionOperand.arguments.map(function (arg) {
|
|
86
|
+
return arg.text;
|
|
87
|
+
}).join(', ');
|
|
88
|
+
return "".concat(functionOperand.function.text, "(").concat(args, ")");
|
|
89
|
+
});
|
|
77
90
|
return _this;
|
|
78
91
|
}
|
|
79
92
|
(0, _inherits2.default)(ValidQueryVisitor, _AbstractJastVisitor);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { ANALYTICS_CHANNEL, useJqlPackageAnalytics } from '@atlaskit/jql-editor-common';
|
|
2
2
|
export const useJqlEditorAnalytics = analyticsSource => {
|
|
3
|
-
return useJqlPackageAnalytics(analyticsSource, "@atlaskit/jql-editor", "5.
|
|
3
|
+
return useJqlPackageAnalytics(analyticsSource, "@atlaskit/jql-editor", "5.9.1", ANALYTICS_CHANNEL);
|
|
4
4
|
};
|
|
@@ -13,7 +13,13 @@ export const replaceRichInlineNodes = (editorState, hydratedValues) => {
|
|
|
13
13
|
Object.entries(hydratedValues).forEach(([fieldName, values]) => {
|
|
14
14
|
values.forEach(value => {
|
|
15
15
|
if (value.type === 'user' || value.type === 'team' && fg('jira_update_jql_teams')) {
|
|
16
|
-
|
|
16
|
+
// First try to find as direct value operand (e.g., Team[Team] = uuid)
|
|
17
|
+
let astNodes = getValueNodes(ast, fieldName, value.id);
|
|
18
|
+
|
|
19
|
+
// If not found as direct value and it's a team, try to find in membersOf function arguments
|
|
20
|
+
if (astNodes.length === 0 && value.type === 'team' && fg('jira_update_jql_membersof_teams')) {
|
|
21
|
+
astNodes = getMembersOfArgumentNodes(ast, value.id);
|
|
22
|
+
}
|
|
17
23
|
astNodes.forEach(astNode => {
|
|
18
24
|
if (astNode.position) {
|
|
19
25
|
const [from, to] = astNode.position;
|
|
@@ -64,9 +70,20 @@ const getValueNodes = (ast, field, value) => {
|
|
|
64
70
|
}
|
|
65
71
|
return ast.query.accept(new FindValuesVisitor(field, value));
|
|
66
72
|
};
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
73
|
+
const getMembersOfArgumentNodes = (ast, teamId) => {
|
|
74
|
+
if (!ast.query) {
|
|
75
|
+
return [];
|
|
76
|
+
}
|
|
77
|
+
return ast.query.accept(new FindMembersOfArgumentsVisitor(teamId));
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Base visitor class for traversing JQL AST to find specific nodes.
|
|
82
|
+
* Provides common traversal logic - subclasses implement specific matching.
|
|
83
|
+
*/
|
|
84
|
+
class BaseAstNodeFinder extends AbstractJastVisitor {
|
|
85
|
+
constructor(...args) {
|
|
86
|
+
super(...args);
|
|
70
87
|
_defineProperty(this, "visitQuery", query => {
|
|
71
88
|
if (query.where === undefined) {
|
|
72
89
|
return [];
|
|
@@ -74,10 +91,39 @@ class FindValuesVisitor extends AbstractJastVisitor {
|
|
|
74
91
|
return query.where.accept(this);
|
|
75
92
|
});
|
|
76
93
|
_defineProperty(this, "visitCompoundClause", compoundClause => {
|
|
77
|
-
return compoundClause.clauses.reduce((
|
|
78
|
-
return [...
|
|
94
|
+
return compoundClause.clauses.reduce((results, clause) => {
|
|
95
|
+
return [...results, ...clause.accept(this)];
|
|
79
96
|
}, []);
|
|
80
97
|
});
|
|
98
|
+
_defineProperty(this, "visitNotClause", notClause => {
|
|
99
|
+
return notClause.clause.accept(this);
|
|
100
|
+
});
|
|
101
|
+
_defineProperty(this, "visitListOperand", listOperand => {
|
|
102
|
+
return listOperand.values.reduce((results, operand) => {
|
|
103
|
+
return [...results, ...operand.accept(this)];
|
|
104
|
+
}, []);
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
aggregateResult(aggregate, nextResult) {
|
|
108
|
+
return [...aggregate, ...nextResult];
|
|
109
|
+
}
|
|
110
|
+
defaultResult() {
|
|
111
|
+
return [];
|
|
112
|
+
}
|
|
113
|
+
equalsIgnoreCase(a, b) {
|
|
114
|
+
return a.localeCompare(b, undefined, {
|
|
115
|
+
sensitivity: 'base'
|
|
116
|
+
}) === 0;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Visitor that finds value operands matching a specific field and value.
|
|
122
|
+
* Used for direct value queries like "assignee = john-doe" or "Team[team] = uuid".
|
|
123
|
+
*/
|
|
124
|
+
class FindValuesVisitor extends BaseAstNodeFinder {
|
|
125
|
+
constructor(field, value) {
|
|
126
|
+
super();
|
|
81
127
|
_defineProperty(this, "visitTerminalClause", terminalClause => {
|
|
82
128
|
if (!this.equalsIgnoreCase(terminalClause.field.value, this.field)) {
|
|
83
129
|
return [];
|
|
@@ -87,32 +133,56 @@ class FindValuesVisitor extends AbstractJastVisitor {
|
|
|
87
133
|
}
|
|
88
134
|
return terminalClause.operand.accept(this);
|
|
89
135
|
});
|
|
90
|
-
_defineProperty(this, "visitNotClause", notClause => {
|
|
91
|
-
return notClause.clause.accept(this);
|
|
92
|
-
});
|
|
93
136
|
_defineProperty(this, "visitValueOperand", valueOperand => {
|
|
94
137
|
if (!this.equalsIgnoreCase(valueOperand.value, this.value)) {
|
|
95
138
|
return [];
|
|
96
139
|
}
|
|
97
140
|
return [valueOperand];
|
|
98
141
|
});
|
|
99
|
-
_defineProperty(this, "visitListOperand", listOperand => {
|
|
100
|
-
return listOperand.values.reduce((values, operand) => {
|
|
101
|
-
return [...values, ...operand.accept(this)];
|
|
102
|
-
}, []);
|
|
103
|
-
});
|
|
104
142
|
this.field = field;
|
|
105
143
|
this.value = value;
|
|
106
144
|
}
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Visitor that finds membersOf function arguments matching a specific team ID.
|
|
149
|
+
* Used for queries like "assignee in membersOf("id: <uuid>")".
|
|
150
|
+
*/
|
|
151
|
+
class FindMembersOfArgumentsVisitor extends BaseAstNodeFinder {
|
|
152
|
+
constructor(teamId) {
|
|
153
|
+
super();
|
|
154
|
+
_defineProperty(this, "visitTerminalClause", terminalClause => {
|
|
155
|
+
if (terminalClause.operand === undefined) {
|
|
156
|
+
return [];
|
|
157
|
+
}
|
|
158
|
+
return terminalClause.operand.accept(this);
|
|
159
|
+
});
|
|
160
|
+
_defineProperty(this, "visitFunctionOperand", functionOperand => {
|
|
161
|
+
const functionName = functionOperand.function.value.toLowerCase();
|
|
162
|
+
|
|
163
|
+
// Only process membersOf function
|
|
164
|
+
if (functionName !== 'membersof') {
|
|
165
|
+
return [];
|
|
166
|
+
}
|
|
167
|
+
const matchingArgs = [];
|
|
168
|
+
functionOperand.arguments.forEach(arg => {
|
|
169
|
+
// Normalize both values by removing extra whitespace for comparison
|
|
170
|
+
// This handles both "id: uuid" and "id:uuid" formats
|
|
171
|
+
const normalizedArgValue = this.normalizeValue(arg.value);
|
|
172
|
+
const normalizedTeamId = this.normalizeValue(this.teamId);
|
|
173
|
+
if (this.equalsIgnoreCase(normalizedArgValue, normalizedTeamId)) {
|
|
174
|
+
matchingArgs.push(arg);
|
|
175
|
+
}
|
|
176
|
+
});
|
|
177
|
+
return matchingArgs;
|
|
178
|
+
});
|
|
179
|
+
this.teamId = teamId;
|
|
112
180
|
}
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
181
|
+
/**
|
|
182
|
+
* Normalize value by removing extra whitespace around colons and trimming.
|
|
183
|
+
* This handles variations like "id: uuid" vs "id:uuid" vs "id: uuid".
|
|
184
|
+
*/
|
|
185
|
+
normalizeValue(value) {
|
|
186
|
+
return value.replace(/\s*:\s*/g, ':').trim();
|
|
117
187
|
}
|
|
118
188
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
2
2
|
import { AbstractJastVisitor } from '@atlaskit/jql-ast';
|
|
3
|
+
import { fg } from '@atlaskit/platform-feature-flags';
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* Given an AST with parse errors, this visitor returns a valid query that is equivalent for hydration purposes
|
|
@@ -15,8 +16,8 @@ import { AbstractJastVisitor } from '@atlaskit/jql-ast';
|
|
|
15
16
|
* - Equivalent query: "project = EM and status in (Done)"
|
|
16
17
|
*/
|
|
17
18
|
export class ValidQueryVisitor extends AbstractJastVisitor {
|
|
18
|
-
constructor(...
|
|
19
|
-
super(...
|
|
19
|
+
constructor(..._args) {
|
|
20
|
+
super(..._args);
|
|
20
21
|
_defineProperty(this, "visitQuery", query => {
|
|
21
22
|
if (!query.where) {
|
|
22
23
|
return '';
|
|
@@ -50,6 +51,16 @@ export class ValidQueryVisitor extends AbstractJastVisitor {
|
|
|
50
51
|
_defineProperty(this, "visitListOperand", listOperand => {
|
|
51
52
|
return `(${listOperand.values.map(value => value.accept(this)).filter(value => !!value).join(', ')})`;
|
|
52
53
|
});
|
|
54
|
+
_defineProperty(this, "visitFunctionOperand", functionOperand => {
|
|
55
|
+
// Only include membersOf function as it has arguments that need hydration
|
|
56
|
+
// Other functions like currentUser() don't have hydratable arguments
|
|
57
|
+
const functionName = functionOperand.function.value.toLowerCase();
|
|
58
|
+
if (functionName !== 'membersof' || !fg('jira_update_jql_membersof_teams')) {
|
|
59
|
+
return '';
|
|
60
|
+
}
|
|
61
|
+
const args = functionOperand.arguments.map(arg => arg.text).join(', ');
|
|
62
|
+
return `${functionOperand.function.text}(${args})`;
|
|
63
|
+
});
|
|
53
64
|
}
|
|
54
65
|
defaultResult() {
|
|
55
66
|
return '';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import { ANALYTICS_CHANNEL, useJqlPackageAnalytics } from '@atlaskit/jql-editor-common';
|
|
2
2
|
export var useJqlEditorAnalytics = function useJqlEditorAnalytics(analyticsSource) {
|
|
3
|
-
return useJqlPackageAnalytics(analyticsSource, "@atlaskit/jql-editor", "5.
|
|
3
|
+
return useJqlPackageAnalytics(analyticsSource, "@atlaskit/jql-editor", "5.9.1", ANALYTICS_CHANNEL);
|
|
4
4
|
};
|
|
@@ -27,7 +27,13 @@ export var replaceRichInlineNodes = function replaceRichInlineNodes(editorState,
|
|
|
27
27
|
values = _ref2[1];
|
|
28
28
|
values.forEach(function (value) {
|
|
29
29
|
if (value.type === 'user' || value.type === 'team' && fg('jira_update_jql_teams')) {
|
|
30
|
+
// First try to find as direct value operand (e.g., Team[Team] = uuid)
|
|
30
31
|
var astNodes = getValueNodes(ast, fieldName, value.id);
|
|
32
|
+
|
|
33
|
+
// If not found as direct value and it's a team, try to find in membersOf function arguments
|
|
34
|
+
if (astNodes.length === 0 && value.type === 'team' && fg('jira_update_jql_membersof_teams')) {
|
|
35
|
+
astNodes = getMembersOfArgumentNodes(ast, value.id);
|
|
36
|
+
}
|
|
31
37
|
astNodes.forEach(function (astNode) {
|
|
32
38
|
if (astNode.position) {
|
|
33
39
|
var _astNode$position = _slicedToArray(astNode.position, 2),
|
|
@@ -78,11 +84,25 @@ var getValueNodes = function getValueNodes(ast, field, value) {
|
|
|
78
84
|
}
|
|
79
85
|
return ast.query.accept(new FindValuesVisitor(field, value));
|
|
80
86
|
};
|
|
81
|
-
var
|
|
82
|
-
|
|
87
|
+
var getMembersOfArgumentNodes = function getMembersOfArgumentNodes(ast, teamId) {
|
|
88
|
+
if (!ast.query) {
|
|
89
|
+
return [];
|
|
90
|
+
}
|
|
91
|
+
return ast.query.accept(new FindMembersOfArgumentsVisitor(teamId));
|
|
92
|
+
};
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Base visitor class for traversing JQL AST to find specific nodes.
|
|
96
|
+
* Provides common traversal logic - subclasses implement specific matching.
|
|
97
|
+
*/
|
|
98
|
+
var BaseAstNodeFinder = /*#__PURE__*/function (_AbstractJastVisitor) {
|
|
99
|
+
function BaseAstNodeFinder() {
|
|
83
100
|
var _this;
|
|
84
|
-
_classCallCheck(this,
|
|
85
|
-
|
|
101
|
+
_classCallCheck(this, BaseAstNodeFinder);
|
|
102
|
+
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
103
|
+
args[_key] = arguments[_key];
|
|
104
|
+
}
|
|
105
|
+
_this = _callSuper(this, BaseAstNodeFinder, [].concat(args));
|
|
86
106
|
_defineProperty(_this, "visitQuery", function (query) {
|
|
87
107
|
if (query.where === undefined) {
|
|
88
108
|
return [];
|
|
@@ -90,39 +110,22 @@ var FindValuesVisitor = /*#__PURE__*/function (_AbstractJastVisitor) {
|
|
|
90
110
|
return query.where.accept(_this);
|
|
91
111
|
});
|
|
92
112
|
_defineProperty(_this, "visitCompoundClause", function (compoundClause) {
|
|
93
|
-
return compoundClause.clauses.reduce(function (
|
|
94
|
-
return [].concat(_toConsumableArray(
|
|
113
|
+
return compoundClause.clauses.reduce(function (results, clause) {
|
|
114
|
+
return [].concat(_toConsumableArray(results), _toConsumableArray(clause.accept(_this)));
|
|
95
115
|
}, []);
|
|
96
116
|
});
|
|
97
|
-
_defineProperty(_this, "visitTerminalClause", function (terminalClause) {
|
|
98
|
-
if (!_this.equalsIgnoreCase(terminalClause.field.value, _this.field)) {
|
|
99
|
-
return [];
|
|
100
|
-
}
|
|
101
|
-
if (terminalClause.operand === undefined) {
|
|
102
|
-
return [];
|
|
103
|
-
}
|
|
104
|
-
return terminalClause.operand.accept(_this);
|
|
105
|
-
});
|
|
106
117
|
_defineProperty(_this, "visitNotClause", function (notClause) {
|
|
107
118
|
return notClause.clause.accept(_this);
|
|
108
119
|
});
|
|
109
|
-
_defineProperty(_this, "visitValueOperand", function (valueOperand) {
|
|
110
|
-
if (!_this.equalsIgnoreCase(valueOperand.value, _this.value)) {
|
|
111
|
-
return [];
|
|
112
|
-
}
|
|
113
|
-
return [valueOperand];
|
|
114
|
-
});
|
|
115
120
|
_defineProperty(_this, "visitListOperand", function (listOperand) {
|
|
116
|
-
return listOperand.values.reduce(function (
|
|
117
|
-
return [].concat(_toConsumableArray(
|
|
121
|
+
return listOperand.values.reduce(function (results, operand) {
|
|
122
|
+
return [].concat(_toConsumableArray(results), _toConsumableArray(operand.accept(_this)));
|
|
118
123
|
}, []);
|
|
119
124
|
});
|
|
120
|
-
_this.field = field;
|
|
121
|
-
_this.value = value;
|
|
122
125
|
return _this;
|
|
123
126
|
}
|
|
124
|
-
_inherits(
|
|
125
|
-
return _createClass(
|
|
127
|
+
_inherits(BaseAstNodeFinder, _AbstractJastVisitor);
|
|
128
|
+
return _createClass(BaseAstNodeFinder, [{
|
|
126
129
|
key: "aggregateResult",
|
|
127
130
|
value: function aggregateResult(aggregate, nextResult) {
|
|
128
131
|
return [].concat(_toConsumableArray(aggregate), _toConsumableArray(nextResult));
|
|
@@ -140,4 +143,85 @@ var FindValuesVisitor = /*#__PURE__*/function (_AbstractJastVisitor) {
|
|
|
140
143
|
}) === 0;
|
|
141
144
|
}
|
|
142
145
|
}]);
|
|
143
|
-
}(AbstractJastVisitor);
|
|
146
|
+
}(AbstractJastVisitor);
|
|
147
|
+
/**
|
|
148
|
+
* Visitor that finds value operands matching a specific field and value.
|
|
149
|
+
* Used for direct value queries like "assignee = john-doe" or "Team[team] = uuid".
|
|
150
|
+
*/
|
|
151
|
+
var FindValuesVisitor = /*#__PURE__*/function (_BaseAstNodeFinder2) {
|
|
152
|
+
function FindValuesVisitor(field, value) {
|
|
153
|
+
var _this2;
|
|
154
|
+
_classCallCheck(this, FindValuesVisitor);
|
|
155
|
+
_this2 = _callSuper(this, FindValuesVisitor);
|
|
156
|
+
_defineProperty(_this2, "visitTerminalClause", function (terminalClause) {
|
|
157
|
+
if (!_this2.equalsIgnoreCase(terminalClause.field.value, _this2.field)) {
|
|
158
|
+
return [];
|
|
159
|
+
}
|
|
160
|
+
if (terminalClause.operand === undefined) {
|
|
161
|
+
return [];
|
|
162
|
+
}
|
|
163
|
+
return terminalClause.operand.accept(_this2);
|
|
164
|
+
});
|
|
165
|
+
_defineProperty(_this2, "visitValueOperand", function (valueOperand) {
|
|
166
|
+
if (!_this2.equalsIgnoreCase(valueOperand.value, _this2.value)) {
|
|
167
|
+
return [];
|
|
168
|
+
}
|
|
169
|
+
return [valueOperand];
|
|
170
|
+
});
|
|
171
|
+
_this2.field = field;
|
|
172
|
+
_this2.value = value;
|
|
173
|
+
return _this2;
|
|
174
|
+
}
|
|
175
|
+
_inherits(FindValuesVisitor, _BaseAstNodeFinder2);
|
|
176
|
+
return _createClass(FindValuesVisitor);
|
|
177
|
+
}(BaseAstNodeFinder);
|
|
178
|
+
/**
|
|
179
|
+
* Visitor that finds membersOf function arguments matching a specific team ID.
|
|
180
|
+
* Used for queries like "assignee in membersOf("id: <uuid>")".
|
|
181
|
+
*/
|
|
182
|
+
var FindMembersOfArgumentsVisitor = /*#__PURE__*/function (_BaseAstNodeFinder3) {
|
|
183
|
+
function FindMembersOfArgumentsVisitor(teamId) {
|
|
184
|
+
var _this3;
|
|
185
|
+
_classCallCheck(this, FindMembersOfArgumentsVisitor);
|
|
186
|
+
_this3 = _callSuper(this, FindMembersOfArgumentsVisitor);
|
|
187
|
+
_defineProperty(_this3, "visitTerminalClause", function (terminalClause) {
|
|
188
|
+
if (terminalClause.operand === undefined) {
|
|
189
|
+
return [];
|
|
190
|
+
}
|
|
191
|
+
return terminalClause.operand.accept(_this3);
|
|
192
|
+
});
|
|
193
|
+
_defineProperty(_this3, "visitFunctionOperand", function (functionOperand) {
|
|
194
|
+
var functionName = functionOperand.function.value.toLowerCase();
|
|
195
|
+
|
|
196
|
+
// Only process membersOf function
|
|
197
|
+
if (functionName !== 'membersof') {
|
|
198
|
+
return [];
|
|
199
|
+
}
|
|
200
|
+
var matchingArgs = [];
|
|
201
|
+
functionOperand.arguments.forEach(function (arg) {
|
|
202
|
+
// Normalize both values by removing extra whitespace for comparison
|
|
203
|
+
// This handles both "id: uuid" and "id:uuid" formats
|
|
204
|
+
var normalizedArgValue = _this3.normalizeValue(arg.value);
|
|
205
|
+
var normalizedTeamId = _this3.normalizeValue(_this3.teamId);
|
|
206
|
+
if (_this3.equalsIgnoreCase(normalizedArgValue, normalizedTeamId)) {
|
|
207
|
+
matchingArgs.push(arg);
|
|
208
|
+
}
|
|
209
|
+
});
|
|
210
|
+
return matchingArgs;
|
|
211
|
+
});
|
|
212
|
+
_this3.teamId = teamId;
|
|
213
|
+
return _this3;
|
|
214
|
+
}
|
|
215
|
+
_inherits(FindMembersOfArgumentsVisitor, _BaseAstNodeFinder3);
|
|
216
|
+
return _createClass(FindMembersOfArgumentsVisitor, [{
|
|
217
|
+
key: "normalizeValue",
|
|
218
|
+
value:
|
|
219
|
+
/**
|
|
220
|
+
* Normalize value by removing extra whitespace around colons and trimming.
|
|
221
|
+
* This handles variations like "id: uuid" vs "id:uuid" vs "id: uuid".
|
|
222
|
+
*/
|
|
223
|
+
function normalizeValue(value) {
|
|
224
|
+
return value.replace(/\s*:\s*/g, ':').trim();
|
|
225
|
+
}
|
|
226
|
+
}]);
|
|
227
|
+
}(BaseAstNodeFinder);
|
|
@@ -7,6 +7,7 @@ import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
|
7
7
|
function _callSuper(t, o, e) { return o = _getPrototypeOf(o), _possibleConstructorReturn(t, _isNativeReflectConstruct() ? Reflect.construct(o, e || [], _getPrototypeOf(t).constructor) : o.apply(t, e)); }
|
|
8
8
|
function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct = function _isNativeReflectConstruct() { return !!t; })(); }
|
|
9
9
|
import { AbstractJastVisitor } from '@atlaskit/jql-ast';
|
|
10
|
+
import { fg } from '@atlaskit/platform-feature-flags';
|
|
10
11
|
|
|
11
12
|
/**
|
|
12
13
|
* Given an AST with parse errors, this visitor returns a valid query that is equivalent for hydration purposes
|
|
@@ -25,10 +26,10 @@ export var ValidQueryVisitor = /*#__PURE__*/function (_AbstractJastVisitor) {
|
|
|
25
26
|
function ValidQueryVisitor() {
|
|
26
27
|
var _this;
|
|
27
28
|
_classCallCheck(this, ValidQueryVisitor);
|
|
28
|
-
for (var _len = arguments.length,
|
|
29
|
-
|
|
29
|
+
for (var _len = arguments.length, _args = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
30
|
+
_args[_key] = arguments[_key];
|
|
30
31
|
}
|
|
31
|
-
_this = _callSuper(this, ValidQueryVisitor, [].concat(
|
|
32
|
+
_this = _callSuper(this, ValidQueryVisitor, [].concat(_args));
|
|
32
33
|
_defineProperty(_this, "visitQuery", function (query) {
|
|
33
34
|
if (!query.where) {
|
|
34
35
|
return '';
|
|
@@ -68,6 +69,18 @@ export var ValidQueryVisitor = /*#__PURE__*/function (_AbstractJastVisitor) {
|
|
|
68
69
|
return !!value;
|
|
69
70
|
}).join(', '), ")");
|
|
70
71
|
});
|
|
72
|
+
_defineProperty(_this, "visitFunctionOperand", function (functionOperand) {
|
|
73
|
+
// Only include membersOf function as it has arguments that need hydration
|
|
74
|
+
// Other functions like currentUser() don't have hydratable arguments
|
|
75
|
+
var functionName = functionOperand.function.value.toLowerCase();
|
|
76
|
+
if (functionName !== 'membersof' || !fg('jira_update_jql_membersof_teams')) {
|
|
77
|
+
return '';
|
|
78
|
+
}
|
|
79
|
+
var args = functionOperand.arguments.map(function (arg) {
|
|
80
|
+
return arg.text;
|
|
81
|
+
}).join(', ');
|
|
82
|
+
return "".concat(functionOperand.function.text, "(").concat(args, ")");
|
|
83
|
+
});
|
|
71
84
|
return _this;
|
|
72
85
|
}
|
|
73
86
|
_inherits(ValidQueryVisitor, _AbstractJastVisitor);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AbstractJastVisitor, type CompoundClause, type ListOperand, type NotClause, type Query, type TerminalClause, type ValueOperand } from '@atlaskit/jql-ast';
|
|
1
|
+
import { AbstractJastVisitor, type CompoundClause, type FunctionOperand, type ListOperand, type NotClause, type Query, type TerminalClause, type ValueOperand } from '@atlaskit/jql-ast';
|
|
2
2
|
/**
|
|
3
3
|
* Given an AST with parse errors, this visitor returns a valid query that is equivalent for hydration purposes
|
|
4
4
|
* (i.e. just fields, operators and values). Resulting query is generated on a best-effort basis and depends on
|
|
@@ -19,5 +19,6 @@ export declare class ValidQueryVisitor extends AbstractJastVisitor<string> {
|
|
|
19
19
|
visitNotClause: (notClause: NotClause) => string;
|
|
20
20
|
visitValueOperand: (valueOperand: ValueOperand) => string;
|
|
21
21
|
visitListOperand: (listOperand: ListOperand) => string;
|
|
22
|
+
visitFunctionOperand: (functionOperand: FunctionOperand) => string;
|
|
22
23
|
protected defaultResult(): string;
|
|
23
24
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { AbstractJastVisitor, type CompoundClause, type ListOperand, type NotClause, type Query, type TerminalClause, type ValueOperand } from '@atlaskit/jql-ast';
|
|
1
|
+
import { AbstractJastVisitor, type CompoundClause, type FunctionOperand, type ListOperand, type NotClause, type Query, type TerminalClause, type ValueOperand } from '@atlaskit/jql-ast';
|
|
2
2
|
/**
|
|
3
3
|
* Given an AST with parse errors, this visitor returns a valid query that is equivalent for hydration purposes
|
|
4
4
|
* (i.e. just fields, operators and values). Resulting query is generated on a best-effort basis and depends on
|
|
@@ -19,5 +19,6 @@ export declare class ValidQueryVisitor extends AbstractJastVisitor<string> {
|
|
|
19
19
|
visitNotClause: (notClause: NotClause) => string;
|
|
20
20
|
visitValueOperand: (valueOperand: ValueOperand) => string;
|
|
21
21
|
visitListOperand: (listOperand: ListOperand) => string;
|
|
22
|
+
visitFunctionOperand: (functionOperand: FunctionOperand) => string;
|
|
22
23
|
protected defaultResult(): string;
|
|
23
24
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/jql-editor",
|
|
3
|
-
"version": "5.9.
|
|
3
|
+
"version": "5.9.2",
|
|
4
4
|
"description": "This package allows consumers to render an advanced JQL editor component to enable autocomplete-assisted authoring and validation of JQL queries.",
|
|
5
5
|
"author": "Atlassian Pty Ltd",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -36,9 +36,9 @@
|
|
|
36
36
|
"@atlaskit/analytics-gas-types": "^5.1.0",
|
|
37
37
|
"@atlaskit/analytics-next": "^11.1.0",
|
|
38
38
|
"@atlaskit/avatar": "^25.5.0",
|
|
39
|
-
"@atlaskit/button": "^23.
|
|
39
|
+
"@atlaskit/button": "^23.7.0",
|
|
40
40
|
"@atlaskit/editor-prosemirror": "7.0.0",
|
|
41
|
-
"@atlaskit/form": "^
|
|
41
|
+
"@atlaskit/form": "^15.0.0",
|
|
42
42
|
"@atlaskit/icon": "^29.0.0",
|
|
43
43
|
"@atlaskit/jql-ast": "^3.3.0",
|
|
44
44
|
"@atlaskit/jql-autocomplete": "^2.0.0",
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
"@atlaskit/teams-avatar": "^2.4.0",
|
|
55
55
|
"@atlaskit/theme": "^21.0.0",
|
|
56
56
|
"@atlaskit/tokens": "^8.4.0",
|
|
57
|
-
"@atlaskit/tooltip": "^20.
|
|
57
|
+
"@atlaskit/tooltip": "^20.11.0",
|
|
58
58
|
"@babel/runtime": "^7.0.0",
|
|
59
59
|
"@emotion/react": "^11.7.1",
|
|
60
60
|
"@emotion/styled": "^11.0.0",
|
|
@@ -146,6 +146,9 @@
|
|
|
146
146
|
"jira_update_jql_teams": {
|
|
147
147
|
"type": "boolean"
|
|
148
148
|
},
|
|
149
|
+
"jira_update_jql_membersof_teams": {
|
|
150
|
+
"type": "boolean"
|
|
151
|
+
},
|
|
149
152
|
"list_lovability_improving_filters": {
|
|
150
153
|
"type": "boolean"
|
|
151
154
|
},
|