@finos/legend-application-marketplace 0.2.11 → 0.2.13

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.
Files changed (43) hide show
  1. package/lib/application/LegendMarketplaceWebApplication.d.ts.map +1 -1
  2. package/lib/application/LegendMarketplaceWebApplication.js +2 -2
  3. package/lib/application/LegendMarketplaceWebApplication.js.map +1 -1
  4. package/lib/components/MarketplaceCard/FieldSearchResultListItem.d.ts +1 -0
  5. package/lib/components/MarketplaceCard/FieldSearchResultListItem.d.ts.map +1 -1
  6. package/lib/components/MarketplaceCard/FieldSearchResultListItem.js +30 -12
  7. package/lib/components/MarketplaceCard/FieldSearchResultListItem.js.map +1 -1
  8. package/lib/index.css +2 -2
  9. package/lib/index.css.map +1 -1
  10. package/lib/package.json +1 -1
  11. package/lib/pages/Lakehouse/entitlements/EntitlementsClosedContractsDashboard.d.ts.map +1 -1
  12. package/lib/pages/Lakehouse/entitlements/EntitlementsClosedContractsDashboard.js +16 -2
  13. package/lib/pages/Lakehouse/entitlements/EntitlementsClosedContractsDashboard.js.map +1 -1
  14. package/lib/pages/Lakehouse/entitlements/EntitlementsPendingContractsDashboard.d.ts.map +1 -1
  15. package/lib/pages/Lakehouse/entitlements/EntitlementsPendingContractsDashboard.js +19 -3
  16. package/lib/pages/Lakehouse/entitlements/EntitlementsPendingContractsDashboard.js.map +1 -1
  17. package/lib/pages/Lakehouse/entitlements/EntitlementsPendingTasksDashboard.d.ts.map +1 -1
  18. package/lib/pages/Lakehouse/entitlements/EntitlementsPendingTasksDashboard.js +23 -4
  19. package/lib/pages/Lakehouse/entitlements/EntitlementsPendingTasksDashboard.js.map +1 -1
  20. package/lib/pages/Lakehouse/searchResults/LegendMarketplaceFieldSearchResults.d.ts.map +1 -1
  21. package/lib/pages/Lakehouse/searchResults/LegendMarketplaceFieldSearchResults.js +29 -23
  22. package/lib/pages/Lakehouse/searchResults/LegendMarketplaceFieldSearchResults.js.map +1 -1
  23. package/lib/pages/Lakehouse/searchResults/LegendMarketplaceSearchResults.d.ts.map +1 -1
  24. package/lib/pages/Lakehouse/searchResults/LegendMarketplaceSearchResults.js +8 -1
  25. package/lib/pages/Lakehouse/searchResults/LegendMarketplaceSearchResults.js.map +1 -1
  26. package/lib/stores/lakehouse/entitlements/EntitlementsDashboardState.d.ts +1 -0
  27. package/lib/stores/lakehouse/entitlements/EntitlementsDashboardState.d.ts.map +1 -1
  28. package/lib/stores/lakehouse/entitlements/EntitlementsDashboardState.js +175 -14
  29. package/lib/stores/lakehouse/entitlements/EntitlementsDashboardState.js.map +1 -1
  30. package/lib/stores/lakehouse/fieldSearch/FieldSearchResultState.d.ts +4 -0
  31. package/lib/stores/lakehouse/fieldSearch/FieldSearchResultState.d.ts.map +1 -1
  32. package/lib/stores/lakehouse/fieldSearch/FieldSearchResultState.js +44 -7
  33. package/lib/stores/lakehouse/fieldSearch/FieldSearchResultState.js.map +1 -1
  34. package/package.json +9 -9
  35. package/src/application/LegendMarketplaceWebApplication.tsx +11 -6
  36. package/src/components/MarketplaceCard/FieldSearchResultListItem.tsx +110 -32
  37. package/src/pages/Lakehouse/entitlements/EntitlementsClosedContractsDashboard.tsx +25 -3
  38. package/src/pages/Lakehouse/entitlements/EntitlementsPendingContractsDashboard.tsx +34 -5
  39. package/src/pages/Lakehouse/entitlements/EntitlementsPendingTasksDashboard.tsx +51 -6
  40. package/src/pages/Lakehouse/searchResults/LegendMarketplaceFieldSearchResults.tsx +100 -25
  41. package/src/pages/Lakehouse/searchResults/LegendMarketplaceSearchResults.tsx +37 -0
  42. package/src/stores/lakehouse/entitlements/EntitlementsDashboardState.ts +276 -36
  43. package/src/stores/lakehouse/fieldSearch/FieldSearchResultState.ts +53 -4
@@ -14,15 +14,39 @@
14
14
  * limitations under the License.
15
15
  */
16
16
  import { DataProductSearchResultDetailsType, } from '@finos/legend-server-marketplace';
17
+ import { hashArray } from '@finos/legend-shared';
17
18
  import { DataProductTypeFilter } from '../LegendMarketplaceSearchResultsStore.js';
18
19
  import { generateGAVCoordinates } from '@finos/legend-storage';
19
20
  import { generateLakehouseDataProductPath, generateLegacyDataProductPath, } from '../../../__lib__/LegendMarketplaceNavigation.js';
