gramene-search 2.13.4 → 2.14.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/dist/index.js CHANGED
@@ -4862,15 +4862,13 @@ const $12feb7ca48271e17$var$FETCH_FIELDS = [
4862
4862
  ...(0, $4b8473139e48e77e$export$705aff68da3ddba0)
4863
4863
  ])
4864
4864
  ];
4865
+ // Default columns, in display order. The two stress fields are adjacent so the
4866
+ // view can merge them into a single "Activated/Repressed by condition" column.
4865
4867
  const $12feb7ca48271e17$export$e4bc2ac09afbc604 = [
4866
4868
  'id',
4867
- 'name',
4868
- 'system_name',
4869
- 'biotype',
4870
- 'expr_class__attr_ss',
4871
- 'expr_organ_level__attr_ss',
4872
- 'expr_tau__attr_f',
4873
4869
  'expr_max_tpm__attr_f',
4870
+ 'expr_organ_level__attr_ss',
4871
+ 'expr_class__attr_ss',
4874
4872
  'expr_activated_by__attr_ss',
4875
4873
  'expr_repressed_by__attr_ss'
4876
4874
  ];
@@ -16947,9 +16945,12 @@ var $1fd2507769d5bd00$export$2e2bcd8739ae039 = (0, $gXNCa$reduxbundlerreact.conn
16947
16945
 
16948
16946
 
16949
16947
  const { MAX_GENES: $8f8e530286a37ce9$var$MAX_GENES } = (0, $12feb7ca48271e17$export$d00a9fd01497b827);
16950
- // expr_organ_level expands into one column per organ (the heatmap block); every
16951
- // other offered field maps to exactly one column.
16948
+ // expr_organ_level expands into one column per organ (the heatmap block).
16952
16949
  const $8f8e530286a37ce9$var$ORGAN_FIELD = 'expr_organ_level__attr_ss';
16950
+ // The two stress fields render as a single merged column.
16951
+ const $8f8e530286a37ce9$var$STRESS_UP = 'expr_activated_by__attr_ss';
16952
+ const $8f8e530286a37ce9$var$STRESS_DOWN = 'expr_repressed_by__attr_ss';
16953
+ const $8f8e530286a37ce9$var$STRESS_COL = 'stress';
16953
16954
  const $8f8e530286a37ce9$var$DEFAULT_COL_DEF = {
16954
16955
  resizable: true,
16955
16956
  sortable: true,
@@ -16971,40 +16972,49 @@ const $8f8e530286a37ce9$var$WIDTHS = {
16971
16972
  expr_tau__attr_f: 80,
16972
16973
  expr_max_tpm__attr_f: 100,
16973
16974
  expr_n_organs_detected__attr_i: 90,
16974
- expr_activated_by__attr_ss: 190,
16975
- expr_repressed_by__attr_ss: 190,
16976
16975
  expr_specific_to__attr_ss: 150,
16977
16976
  expr_enhanced_in__attr_ss: 150,
16978
16977
  expr_high_in__attr_ss: 150
16979
16978
  };
16980
16979
  const $8f8e530286a37ce9$var$joinValues = (p)=>Array.isArray(p.value) ? p.value.map((v)=>String(v).replace(/_/g, ' ')).join(', ') : p.value ?? '';
16981
- // ↑activated / ↓repressed condition chips.
16982
- const $8f8e530286a37ce9$var$chipRenderer = (dir)=>({ value: value })=>{
16983
- const list = Array.isArray(value) ? value : value ? [
16984
- value
16985
- ] : [];
16986
- if (!list.length) return null;
16987
- return /*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsx)("span", {
16988
- children: list.map((c, i)=>/*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsx)("span", {
16989
- style: {
16990
- fontSize: 10,
16991
- lineHeight: '16px',
16992
- padding: '0 4px',
16993
- borderRadius: 2,
16994
- marginRight: 3,
16995
- whiteSpace: 'nowrap',
16996
- background: (0, $4b8473139e48e77e$export$c6dbe9be8c8b382e)[dir].bg,
16997
- color: (0, $4b8473139e48e77e$export$c6dbe9be8c8b382e)[dir].fg
16998
- },
16999
- children: (dir === 'up' ? "\u2191" : "\u2193") + c
17000
- }, i))
16980
+ const $8f8e530286a37ce9$var$StressChip = ({ c: c, dir: dir })=>/*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsx)("span", {
16981
+ style: {
16982
+ fontSize: 10,
16983
+ lineHeight: '16px',
16984
+ padding: '0 4px',
16985
+ borderRadius: 2,
16986
+ marginRight: 3,
16987
+ whiteSpace: 'nowrap',
16988
+ background: (0, $4b8473139e48e77e$export$c6dbe9be8c8b382e)[dir].bg,
16989
+ color: (0, $4b8473139e48e77e$export$c6dbe9be8c8b382e)[dir].fg
16990
+ },
16991
+ children: (dir === 'up' ? "\u2191" : "\u2193") + c
16992
+ });
16993
+ // Merged ↑activated / ↓repressed renderer; the two directions are shown per the
16994
+ // picker (a column exists if either field is selected).
16995
+ const $8f8e530286a37ce9$var$stressRenderer = (showUp, showDown)=>({ data: data })=>{
16996
+ const up = showUp && Array.isArray(data && data[$8f8e530286a37ce9$var$STRESS_UP]) ? data[$8f8e530286a37ce9$var$STRESS_UP] : [];
16997
+ const down = showDown && Array.isArray(data && data[$8f8e530286a37ce9$var$STRESS_DOWN]) ? data[$8f8e530286a37ce9$var$STRESS_DOWN] : [];
16998
+ if (!up.length && !down.length) return null;
16999
+ return /*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsxs)("span", {
17000
+ children: [
17001
+ up.map((c, i)=>/*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsx)($8f8e530286a37ce9$var$StressChip, {
17002
+ c: c,
17003
+ dir: "up"
17004
+ }, `u${i}`)),
17005
+ down.map((c, i)=>/*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsx)($8f8e530286a37ce9$var$StressChip, {
17006
+ c: c,
17007
+ dir: "down"
17008
+ }, `d${i}`))
17009
+ ]
17001
17010
  });
17002
17011
  };
17003
17012
  // Vertical header for the narrow organ columns, so full tissue names stay
17004
17013
  // legible without widening the heatmap. Clicking still sorts the column, and a
17005
17014
  // rotated sort arrow is drawn before the label (the default ag-grid sort UI is
17006
17015
  // replaced by this custom header, so we render our own indicator). The arrow
17007
- // sits in the rotated span, so (asc) renders pointing left and ▼ (desc) right.
17016
+ // sits in the -90°-rotated span, so a (asc) renders pointing up and a
17017
+ // ← (desc) pointing down.
17008
17018
  const $8f8e530286a37ce9$var$RotatedHeader = (props)=>{
17009
17019
  const [sort, setSort] = (0, $gXNCa$react.useState)(props.column.getSort ? props.column.getSort() : null);
17010
17020
  (0, $gXNCa$react.useEffect)(()=>{
@@ -17017,7 +17027,7 @@ const $8f8e530286a37ce9$var$RotatedHeader = (props)=>{
17017
17027
  props.column
17018
17028
  ]);
17019
17029
  const onClick = (e)=>props.progressSort && props.progressSort(e.shiftKey);
17020
- const arrow = sort === 'asc' ? "\u25B2\u2009" : sort === 'desc' ? "\u25BC\u2009" : '';
17030
+ const arrow = sort === 'asc' ? "\u2192 " : sort === 'desc' ? "\u2190 " : '';
17021
17031
  return /*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsx)("div", {
17022
17032
  className: "attrtable-rot-header",
17023
17033
  title: props.displayName,
@@ -17031,9 +17041,11 @@ const $8f8e530286a37ce9$var$RotatedHeader = (props)=>{
17031
17041
  });
17032
17042
  };
17033
17043
  const $8f8e530286a37ce9$var$AttrTableViewCmp = (props)=>{
17034
- const { attrTable: attrTable, fieldCatalog: fieldCatalog, fieldCatalogByName: fieldCatalogByName, doToggleAttrTableField: doToggleAttrTableField, doBulkSetAttrTableFields: doBulkSetAttrTableFields, doResetAttrTableFields: doResetAttrTableFields } = props;
17044
+ const { attrTable: attrTable, fieldCatalog: fieldCatalog, fieldCatalogByName: fieldCatalogByName, doToggleAttrTableField: doToggleAttrTableField, doBulkSetAttrTableFields: doBulkSetAttrTableFields, doResetAttrTableFields: doResetAttrTableFields, doAcceptGrameneSuggestion: doAcceptGrameneSuggestion } = props;
17035
17045
  const [showColumns, setShowColumns] = (0, $gXNCa$react.useState)(false);
17036
17046
  const [fieldQuery, setFieldQuery] = (0, $gXNCa$react.useState)('');
17047
+ const [popover, setPopover] = (0, $gXNCa$react.useState)(null);
17048
+ const popRef = (0, $gXNCa$react.useRef)(null);
17037
17049
  const { docs: docs, total: total, truncated: truncated, status: status, error: error, visibleFields: visibleFields } = attrTable;
17038
17050
  const visibleSet = (0, $gXNCa$react.useMemo)(()=>new Set(visibleFields), [
17039
17051
  visibleFields
@@ -17068,46 +17080,33 @@ const $8f8e530286a37ce9$var$AttrTableViewCmp = (props)=>{
17068
17080
  }, [
17069
17081
  docs
17070
17082
  ]);
17071
- // Only the Core identifiers + Expression attributes groups are offered, in
17072
- // catalog order. Falls back to the built-in lists until the catalog loads.
17073
- const orderedFields = (0, $gXNCa$react.useMemo)(()=>{
17074
- const groups = fieldCatalog && fieldCatalog.groups || [];
17075
- const out = [];
17076
- (0, $12feb7ca48271e17$export$53e90de8d659db95).forEach((gid)=>{
17077
- const g = groups.find((x)=>x.id === gid);
17078
- if (g && g.fields) out.push(...g.fields);
17079
- });
17080
- return out.length ? out : [
17081
- ...(0, $12feb7ca48271e17$export$9d77d82cc773e55e),
17082
- ...(0, $4b8473139e48e77e$export$705aff68da3ddba0)
17083
- ];
17084
- }, [
17085
- fieldCatalog
17086
- ]);
17083
+ // Only the Core identifiers + Expression attributes groups are offered.
17087
17084
  const pickerCatalog = (0, $gXNCa$react.useMemo)(()=>{
17088
17085
  if (!fieldCatalog || !fieldCatalog.groups) return null;
17089
17086
  return {
17090
17087
  ...fieldCatalog,
17091
- groups: fieldCatalog.groups.filter((g)=>(0, $12feb7ca48271e17$export$53e90de8d659db95).includes(g.id))
17088
+ groups: fieldCatalog.groups.filter((g)=>[
17089
+ 'core',
17090
+ 'exprattrs'
17091
+ ].includes(g.id))
17092
17092
  };
17093
17093
  }, [
17094
17094
  fieldCatalog
17095
17095
  ]);
17096
+ const labelOf = (f)=>fieldCatalogByName && fieldCatalogByName[f] && fieldCatalogByName[f].label || f;
17097
+ // Columns follow the selected-field order (so the default order is honoured),
17098
+ // expanding organ_level into the heatmap block and merging the two stress
17099
+ // fields into one column.
17096
17100
  const columnDefs = (0, $gXNCa$react.useMemo)(()=>{
17097
- const labelOf = (f)=>fieldCatalogByName && fieldCatalogByName[f] && fieldCatalogByName[f].label || f;
17098
17101
  const cols = [];
17099
- orderedFields.forEach((f)=>{
17100
- if (!visibleSet.has(f)) return;
17101
- const headerName = labelOf(f);
17102
- const width = $8f8e530286a37ce9$var$WIDTHS[f] || 150;
17102
+ let stressDone = false;
17103
+ visibleFields.forEach((f)=>{
17103
17104
  if (f === $8f8e530286a37ce9$var$ORGAN_FIELD) {
17104
17105
  organs.forEach((o, i)=>{
17105
- // The last organ keeps a right border (heatmap's outer edge); the rest
17106
- // drop it so the heatmap reads as one continuous block.
17107
17106
  const last = i === organs.length - 1 ? ' attrtable-organ-last' : '';
17108
17107
  cols.push({
17109
- // No ':' in colId — ag-grid uses colId in internal CSS selectors, where
17110
- // a colon is a metacharacter and silently breaks the column.
17108
+ // No ':' in colId — ag-grid uses colId in internal CSS selectors,
17109
+ // where a colon is a metacharacter and silently breaks the column.
17111
17110
  colId: `organ_${o}`,
17112
17111
  headerName: (0, $4b8473139e48e77e$export$50c1f966fd3af83e)(o),
17113
17112
  headerComponent: $8f8e530286a37ce9$var$RotatedHeader,
@@ -17137,12 +17136,25 @@ const $8f8e530286a37ce9$var$AttrTableViewCmp = (props)=>{
17137
17136
  });
17138
17137
  return;
17139
17138
  }
17139
+ if (f === $8f8e530286a37ce9$var$STRESS_UP || f === $8f8e530286a37ce9$var$STRESS_DOWN) {
17140
+ if (stressDone) return;
17141
+ stressDone = true;
17142
+ cols.push({
17143
+ colId: $8f8e530286a37ce9$var$STRESS_COL,
17144
+ headerName: 'Activated/Repressed by condition',
17145
+ width: 240,
17146
+ sortable: false,
17147
+ valueGetter: ()=>'',
17148
+ cellRenderer: $8f8e530286a37ce9$var$stressRenderer(visibleSet.has($8f8e530286a37ce9$var$STRESS_UP), visibleSet.has($8f8e530286a37ce9$var$STRESS_DOWN))
17149
+ });
17150
+ return;
17151
+ }
17140
17152
  if (f === 'expr_max_tpm__attr_f') {
17141
17153
  cols.push({
17142
17154
  colId: f,
17143
17155
  field: f,
17144
- headerName: headerName,
17145
- width: width,
17156
+ headerName: labelOf(f),
17157
+ width: $8f8e530286a37ce9$var$WIDTHS[f] || 100,
17146
17158
  type: 'numericColumn',
17147
17159
  valueFormatter: (p)=>(0, $4b8473139e48e77e$export$8eaa32ef86afdd9c)(p.value),
17148
17160
  cellStyle: (p)=>({
@@ -17155,43 +17167,153 @@ const $8f8e530286a37ce9$var$AttrTableViewCmp = (props)=>{
17155
17167
  cols.push({
17156
17168
  colId: f,
17157
17169
  field: f,
17158
- headerName: headerName,
17159
- width: width,
17170
+ headerName: labelOf(f),
17171
+ width: $8f8e530286a37ce9$var$WIDTHS[f] || 80,
17160
17172
  type: 'numericColumn',
17161
17173
  valueFormatter: (p)=>Number.isFinite(p.value) ? p.value.toFixed(3) : ''
17162
17174
  });
17163
17175
  return;
17164
17176
  }
17165
- if (f === 'expr_activated_by__attr_ss' || f === 'expr_repressed_by__attr_ss') {
17166
- cols.push({
17167
- colId: f,
17168
- field: f,
17169
- headerName: headerName,
17170
- width: width,
17171
- sortable: false,
17172
- valueFormatter: ()=>'',
17173
- cellRenderer: $8f8e530286a37ce9$var$chipRenderer(f === 'expr_activated_by__attr_ss' ? 'up' : 'down')
17174
- });
17175
- return;
17176
- }
17177
17177
  cols.push({
17178
17178
  colId: f,
17179
17179
  field: f,
17180
- headerName: headerName,
17180
+ headerName: labelOf(f),
17181
17181
  headerTooltip: f,
17182
- width: width,
17182
+ width: $8f8e530286a37ce9$var$WIDTHS[f] || 150,
17183
17183
  pinned: f === 'id' || f === 'name' ? 'left' : undefined,
17184
17184
  valueFormatter: $8f8e530286a37ce9$var$joinValues
17185
17185
  });
17186
17186
  });
17187
17187
  return cols;
17188
+ // eslint-disable-next-line react-hooks/exhaustive-deps
17188
17189
  }, [
17189
- orderedFields,
17190
+ visibleFields,
17190
17191
  visibleSet,
17191
17192
  organs,
17192
17193
  tpmRange,
17193
17194
  fieldCatalogByName
17194
17195
  ]);
17196
+ // Build the click-popover for a cell: a title (the column meaning) and one
17197
+ // filterable item per value. Each item carries the fq_field / fq_value the
17198
+ // "add filter" button hands to doAcceptGrameneSuggestion.
17199
+ const buildCellPopover = (colId, data)=>{
17200
+ if (!data) return null;
17201
+ const mk = (text, fqField, fqValue, category, name)=>({
17202
+ text: text,
17203
+ fqField: fqField,
17204
+ fqValue: fqValue,
17205
+ category: category,
17206
+ name: name || text
17207
+ });
17208
+ if (colId === 'id') return {
17209
+ title: 'Gene ID',
17210
+ items: [
17211
+ mk(data.id, 'id', data.id, 'Gene', data.id)
17212
+ ]
17213
+ };
17214
+ if (colId === $8f8e530286a37ce9$var$STRESS_COL) {
17215
+ const items = [];
17216
+ (data[$8f8e530286a37ce9$var$STRESS_UP] || []).forEach((c)=>items.push(mk("\u2191 " + c, $8f8e530286a37ce9$var$STRESS_UP, c, 'Activated by', 'activated by ' + c)));
17217
+ (data[$8f8e530286a37ce9$var$STRESS_DOWN] || []).forEach((c)=>items.push(mk("\u2193 " + c, $8f8e530286a37ce9$var$STRESS_DOWN, c, 'Repressed by', 'repressed by ' + c)));
17218
+ return {
17219
+ title: 'Activated/Repressed by condition',
17220
+ items: items
17221
+ };
17222
+ }
17223
+ if (colId.startsWith('organ_')) {
17224
+ const organ = colId.slice(6);
17225
+ const lvl = data._organ && data._organ[organ];
17226
+ if (!lvl) return {
17227
+ title: 'Expression level by organ',
17228
+ items: []
17229
+ };
17230
+ const label = `${(0, $4b8473139e48e77e$export$50c1f966fd3af83e)(organ)}: ${(0, $4b8473139e48e77e$export$433053e2c141d410)[lvl] || lvl}`;
17231
+ return {
17232
+ title: 'Expression level by organ',
17233
+ items: [
17234
+ mk(label, $8f8e530286a37ce9$var$ORGAN_FIELD, `${organ}:${lvl}`, 'Expression', label)
17235
+ ]
17236
+ };
17237
+ }
17238
+ if (colId === 'expr_max_tpm__attr_f') {
17239
+ const v = data.expr_max_tpm__attr_f;
17240
+ if (!Number.isFinite(+v)) return {
17241
+ title: labelOf(colId),
17242
+ items: []
17243
+ };
17244
+ return {
17245
+ title: labelOf(colId),
17246
+ items: [
17247
+ mk(`\u{2265} ${(0, $4b8473139e48e77e$export$8eaa32ef86afdd9c)(+v)} TPM`, colId, `[${v} TO *]`, 'Max TPM', `Max TPM \u{2265} ${(0, $4b8473139e48e77e$export$8eaa32ef86afdd9c)(+v)}`)
17248
+ ]
17249
+ };
17250
+ }
17251
+ if (colId === 'expr_tau__attr_f') {
17252
+ const v = data.expr_tau__attr_f;
17253
+ if (!Number.isFinite(+v)) return {
17254
+ title: labelOf(colId),
17255
+ items: []
17256
+ };
17257
+ return {
17258
+ title: labelOf(colId),
17259
+ items: [
17260
+ mk(`\u{2265} ${(+v).toFixed(3)}`, colId, `[${v} TO *]`, 'Tau', `tau \u{2265} ${(+v).toFixed(3)}`)
17261
+ ]
17262
+ };
17263
+ }
17264
+ // Generic (Expression class, and any core / added attribute).
17265
+ const label = labelOf(colId);
17266
+ const raw = data[colId];
17267
+ const vals = Array.isArray(raw) ? raw : raw != null && raw !== '' ? [
17268
+ raw
17269
+ ] : [];
17270
+ return {
17271
+ title: label,
17272
+ items: vals.map((v)=>mk(String(v).replace(/_/g, ' '), colId, v, label, String(v).replace(/_/g, ' ')))
17273
+ };
17274
+ };
17275
+ const onCellClicked = (e)=>{
17276
+ const desc = buildCellPopover(e.column.getColId(), e.data);
17277
+ if (!desc || !desc.items.length) {
17278
+ setPopover(null);
17279
+ return;
17280
+ }
17281
+ const ev = e.event || {};
17282
+ setPopover({
17283
+ x: ev.clientX || 0,
17284
+ y: ev.clientY || 0,
17285
+ title: desc.title,
17286
+ items: desc.items
17287
+ });
17288
+ };
17289
+ const addFilter = (it)=>{
17290
+ doAcceptGrameneSuggestion({
17291
+ fq_field: it.fqField,
17292
+ fq_value: it.fqValue,
17293
+ name: it.name,
17294
+ category: it.category
17295
+ });
17296
+ setPopover(null);
17297
+ };
17298
+ // Close the popover on outside-click or Escape. Registered after the opening
17299
+ // click, so that click can't immediately dismiss it.
17300
+ (0, $gXNCa$react.useEffect)(()=>{
17301
+ if (!popover) return;
17302
+ const onDown = (e)=>{
17303
+ if (popRef.current && !popRef.current.contains(e.target)) setPopover(null);
17304
+ };
17305
+ const onKey = (e)=>{
17306
+ if (e.key === 'Escape') setPopover(null);
17307
+ };
17308
+ document.addEventListener('mousedown', onDown, true);
17309
+ document.addEventListener('keydown', onKey);
17310
+ return ()=>{
17311
+ document.removeEventListener('mousedown', onDown, true);
17312
+ document.removeEventListener('keydown', onKey);
17313
+ };
17314
+ }, [
17315
+ popover
17316
+ ]);
17195
17317
  const shown = rows.length;
17196
17318
  const loading = status === 'loading';
17197
17319
  const organShown = visibleSet.has($8f8e530286a37ce9$var$ORGAN_FIELD);
@@ -17320,13 +17442,43 @@ const $8f8e530286a37ce9$var$AttrTableViewCmp = (props)=>{
17320
17442
  suppressDragLeaveHidesColumns: true,
17321
17443
  tooltipShowDelay: 300,
17322
17444
  rowHeight: 22,
17323
- headerHeight: organShown ? 92 : 28
17445
+ headerHeight: organShown ? 92 : 28,
17446
+ onCellClicked: onCellClicked
17324
17447
  })
17448
+ }),
17449
+ popover && /*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsxs)("div", {
17450
+ ref: popRef,
17451
+ className: "attrtable-popover",
17452
+ style: {
17453
+ left: Math.min(popover.x, window.innerWidth - 280),
17454
+ top: Math.min(popover.y, window.innerHeight - 32 - popover.items.length * 30)
17455
+ },
17456
+ children: [
17457
+ /*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsx)("div", {
17458
+ className: "attrtable-popover-title",
17459
+ children: popover.title
17460
+ }),
17461
+ popover.items.map((it, i)=>/*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsxs)("div", {
17462
+ className: "attrtable-popover-row",
17463
+ children: [
17464
+ /*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsx)("span", {
17465
+ className: "attrtable-popover-val",
17466
+ children: it.text
17467
+ }),
17468
+ /*#__PURE__*/ (0, $gXNCa$reactjsxruntime.jsx)("button", {
17469
+ type: "button",
17470
+ className: "btn btn-sm btn-outline-primary attrtable-popover-btn",
17471
+ onClick: ()=>addFilter(it),
17472
+ children: "add filter"
17473
+ })
17474
+ ]
17475
+ }, i))
17476
+ ]
17325
17477
  })
17326
17478
  ]
17327
17479
  });
17328
17480
  };
17329
- var $8f8e530286a37ce9$export$2e2bcd8739ae039 = (0, $gXNCa$reduxbundlerreact.connect)('selectAttrTable', 'selectFieldCatalog', 'selectFieldCatalogByName', 'doToggleAttrTableField', 'doBulkSetAttrTableFields', 'doResetAttrTableFields', $8f8e530286a37ce9$var$AttrTableViewCmp);
17481
+ var $8f8e530286a37ce9$export$2e2bcd8739ae039 = (0, $gXNCa$reduxbundlerreact.connect)('selectAttrTable', 'selectFieldCatalog', 'selectFieldCatalogByName', 'doToggleAttrTableField', 'doBulkSetAttrTableFields', 'doResetAttrTableFields', 'doAcceptGrameneSuggestion', $8f8e530286a37ce9$var$AttrTableViewCmp);
17330
17482
 
17331
17483
 
17332
17484