@backstage/plugin-catalog-react 0.6.13 → 0.6.14-next.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/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  # @backstage/plugin-catalog-react
2
2
 
3
+ ## 0.6.14-next.0
4
+
5
+ ### Patch Changes
6
+
7
+ - 680e7c7452: Updated `useEntityListProvider` and catalog pickers to respond to external changes to query parameters in the URL, such as two sidebar links that apply different catalog filters.
8
+ - 7bb1bde7f6: Minor API cleanups
9
+ - Updated dependencies
10
+ - @backstage/core-components@0.8.8-next.0
11
+
3
12
  ## 0.6.13
4
13
 
5
14
  ### Patch Changes
package/dist/index.cjs.js CHANGED
@@ -294,16 +294,18 @@ const EntityListProvider = ({
294
294
  const isMounted = useMountedState__default["default"]();
295
295
  const catalogApi = corePluginApi.useApi(catalogApiRef);
296
296
  const [requestedFilters, setRequestedFilters] = React.useState({});
297
- const [outputState, setOutputState] = React.useState(() => {
297
+ const location = reactRouter.useLocation();
298
+ const queryParameters = React.useMemo(() => {
298
299
  var _a;
299
- const query = qs__default["default"].parse(window.location.search, {
300
+ return (_a = qs__default["default"].parse(location.search, {
300
301
  ignoreQueryPrefix: true
301
- });
302
+ }).filters) != null ? _a : {};
303
+ }, [location]);
304
+ const [outputState, setOutputState] = React.useState(() => {
302
305
  return {
303
306
  appliedFilters: {},
304
307
  entities: [],
305
- backendEntities: [],
306
- queryParameters: (_a = query.filters) != null ? _a : {}
308
+ backendEntities: []
307
309
  };
308
310
  });
309
311
  const [{ loading, error }, refresh] = useAsyncFn__default["default"](async () => {
@@ -326,26 +328,24 @@ const EntityListProvider = ({
326
328
  setOutputState({
327
329
  appliedFilters: requestedFilters,
328
330
  backendEntities: response.items,
329
- entities: response.items.filter(entityFilter),
330
- queryParameters: queryParams
331
+ entities: response.items.filter(entityFilter)
331
332
  });
332
333
  } else {
333
334
  setOutputState({
334
335
  appliedFilters: requestedFilters,
335
336
  backendEntities: outputState.backendEntities,
336
- entities: outputState.backendEntities.filter(entityFilter),
337
- queryParameters: queryParams
337
+ entities: outputState.backendEntities.filter(entityFilter)
338
338
  });
339
339
  }
340
340
  if (isMounted()) {
341
- const oldParams = qs__default["default"].parse(window.location.search, {
341
+ const oldParams = qs__default["default"].parse(location.search, {
342
342
  ignoreQueryPrefix: true
343
343
  });
344
344
  const newParams = qs__default["default"].stringify({ ...oldParams, filters: queryParams }, { addQueryPrefix: true });
345
345
  const newUrl = `${window.location.pathname}${newParams}`;
346
346
  (_a = window.history) == null ? void 0 : _a.replaceState(null, document.title, newUrl);
347
347
  }
348
- }, [catalogApi, requestedFilters, outputState], { loading: true });
348
+ }, [catalogApi, queryParameters, requestedFilters, outputState], { loading: true });
349
349
  useDebounce__default["default"](refresh, 10, [requestedFilters]);
350
350
  const updateFilters = React.useCallback((update) => {
351
351
  setRequestedFilters((prevFilters) => {
@@ -358,10 +358,10 @@ const EntityListProvider = ({
358
358
  entities: outputState.entities,
359
359
  backendEntities: outputState.backendEntities,
360
360
  updateFilters,
361
- queryParameters: outputState.queryParameters,
361
+ queryParameters,
362
362
  loading,
363
363
  error
364
- }), [outputState, updateFilters, loading, error]);
364
+ }), [outputState, updateFilters, queryParameters, loading, error]);
365
365
  return /* @__PURE__ */ React__default["default"].createElement(EntityListContext.Provider, {
366
366
  value
367
367
  }, children);
@@ -548,8 +548,13 @@ function useEntityTypeFilter() {
548
548
  queryParameters,
549
549
  updateFilters
550
550
  } = useEntityListProvider();
551
- const queryParamTypes = [queryParameters.type].flat().filter(Boolean);
551
+ const queryParamTypes = React.useMemo(() => [queryParameters.type].flat().filter(Boolean), [queryParameters]);
552
552
  const [selectedTypes, setSelectedTypes] = React.useState(queryParamTypes.length ? queryParamTypes : (_a = typeFilter == null ? void 0 : typeFilter.getTypes()) != null ? _a : []);
553
+ React.useEffect(() => {
554
+ if (queryParamTypes.length) {
555
+ setSelectedTypes(queryParamTypes);
556
+ }
557
+ }, [queryParamTypes]);
553
558
  const [availableTypes, setAvailableTypes] = React.useState([]);
554
559
  const kind = React.useMemo(() => kindFilter == null ? void 0 : kindFilter.value, [kindFilter]);
555
560
  const {
@@ -796,11 +801,9 @@ function useEntityPermission(permission) {
796
801
  return { loading: false, allowed, error: permissionError };
797
802
  }
798
803
 
799
- const EntityKindPicker = ({
800
- initialFilter,
801
- hidden
802
- }) => {
804
+ const EntityKindPicker = (props) => {
803
805
  var _a;
806
+ const { initialFilter, hidden } = props;
804
807
  const { updateFilters, queryParameters } = useEntityListProvider();
805
808
  const [selectedKind] = React.useState((_a = [queryParameters.kind].flat()[0]) != null ? _a : initialFilter);
806
809
  React.useEffect(() => {
@@ -830,8 +833,13 @@ const EntityLifecyclePicker = () => {
830
833
  var _a, _b;
831
834
  const classes = useStyles$6();
832
835
  const { updateFilters, backendEntities, filters, queryParameters } = useEntityListProvider();
833
- const queryParamLifecycles = [queryParameters.lifecycles].flat().filter(Boolean);
836
+ const queryParamLifecycles = React.useMemo(() => [queryParameters.lifecycles].flat().filter(Boolean), [queryParameters]);
834
837
  const [selectedLifecycles, setSelectedLifecycles] = React.useState(queryParamLifecycles.length ? queryParamLifecycles : (_b = (_a = filters.lifecycles) == null ? void 0 : _a.values) != null ? _b : []);
838
+ React.useEffect(() => {
839
+ if (queryParamLifecycles.length) {
840
+ setSelectedLifecycles(queryParamLifecycles);
841
+ }
842
+ }, [queryParamLifecycles]);
835
843
  React.useEffect(() => {
836
844
  updateFilters({
837
845
  lifecycles: selectedLifecycles.length ? new EntityLifecycleFilter(selectedLifecycles) : void 0
@@ -891,8 +899,13 @@ const EntityOwnerPicker = () => {
891
899
  var _a, _b;
892
900
  const classes = useStyles$5();
893
901
  const { updateFilters, backendEntities, filters, queryParameters } = useEntityListProvider();
894
- const queryParamOwners = [queryParameters.owners].flat().filter(Boolean);
902
+ const queryParamOwners = React.useMemo(() => [queryParameters.owners].flat().filter(Boolean), [queryParameters]);
895
903
  const [selectedOwners, setSelectedOwners] = React.useState(queryParamOwners.length ? queryParamOwners : (_b = (_a = filters.owners) == null ? void 0 : _a.values) != null ? _b : []);
904
+ React.useEffect(() => {
905
+ if (queryParamOwners.length) {
906
+ setSelectedOwners(queryParamOwners);
907
+ }
908
+ }, [queryParamOwners]);
896
909
  React.useEffect(() => {
897
910
  updateFilters({
898
911
  owners: selectedOwners.length ? new EntityOwnerFilter(selectedOwners) : void 0
@@ -976,9 +989,8 @@ const EntitySearchBar = () => {
976
989
  })));
977
990
  };
978
991
 
979
- function createEntityRefColumn({
980
- defaultKind
981
- }) {
992
+ function createEntityRefColumn(options) {
993
+ const { defaultKind } = options;
982
994
  function formatContent(entity) {
983
995
  var _a;
984
996
  return ((_a = entity.metadata) == null ? void 0 : _a.title) || formatEntityRefTitle(entity, {
@@ -1118,13 +1130,14 @@ const useStyles$3 = core.makeStyles((theme) => ({
1118
1130
  justifyContent: "center"
1119
1131
  }
1120
1132
  }));
1121
- function EntityTable({
1122
- entities,
1123
- title,
1124
- emptyContent,
1125
- variant = "gridItem",
1126
- columns
1127
- }) {
1133
+ function EntityTable(props) {
1134
+ const {
1135
+ entities,
1136
+ title,
1137
+ emptyContent,
1138
+ variant = "gridItem",
1139
+ columns
1140
+ } = props;
1128
1141
  const classes = useStyles$3();
1129
1142
  const tableStyle = {
1130
1143
  minWidth: "0",
@@ -1168,8 +1181,13 @@ const EntityTagPicker = () => {
1168
1181
  var _a, _b;
1169
1182
  const classes = useStyles$2();
1170
1183
  const { updateFilters, backendEntities, filters, queryParameters } = useEntityListProvider();
1171
- const queryParamTags = [queryParameters.tags].flat().filter(Boolean);
1184
+ const queryParamTags = React.useMemo(() => [queryParameters.tags].flat().filter(Boolean), [queryParameters]);
1172
1185
  const [selectedTags, setSelectedTags] = React.useState(queryParamTags.length ? queryParamTags : (_b = (_a = filters.tags) == null ? void 0 : _a.values) != null ? _b : []);
1186
+ React.useEffect(() => {
1187
+ if (queryParamTags.length) {
1188
+ setSelectedTags(queryParamTags);
1189
+ }
1190
+ }, [queryParamTags]);
1173
1191
  React.useEffect(() => {
1174
1192
  updateFilters({
1175
1193
  tags: selectedTags.length ? new EntityTagFilter(selectedTags) : void 0
@@ -1516,7 +1534,7 @@ const UserListPicker = ({
1516
1534
  initialFilter,
1517
1535
  availableFilters
1518
1536
  }) => {
1519
- var _a, _b;
1537
+ var _a;
1520
1538
  const classes = useStyles();
1521
1539
  const configApi = corePluginApi.useApi(corePluginApi.configApiRef);
1522
1540
  const orgName = (_a = configApi.getOptionalString("organization.name")) != null ? _a : "Company";
@@ -1530,13 +1548,19 @@ const UserListPicker = ({
1530
1548
  const { isOwnedEntity } = useEntityOwnership();
1531
1549
  const ownedFilter = React.useMemo(() => new UserListFilter("owned", isOwnedEntity, isStarredEntity), [isOwnedEntity, isStarredEntity]);
1532
1550
  const starredFilter = React.useMemo(() => new UserListFilter("starred", isOwnedEntity, isStarredEntity), [isOwnedEntity, isStarredEntity]);
1533
- const [selectedUserFilter, setSelectedUserFilter] = React.useState((_b = [queryParameters.user].flat()[0]) != null ? _b : initialFilter);
1551
+ const queryParamUserFilter = React.useMemo(() => [queryParameters.user].flat()[0], [queryParameters]);
1552
+ const [selectedUserFilter, setSelectedUserFilter] = React.useState(queryParamUserFilter != null ? queryParamUserFilter : initialFilter);
1534
1553
  const entitiesWithoutUserFilter = React.useMemo(() => backendEntities.filter(reduceEntityFilters(lodash.compact(Object.values({ ...filters, user: void 0 })))), [filters, backendEntities]);
1535
1554
  const filterCounts = React.useMemo(() => ({
1536
1555
  all: entitiesWithoutUserFilter.length,
1537
1556
  starred: entitiesWithoutUserFilter.filter((entity) => starredFilter.filterEntity(entity)).length,
1538
1557
  owned: entitiesWithoutUserFilter.filter((entity) => ownedFilter.filterEntity(entity)).length
1539
1558
  }), [entitiesWithoutUserFilter, starredFilter, ownedFilter]);
1559
+ React.useEffect(() => {
1560
+ if (queryParamUserFilter) {
1561
+ setSelectedUserFilter(queryParamUserFilter);
1562
+ }
1563
+ }, [queryParamUserFilter]);
1540
1564
  React.useEffect(() => {
1541
1565
  if (!loading && !!selectedUserFilter && selectedUserFilter !== "all" && filterCounts[selectedUserFilter] === 0) {
1542
1566
  setSelectedUserFilter("all");
@@ -1560,7 +1584,7 @@ const UserListPicker = ({
1560
1584
  disablePadding: true,
1561
1585
  dense: true
1562
1586
  }, group.items.map((item) => {
1563
- var _a2, _b2;
1587
+ var _a2, _b;
1564
1588
  return /* @__PURE__ */ React__default["default"].createElement(core.MenuItem, {
1565
1589
  key: item.id,
1566
1590
  button: true,
@@ -1576,7 +1600,7 @@ const UserListPicker = ({
1576
1600
  fontSize: "small"
1577
1601
  })), /* @__PURE__ */ React__default["default"].createElement(core.ListItemText, null, /* @__PURE__ */ React__default["default"].createElement(core.Typography, {
1578
1602
  variant: "body1"
1579
- }, item.label)), /* @__PURE__ */ React__default["default"].createElement(core.ListItemSecondaryAction, null, (_b2 = filterCounts[item.id]) != null ? _b2 : "-"));
1603
+ }, item.label)), /* @__PURE__ */ React__default["default"].createElement(core.ListItemSecondaryAction, null, (_b = filterCounts[item.id]) != null ? _b : "-"));
1580
1604
  }))))));
1581
1605
  };
1582
1606
 
@@ -1592,17 +1616,25 @@ const MockEntityListContextProvider = ({
1592
1616
  return { ...prevFilters, ...newFilters };
1593
1617
  });
1594
1618
  }, []);
1595
- const defaultContext = {
1619
+ const defaultValues = React.useMemo(() => ({
1596
1620
  entities: [],
1597
1621
  backendEntities: [],
1598
- updateFilters,
1599
- filters,
1600
- loading: false,
1601
1622
  queryParameters: {}
1602
- };
1603
- const { filters: _, ...otherContextFields } = value != null ? value : {};
1623
+ }), []);
1624
+ const resolvedValue = React.useMemo(() => {
1625
+ var _a2, _b, _c, _d, _e;
1626
+ return {
1627
+ entities: (_a2 = value == null ? void 0 : value.entities) != null ? _a2 : defaultValues.entities,
1628
+ backendEntities: (_b = value == null ? void 0 : value.backendEntities) != null ? _b : defaultValues.backendEntities,
1629
+ updateFilters: (_c = value == null ? void 0 : value.updateFilters) != null ? _c : updateFilters,
1630
+ filters,
1631
+ loading: (_d = value == null ? void 0 : value.loading) != null ? _d : false,
1632
+ queryParameters: (_e = value == null ? void 0 : value.queryParameters) != null ? _e : defaultValues.queryParameters,
1633
+ error: value == null ? void 0 : value.error
1634
+ };
1635
+ }, [value, defaultValues, filters, updateFilters]);
1604
1636
  return /* @__PURE__ */ React__default["default"].createElement(EntityListContext.Provider, {
1605
- value: { ...defaultContext, ...otherContextFields }
1637
+ value: resolvedValue
1606
1638
  }, children);
1607
1639
  };
1608
1640