21
+ var FieldSearchResultStateDefaultValue;
22
+ (function (FieldSearchResultStateDefaultValue) {
23
+ FieldSearchResultStateDefaultValue["UNKNOWN_FIELD_TYPE"] = "Unknown";
24
+ FieldSearchResultStateDefaultValue["EMPTY_FIELD_DESCRIPTION"] = "-";
25
+ })(FieldSearchResultStateDefaultValue || (FieldSearchResultStateDefaultValue = {}));
26
+ var FieldSearchDataProductKey;
27
+ (function (FieldSearchDataProductKey) {
28
+ FieldSearchDataProductKey["DISTINCT_SEPARATOR"] = "|";
29
+ })(FieldSearchDataProductKey || (FieldSearchDataProductKey = {}));
20
30
  const PRODUCT_TYPE_FILTER_MAP = {
21
31
  [DataProductSearchResultDetailsType.LEGACY]: DataProductTypeFilter.LEGACY,
22
32
  [DataProductSearchResultDetailsType.LAKEHOUSE]: DataProductTypeFilter.LAKEHOUSE,
23
33
  [DataProductSearchResultDetailsType.ERROR]: DataProductTypeFilter.LEGACY,
24
34
  };
25
35
  const getDataProductName = (path) => path.split('::').at(-1) ?? path;
36
+ const generateFieldSearchResultId = (fieldName, fieldType, fieldDescription) => `${hashArray([fieldName, fieldType, fieldDescription])}`;
37
+ const getDistinctDataProducts = (dataProducts) => {
38
+ const seen = new Set();
39
+ return dataProducts.filter((dp) => {
40
+ // Dedupe primarily by owning data product path. Fallback to a stable
41
+ // composite key only when path is unavailable.
42
+ const dedupeKey = dp.path || dp.distinctKey;
43
+ if (seen.has(dedupeKey)) {
44
+ return false;
45
+ }
46
+ seen.add(dedupeKey);
47
+ return true;
48
+ });
49
+ };
26
50
  const getOwningDataProductPath = (dataProduct) => {
27
51
  if (dataProduct.productType === DataProductSearchResultDetailsType.LEGACY &&
28
52
  dataProduct.groupId) {
@@ -38,6 +62,8 @@ const getOwningDataProductPath = (dataProduct) => {
38
62
  export class FieldSearchDataProductEntry {
39
63
  name;
40
64
  datasetName;
65
+ datasetDescription;
66
+ executionContextKey;
41
67
  modelPath;
42
68
  path;
43
69
  entityPath;
@@ -47,11 +73,14 @@ export class FieldSearchDataProductEntry {
47
73
  artifactId;
48
74
  versionId;
49
75
  productType;
76
+ distinctKey;
50
77
  constructor(dataProduct) {
51
78
  const productType = PRODUCT_TYPE_FILTER_MAP[dataProduct.productType];
52
79
  const dataProductName = getDataProductName(dataProduct.path);
53
80
  this.name = dataProductName;
54
81
  this.datasetName = dataProduct.datasetName;
82
+ this.datasetDescription = dataProduct.datasetDescription;
83
+ this.executionContextKey = dataProduct.defaultExecutionContext;
55
84
  this.modelPath = dataProduct.modelPath;
56
85
  this.path = getOwningDataProductPath(dataProduct);
57
86
  this.entityPath = dataProduct.path;
@@ -61,6 +90,12 @@ export class FieldSearchDataProductEntry {
61
90
  this.artifactId = dataProduct.artifactId;
62
91
  this.versionId = dataProduct.versionId;
63
92
  this.productType = productType;
93
+ this.distinctKey = [
94
+ this.path,
95
+ this.entityPath,
96
+ this.dataProductId,
97
+ this.name,
98
+ ].join(FieldSearchDataProductKey.DISTINCT_SEPARATOR);
64
99
  }
65
100
  }
66
101
  export class FieldSearchResultState {
@@ -69,16 +104,18 @@ export class FieldSearchResultState {
69
104
  fieldType;
70
105
  fieldDescription;
71
106
  dataProducts;
107
+ distinctDataProducts;
72
108
  constructor(result) {
73
109
  this.fieldName = result.fieldName;
74
- this.fieldType = result.fieldType ?? 'Unknown';
75
- this.fieldDescription = result.fieldDescription ?? '-';
76
- this.id = JSON.stringify([
77
- this.fieldName,
78
- this.fieldType,
79
- this.fieldDescription,
80
- ]);
110
+ this.fieldType =
111
+ result.fieldType ?? FieldSearchResultStateDefaultValue.UNKNOWN_FIELD_TYPE;
112
+ this.fieldDescription =
113
+ result.fieldDescription ??
114
+ FieldSearchResultStateDefaultValue.EMPTY_FIELD_DESCRIPTION;
115
+ this.id = generateFieldSearchResultId(this.fieldName, this.fieldType, this.fieldDescription);
81
116
  this.dataProducts = result.dataProducts.map((dp) => new FieldSearchDataProductEntry(dp));
117
+ // Precompute once since dataProducts are immutable after construction.
118
+ this.distinctDataProducts = getDistinctDataProducts(this.dataProducts);
82
119
  }
83
120
  }
84
121
  //# sourceMappingURL=FieldSearchResultState.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"FieldSearchResultState.js","sourceRoot":"","sources":["../../../../src/stores/lakehouse/fieldSearch/FieldSearchResultState.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"FieldSearchResultState.js","sourceRoot":"","sources":["../../../../src/stores/lakehouse/fieldSearch/FieldSearchResultState.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EACL,kCAAkC,GAGnC,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,qBAAqB,EAAE,MAAM,2CAA2C,CAAC;AAClF,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EACL,gCAAgC,EAChC,6BAA6B,GAC9B,MAAM,iDAAiD,CAAC;AAEzD,IAAK,kCAGJ;AAHD,WAAK,kCAAkC;IACrC,oEAA8B,CAAA;IAC9B,mEAA6B,CAAA;AAC/B,CAAC,EAHI,kCAAkC,KAAlC,kCAAkC,QAGtC;AAED,IAAK,yBAEJ;AAFD,WAAK,yBAAyB;IAC5B,qDAAwB,CAAA;AAC1B,CAAC,EAFI,yBAAyB,KAAzB,yBAAyB,QAE7B;AAED,MAAM,uBAAuB,GAGzB;IACF,CAAC,kCAAkC,CAAC,MAAM,CAAC,EAAE,qBAAqB,CAAC,MAAM;IACzE,CAAC,kCAAkC,CAAC,SAAS,CAAC,EAC5C,qBAAqB,CAAC,SAAS;IACjC,CAAC,kCAAkC,CAAC,KAAK,CAAC,EAAE,qBAAqB,CAAC,MAAM;CACzE,CAAC;AAEF,MAAM,kBAAkB,GAAG,CAAC,IAAY,EAAU,EAAE,CAClD,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;AAElC,MAAM,2BAA2B,GAAG,CAClC,SAAiB,EACjB,SAAiB,EACjB,gBAAwB,EAChB,EAAE,CAAC,GAAG,SAAS,CAAC,CAAC,SAAS,EAAE,SAAS,EAAE,gBAAgB,CAAC,CAAC,EAAE,CAAC;AAEtE,MAAM,uBAAuB,GAAG,CAC9B,YAA2C,EACZ,EAAE;IACjC,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,OAAO,YAAY,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE;QAChC,qEAAqE;QACrE,+CAA+C;QAC/C,MAAM,SAAS,GAAG,EAAE,CAAC,IAAI,IAAI,EAAE,CAAC,WAAW,CAAC;QAC5C,IAAI,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;YACxB,OAAO,KAAK,CAAC;QACf,CAAC;QACD,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACpB,OAAO,IAAI,CAAC;IACd,CAAC,CAAC,CAAC;AACL,CAAC,CAAC;AAEF,MAAM,wBAAwB,GAAG,CAC/B,WAA0C,EAClC,EAAE;IACV,IACE,WAAW,CAAC,WAAW,KAAK,kCAAkC,CAAC,MAAM;QACrE,WAAW,CAAC,OAAO,EACnB,CAAC;QACD,OAAO,6BAA6B,CAClC,sBAAsB,CACpB,WAAW,CAAC,OAAO,EACnB,WAAW,CAAC,UAAU,IAAI,EAAE,EAC5B,WAAW,CAAC,SAAS,IAAI,EAAE,CAC5B,EACD,WAAW,CAAC,IAAI,CACjB,CAAC;IACJ,CAAC;IACD,IACE,WAAW,CAAC,WAAW,KAAK,kCAAkC,CAAC,SAAS;QACxE,WAAW,CAAC,aAAa;QACzB,WAAW,CAAC,YAAY,KAAK,SAAS,EACtC,CAAC;QACD,OAAO,gCAAgC,CACrC,WAAW,CAAC,aAAa,EACzB,WAAW,CAAC,YAAY,CACzB,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC,CAAC;AAEF,MAAM,OAAO,2BAA2B;IAC7B,IAAI,CAAS;IACb,WAAW,CAAqB;IAChC,kBAAkB,CAAqB;IACvC,mBAAmB,CAAqB;IACxC,SAAS,CAAqB;IAC9B,IAAI,CAAS;IACb,UAAU,CAAS;IACnB,aAAa,CAAqB;IAClC,YAAY,CAAqB;IACjC,OAAO,CAAqB;IAC5B,UAAU,CAAqB;IAC/B,SAAS,CAAqB;IAC9B,WAAW,CAAoC;IAC/C,WAAW,CAAS;IAE7B,YAAY,WAA0C;QACpD,MAAM,WAAW,GAAG,uBAAuB,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC;QACrE,MAAM,eAAe,GAAG,kBAAkB,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QAE7D,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;QAC5B,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC,WAAW,CAAC;QAC3C,IAAI,CAAC,kBAAkB,GAAG,WAAW,CAAC,kBAAkB,CAAC;QACzD,IAAI,CAAC,mBAAmB,GAAG,WAAW,CAAC,uBAAuB,CAAC;QAC/D,IAAI,CAAC,SAAS,GAAG,WAAW,CAAC,SAAS,CAAC;QACvC,IAAI,CAAC,IAAI,GAAG,wBAAwB,CAAC,WAAW,CAAC,CAAC;QAClD,IAAI,CAAC,UAAU,GAAG,WAAW,CAAC,IAAI,CAAC;QACnC,IAAI,CAAC,aAAa,GAAG,WAAW,CAAC,aAAa,IAAI,eAAe,CAAC;QAClE,IAAI,CAAC,YAAY,GAAG,WAAW,CAAC,YAAY,CAAC;QAC7C,IAAI,CAAC,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC;QACnC,IAAI,CAAC,UAAU,GAAG,WAAW,CAAC,UAAU,CAAC;QACzC,IAAI,CAAC,SAAS,GAAG,WAAW,CAAC,SAAS,CAAC;QACvC,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;QAC/B,IAAI,CAAC,WAAW,GAAG;YACjB,IAAI,CAAC,IAAI;YACT,IAAI,CAAC,UAAU;YACf,IAAI,CAAC,aAAa;YAClB,IAAI,CAAC,IAAI;SACV,CAAC,IAAI,CAAC,yBAAyB,CAAC,kBAAkB,CAAC,CAAC;IACvD,CAAC;CACF;AAED,MAAM,OAAO,sBAAsB;IACxB,EAAE,CAAS;IACX,SAAS,CAAS;IAClB,SAAS,CAAS;IAClB,gBAAgB,CAAS;IACzB,YAAY,CAAgC;IAC5C,oBAAoB,CAAgC;IAE7D,YAAY,MAAqC;QAC/C,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC,SAAS,CAAC;QAClC,IAAI,CAAC,SAAS;YACZ,MAAM,CAAC,SAAS,IAAI,kCAAkC,CAAC,kBAAkB,CAAC;QAC5E,IAAI,CAAC,gBAAgB;YACnB,MAAM,CAAC,gBAAgB;gBACvB,kCAAkC,CAAC,uBAAuB,CAAC;QAC7D,IAAI,CAAC,EAAE,GAAG,2BAA2B,CACnC,IAAI,CAAC,SAAS,EACd,IAAI,CAAC,SAAS,EACd,IAAI,CAAC,gBAAgB,CACtB,CAAC;QACF,IAAI,CAAC,YAAY,GAAG,MAAM,CAAC,YAAY,CAAC,GAAG,CACzC,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,2BAA2B,CAAC,EAAE,CAAC,CAC5C,CAAC;QACF,uEAAuE;QACvE,IAAI,CAAC,oBAAoB,GAAG,uBAAuB,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IACzE,CAAC;CACF"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@finos/legend-application-marketplace",
3
- "version": "0.2.11",
3
+ "version": "0.2.13",
4
4
  "description": "Legend Marketplace application core",
5
5
  "keywords": [
6
6
  "legend",
@@ -45,16 +45,16 @@
45
45
  "test:watch": "jest --watch"
46
46
  },
47
47
  "dependencies": {
48
- "@finos/legend-application": "16.0.106",
48
+ "@finos/legend-application": "16.0.107",
49
49
  "@finos/legend-art": "7.1.148",
50
- "@finos/legend-code-editor": "2.0.171",
51
- "@finos/legend-extension-dsl-data-product": "0.0.80",
52
- "@finos/legend-extension-dsl-data-space": "10.4.219",
53
- "@finos/legend-graph": "32.6.3",
54
- "@finos/legend-lego": "2.0.191",
50
+ "@finos/legend-code-editor": "2.0.172",
51
+ "@finos/legend-extension-dsl-data-product": "0.0.82",
52
+ "@finos/legend-extension-dsl-data-space": "10.4.221",
53
+ "@finos/legend-graph": "32.6.4",
54
+ "@finos/legend-lego": "2.0.192",
55
55
  "@finos/legend-server-depot": "6.1.12",
56
- "@finos/legend-server-lakehouse": "0.3.52",
57
- "@finos/legend-server-marketplace": "0.1.66",
56
+ "@finos/legend-server-lakehouse": "0.3.53",
57
+ "@finos/legend-server-marketplace": "0.1.68",
58
58
  "@finos/legend-shared": "11.0.25",
59
59
  "@finos/legend-storage": "3.0.146",
60
60
  "@mui/material": "7.3.4",
@@ -21,7 +21,10 @@ import {
21
21
  CubesLoadingIndicatorIcon,
22
22
  GhostIcon,
23
23
  } from '@finos/legend-art';
24
- import { useApplicationStore } from '@finos/legend-application';
24
+ import {
25
+ useApplicationStore,
26
+ LegendTokenSync,
27
+ } from '@finos/legend-application';
25
28
  import {
26
29
  BrowserEnvironmentProvider,
27
30
  Outlet,
@@ -463,11 +466,13 @@ export const LegendMarketplaceWebApplication = observer(
463
466
 
464
467
  return (
465
468
  <AuthProvider {...mergedOIDCConfig}>
466
- <BrowserEnvironmentProvider baseUrl={baseUrl}>
467
- <LegendMarketplaceFrameworkProvider>
468
- <LegendMarketplaceWebApplicationRouter />
469
- </LegendMarketplaceFrameworkProvider>
470
- </BrowserEnvironmentProvider>
469
+ <LegendTokenSync>
470
+ <BrowserEnvironmentProvider baseUrl={baseUrl}>
471
+ <LegendMarketplaceFrameworkProvider>
472
+ <LegendMarketplaceWebApplicationRouter />
473
+ </LegendMarketplaceFrameworkProvider>
474
+ </BrowserEnvironmentProvider>
475
+ </LegendTokenSync>
471
476
  </AuthProvider>
472
477
  );
473
478
  },
@@ -16,7 +16,7 @@
16
16
 
17
17
  import { observer } from 'mobx-react-lite';
18
18
  import { useState } from 'react';
19
- import { Chip, Typography } from '@mui/material';
19
+ import { Chip, Tooltip, Typography } from '@mui/material';
20
20
  import { DatasetIcon, PackageIcon } from '@finos/legend-art';
21
21
  import type {
22
22
  FieldSearchDataProductEntry,
@@ -26,6 +26,8 @@ import { LegendMarketplaceListItem } from '../MarketplaceCard/LegendMarketplaceL
26
26
 
27
27
  enum FieldSearchResultListItemLabel {
28
28
  SHOW_LESS = 'Show Less',
29
+ SHOW_LESS_INLINE = 'Show less',
30
+ SHOW_MORE_INLINE = 'Show more',
29
31
  MORE_SUFFIX = 'More',
30
32
  DATASET_SEPARATOR = '|',
31
33
  EMPTY_VALUE = '-',
@@ -36,21 +38,52 @@ enum FieldSearchResultListItemValue {
36
38
  MAX_DESCRIPTION_LENGTH = 150,
37
39
  }
38
40
 
41
+ function getCollapsibleListState<T>(
42
+ items: T[],
43
+ expanded: boolean,
44
+ ): { visibleItems: T[]; toggleLabel: string; shouldShowToggle: boolean } {
45
+ const visibleItems = expanded
46
+ ? items
47
+ : items.slice(
48
+ 0,
49
+ FieldSearchResultListItemValue.COLLAPSED_VISIBLE_DATA_PRODUCTS,
50
+ );
51
+ const hiddenItemCount = Math.max(
52
+ 0,
53
+ items.length -
54
+ FieldSearchResultListItemValue.COLLAPSED_VISIBLE_DATA_PRODUCTS,
55
+ );
56
+ const toggleLabel = expanded
57
+ ? FieldSearchResultListItemLabel.SHOW_LESS
58
+ : `+${hiddenItemCount} ${FieldSearchResultListItemLabel.MORE_SUFFIX}`;
59
+
60
+ return {
61
+ visibleItems,
62
+ toggleLabel,
63
+ shouldShowToggle:
64
+ items.length >
65
+ FieldSearchResultListItemValue.COLLAPSED_VISIBLE_DATA_PRODUCTS,
66
+ };
67
+ }
68
+
39
69
  export const FieldSearchResultListRow = observer(
40
70
  (props: {
41
71
  fieldSearchResultState: FieldSearchResultState;
42
72
  expanded: boolean;
43
73
  onToggleExpanded: (rowId: string) => void;
44
74
  onOpenDataProduct: (dataProduct: FieldSearchDataProductEntry) => void;
75
+ onOpenDatasetInQuery: (dataProduct: FieldSearchDataProductEntry) => void;
45
76
  }): React.ReactNode => {
46
77
  const {
47
78
  fieldSearchResultState,
48
79
  expanded,
49
80
  onToggleExpanded,
50
81
  onOpenDataProduct,
82
+ onOpenDatasetInQuery,
51
83
  } = props;
52
84
 
53
85
  const [descriptionExpanded, setDescriptionExpanded] = useState(false);
86
+ const [dpExpanded, setDpExpanded] = useState(false);
54
87
  const description = fieldSearchResultState.fieldDescription;
55
88
  const isDescriptionTruncatable =
56
89
  description.length >
@@ -60,20 +93,19 @@ export const FieldSearchResultListRow = observer(
60
93
  ? `${description.substring(0, FieldSearchResultListItemValue.MAX_DESCRIPTION_LENGTH)}...`
61
94
  : description;
62
95
 
63
- const visibleDataProducts = expanded
64
- ? fieldSearchResultState.dataProducts
65
- : fieldSearchResultState.dataProducts.slice(
66
- 0,
67
- FieldSearchResultListItemValue.COLLAPSED_VISIBLE_DATA_PRODUCTS,
68
- );
69
- const hiddenDataProductCount = Math.max(
70
- 0,
71
- fieldSearchResultState.dataProducts.length -
72
- FieldSearchResultListItemValue.COLLAPSED_VISIBLE_DATA_PRODUCTS,
73
- );
74
- const toggleLabel = expanded
75
- ? FieldSearchResultListItemLabel.SHOW_LESS
76
- : `+${hiddenDataProductCount} ${FieldSearchResultListItemLabel.MORE_SUFFIX}`;
96
+ const distinctDataProducts = fieldSearchResultState.distinctDataProducts;
97
+
98
+ const {
99
+ visibleItems: visibleDataProducts,
100
+ toggleLabel,
101
+ shouldShowToggle: shouldShowDataProductToggle,
102
+ } = getCollapsibleListState(fieldSearchResultState.dataProducts, expanded);
103
+
104
+ const {
105
+ visibleItems: visibleDistinctDataProducts,
106
+ toggleLabel: dpToggleLabel,
107
+ shouldShowToggle: shouldShowDistinctDataProductToggle,
108
+ } = getCollapsibleListState(distinctDataProducts, dpExpanded);
77
109
 
78
110
  const content = (
79
111
  <div className="marketplace-lakehouse-field-search-results__list-item-grid">
@@ -99,32 +131,23 @@ export const FieldSearchResultListRow = observer(
99
131
  setDescriptionExpanded(!descriptionExpanded);
100
132
  }}
101
133
  >
102
- {descriptionExpanded ? 'Show less' : 'Show more'}
134
+ {descriptionExpanded
135
+ ? FieldSearchResultListItemLabel.SHOW_LESS_INLINE
136
+ : FieldSearchResultListItemLabel.SHOW_MORE_INLINE}
103
137
  </button>
104
138
  )}
105
139
  </div>
106
140
  <div className="marketplace-lakehouse-field-search-results__data-products-cell">
107
- {fieldSearchResultState.dataProducts.length > 0 ? (
141
+ {distinctDataProducts.length > 0 ? (
108
142
  <>
109
- {visibleDataProducts.map((dataProduct) => (
143
+ {visibleDistinctDataProducts.map((dataProduct) => (
110
144
  <Chip
111
- key={`${fieldSearchResultState.id}-${dataProduct.path}-${dataProduct.datasetName ?? ''}`}
145
+ key={`${fieldSearchResultState.id}-dp-${dataProduct.distinctKey}`}
112
146
  clickable={true}
113
147
  label={
114
148
  <span className="marketplace-lakehouse-field-search-results__chip-label">
115
149
  <PackageIcon className="marketplace-lakehouse-field-search-results__chip-icon" />
116
150
  <span>{dataProduct.name}</span>
117
- {dataProduct.datasetName && (
118
- <span className="marketplace-lakehouse-field-search-results__chip-secondary">
119
- <span className="marketplace-lakehouse-field-search-results__chip-separator">
120
- {FieldSearchResultListItemLabel.DATASET_SEPARATOR}
121
- </span>
122
- <DatasetIcon className="marketplace-lakehouse-field-search-results__chip-icon" />
123
- <span className="marketplace-lakehouse-field-search-results__chip-secondary-text">
124
- {dataProduct.datasetName}
125
- </span>
126
- </span>
127
- )}
128
151
  </span>
129
152
  }
130
153
  onClick={() => onOpenDataProduct(dataProduct)}
@@ -132,8 +155,63 @@ export const FieldSearchResultListRow = observer(
132
155
  size="small"
133
156
  />
134
157
  ))}
135
- {fieldSearchResultState.dataProducts.length >
136
- FieldSearchResultListItemValue.COLLAPSED_VISIBLE_DATA_PRODUCTS && (
158
+ {shouldShowDistinctDataProductToggle && (
159
+ <Chip
160
+ key={`${fieldSearchResultState.id}-dp-toggle`}
161
+ label={dpToggleLabel}
162
+ onClick={(e) => {
163
+ e.stopPropagation();
164
+ setDpExpanded(!dpExpanded);
165
+ }}
166
+ size="small"
167
+ variant="outlined"
168
+ className="marketplace-lakehouse-field-search-results__data-product-toggle"
169
+ />
170
+ )}
171
+ </>
172
+ ) : (
173
+ <Typography className="marketplace-lakehouse-field-search-results__list-item-text marketplace-lakehouse-field-search-results__list-item-text--empty">
174
+ {FieldSearchResultListItemLabel.EMPTY_VALUE}
175
+ </Typography>
176
+ )}
177
+ </div>
178
+ <div className="marketplace-lakehouse-field-search-results__data-products-cell">
179
+ {fieldSearchResultState.dataProducts.length > 0 ? (
180
+ <>
181
+ {visibleDataProducts.map((dataProduct) => (
182
+ <Tooltip
183
+ key={`${fieldSearchResultState.id}-${dataProduct.path}-${dataProduct.datasetName ?? ''}`}
184
+ title={dataProduct.datasetDescription ?? ''}
185
+ placement="top"
186
+ arrow={true}
187
+ disableHoverListener={!dataProduct.datasetDescription}
188
+ >
189
+ <Chip
190
+ clickable={true}
191
+ label={
192
+ <span className="marketplace-lakehouse-field-search-results__chip-label">
193
+ <PackageIcon className="marketplace-lakehouse-field-search-results__chip-icon" />
194
+ <span>{dataProduct.name}</span>
195
+ {dataProduct.datasetName && (
196
+ <span className="marketplace-lakehouse-field-search-results__chip-secondary">
197
+ <span className="marketplace-lakehouse-field-search-results__chip-separator">
198
+ {FieldSearchResultListItemLabel.DATASET_SEPARATOR}
199
+ </span>
200
+ <DatasetIcon className="marketplace-lakehouse-field-search-results__chip-icon" />
201
+ <span className="marketplace-lakehouse-field-search-results__chip-secondary-text">
202
+ {dataProduct.datasetName}
203
+ </span>
204
+ </span>
205
+ )}
206
+ </span>
207
+ }
208
+ onClick={() => onOpenDatasetInQuery(dataProduct)}
209
+ className="marketplace-lakehouse-field-search-results__data-product-link"
210
+ size="small"
211
+ />
212
+ </Tooltip>
213
+ ))}
214
+ {shouldShowDataProductToggle && (
137
215
  <Chip
138
216
  key={`${fieldSearchResultState.id}-toggle`}
139
217
  label={toggleLabel}
@@ -84,6 +84,10 @@ export const EntitlementsClosedContractsDashboard = observer(
84
84
  const [selectedContract, setSelectedContract] = useState<
85
85
  V1_LiteDataContract | undefined
86
86
  >();
87
+ const [unverifiedIngestDefinitions, setUnverifiedIngestDefinitions] =
88
+ useState<string[] | undefined>(undefined);
89
+ const [ingestVerificationInProgress, setIngestVerificationInProgress] =
90
+ useState(false);
87
91
  const [showForOthers, setShowForOthers] = useState<boolean>(
88
92
  myClosedContracts.length === 0 && closedContractsForOthers.length > 0,
89
93
  );
@@ -93,7 +97,20 @@ export const EntitlementsClosedContractsDashboard = observer(
93
97
  V1_LiteDataContractWithUserStatus | ContractCreatedByUserDetails
94
98
  >,
95
99
  ) => {
96
- setSelectedContract(event.data?.contractResultLite);
100
+ const contract = event.data?.contractResultLite;
101
+ setSelectedContract(contract);
102
+ setUnverifiedIngestDefinitions(undefined);
103
+ if (contract !== undefined) {
104
+ setIngestVerificationInProgress(true);
105
+ const result = await flowResult(
106
+ dashboardState.getUnverifiedIngestDefinitions(
107
+ contract.guid,
108
+ auth.user?.access_token,
109
+ ),
110
+ );
111
+ setUnverifiedIngestDefinitions(result);
112
+ setIngestVerificationInProgress(false);
113
+ }
97
114
  };
98
115
 
99
116
  const defaultColDef: DataGridColumnDefinition<
@@ -210,10 +227,15 @@ export const EntitlementsClosedContractsDashboard = observer(
210
227
  overlayLoadingTemplate="Loading contracts"
211
228
  />
212
229
  </Box>
213
- {selectedContract !== undefined && (
230
+ {selectedContract !== undefined && !ingestVerificationInProgress && (
214
231
  <DataAccessRequestViewer
215
232
  open={true}
216
- onClose={() => setSelectedContract(undefined)}
233
+ onClose={() => {
234
+ setSelectedContract(undefined);
235
+ setUnverifiedIngestDefinitions(undefined);
236
+ setIngestVerificationInProgress(false);
237
+ }}
238
+ unverifiedIngestDefinitions={unverifiedIngestDefinitions}
217
239
  viewerState={
218
240
  new DataContractViewerState(
219
241
  selectedContract,
@@ -115,16 +115,33 @@ export const EntitlementsPendingContractsDashboard = observer(
115
115
  const [selectedContract, setSelectedContract] = useState<
116
116
  V1_LiteDataContract | undefined
117
117
  >();
118
+ const [unverifiedIngestDefinitions, setUnverifiedIngestDefinitions] =
119
+ useState<string[] | undefined>(undefined);
120
+ const [ingestVerificationInProgress, setIngestVerificationInProgress] =
121
+ useState(false);
118
122
  const [showForOthers, setShowForOthers] = useState<boolean>(
119
123
  myPendingContracts.length === 0 && pendingContractsForOthers.length > 0,
120
124
  );
121
125
 
122
- const handleCellClicked = (
126
+ const handleCellClicked = async (
123
127
  event: DataGridCellClickedEvent<
124
128
  V1_LiteDataContractWithUserStatus | ContractCreatedByUserDetails
125
129
  >,
126
130
  ) => {
127
- setSelectedContract(event.data?.contractResultLite);
131
+ const contract = event.data?.contractResultLite;
132
+ setSelectedContract(contract);
133
+ setUnverifiedIngestDefinitions(undefined);
134
+ if (contract !== undefined) {
135
+ setIngestVerificationInProgress(true);
136
+ const result = await flowResult(
137
+ dashboardState.getUnverifiedIngestDefinitions(
138
+ contract.guid,
139
+ auth.user?.access_token,
140
+ ),
141
+ );
142
+ setUnverifiedIngestDefinitions(result);
143
+ setIngestVerificationInProgress(false);
144
+ }
128
145
  };
129
146
 
130
147
  const defaultColDef: DataGridColumnDefinition<
@@ -235,7 +252,14 @@ export const EntitlementsPendingContractsDashboard = observer(
235
252
  suppressFieldDotNotation={true}
236
253
  suppressContextMenu={false}
237
254
  columnDefs={colDefs}
238
- onCellClicked={handleCellClicked}
255
+ onCellClicked={(
256
+ event: DataGridCellClickedEvent<
257
+ V1_LiteDataContractWithUserStatus | ContractCreatedByUserDetails
258
+ >,
259
+ ) =>
260
+ // eslint-disable-next-line no-void
261
+ void handleCellClicked(event)
262
+ }
239
263
  defaultColDef={defaultColDef}
240
264
  rowHeight={45}
241
265
  overlayNoRowsTemplate="You have no pending contracts"
@@ -243,10 +267,15 @@ export const EntitlementsPendingContractsDashboard = observer(
243
267
  overlayLoadingTemplate="Loading contracts"
244
268
  />
245
269
  </Box>
246
- {selectedContract !== undefined && (
270
+ {selectedContract !== undefined && !ingestVerificationInProgress && (
247
271
  <DataAccessRequestViewer
248
272
  open={true}
249
- onClose={() => setSelectedContract(undefined)}
273
+ onClose={() => {
274
+ setSelectedContract(undefined);
275
+ setUnverifiedIngestDefinitions(undefined);
276
+ setIngestVerificationInProgress(false);
277
+ }}
278
+ unverifiedIngestDefinitions={unverifiedIngestDefinitions}
250
279
  viewerState={
251
280
  new DataContractViewerState(
252
281
  selectedContract,
@@ -289,6 +289,10 @@ export const EntitlementsPendingTasksDashboard = observer(
289
289
  >();
290
290
  const [selectedContractTargetUser, setSelectedContractTargetUser] =
291
291
  useState<string | undefined>();
292
+ const [unverifiedIngestDefinitions, setUnverifiedIngestDefinitions] =
293
+ useState<string[] | undefined>(undefined);
294
+ const [ingestVerificationInProgress, setIngestVerificationInProgress] =
295
+ useState(false);
292
296
 
293
297
  const auth = useAuth();
294
298
 
@@ -309,7 +313,7 @@ export const EntitlementsPendingTasksDashboard = observer(
309
313
  event.api.setNodesSelected({ nodes: nodesToSelect, newValue: true });
310
314
  };
311
315
 
312
- const handleCellClicked = (
316
+ const handleCellClicked = async (
313
317
  event: DataGridCellClickedEvent<V1_ContractUserEventRecord, unknown>,
314
318
  ) => {
315
319
  if (event.colDef.colId !== 'selection') {
@@ -318,6 +322,18 @@ export const EntitlementsPendingTasksDashboard = observer(
318
322
  );
319
323
  setSelectedContract(contract);
320
324
  setSelectedContractTargetUser(event.data?.consumer);
325
+ setUnverifiedIngestDefinitions(undefined);
326
+ if (contract !== undefined) {
327
+ setIngestVerificationInProgress(true);
328
+ const result = await flowResult(
329
+ dashboardState.getUnverifiedIngestDefinitions(
330
+ contract.guid,
331
+ auth.user?.access_token,
332
+ ),
333
+ );
334
+ setUnverifiedIngestDefinitions(result);
335
+ setIngestVerificationInProgress(false);
336
+ }
321
337
  }
322
338
  };
323
339
 
@@ -737,7 +753,15 @@ export const EntitlementsPendingTasksDashboard = observer(
737
753
  rowHeight={45}
738
754
  rowSelection={rowSelection}
739
755
  onFirstDataRendered={handleFirstDataRendered}
740
- onCellClicked={handleCellClicked}
756
+ onCellClicked={(
757
+ event: DataGridCellClickedEvent<
758
+ V1_ContractUserEventRecord,
759
+ unknown
760
+ >,
761
+ ) =>
762
+ // eslint-disable-next-line no-void
763
+ void handleCellClicked(event)
764
+ }
741
765
  columnDefs={privilegeManagerColDefs}
742
766
  overlayNoRowsTemplate="You have no contracts to approve as a Privilege Manager"
743
767
  loading={loading}
@@ -772,7 +796,15 @@ export const EntitlementsPendingTasksDashboard = observer(
772
796
  rowHeight={45}
773
797
  rowSelection={rowSelection}
774
798
  onFirstDataRendered={handleFirstDataRendered}
775
- onCellClicked={handleCellClicked}
799
+ onCellClicked={(
800
+ event: DataGridCellClickedEvent<
801
+ V1_ContractUserEventRecord,
802
+ unknown
803
+ >,
804
+ ) =>
805
+ // eslint-disable-next-line no-void
806
+ void handleCellClicked(event)
807
+ }
776
808
  columnDefs={dataOwnerColDefs}
777
809
  overlayNoRowsTemplate="You have no contracts to approve as a Data Owner"
778
810
  loading={loading}
@@ -796,7 +828,15 @@ export const EntitlementsPendingTasksDashboard = observer(
796
828
  rowHeight={45}
797
829
  rowSelection={rowSelection}
798
830
  onFirstDataRendered={handleFirstDataRendered}
799
- onCellClicked={handleCellClicked}
831
+ onCellClicked={(
832
+ event: DataGridCellClickedEvent<
833
+ V1_ContractUserEventRecord,
834
+ unknown
835
+ >,
836
+ ) =>
837
+ // eslint-disable-next-line no-void
838
+ void handleCellClicked(event)
839
+ }
800
840
  columnDefs={otherTasksColDefs}
801
841
  loading={loading}
802
842
  overlayLoadingTemplate="Loading contracts"
@@ -819,10 +859,15 @@ export const EntitlementsPendingTasksDashboard = observer(
819
859
  pendingTaskContracts={pendingTaskContracts}
820
860
  marketplaceBaseStore={marketplaceBaseStore}
821
861
  />
822
- {selectedContract !== undefined && (
862
+ {selectedContract !== undefined && !ingestVerificationInProgress && (
823
863
  <DataAccessRequestViewer
824
864
  open={true}
825
- onClose={() => setSelectedContract(undefined)}
865
+ onClose={() => {
866
+ setSelectedContract(undefined);
867
+ setUnverifiedIngestDefinitions(undefined);
868
+ setIngestVerificationInProgress(false);
869
+ }}
870
+ unverifiedIngestDefinitions={unverifiedIngestDefinitions}
826
871
  viewerState={
827
872
  new DataContractViewerState(
828
873
  selectedContract,