@plusscommunities/pluss-maintenance-web-forms 1.1.37-beta.6 → 1.1.37-beta.7

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.cjs.js CHANGED
@@ -816,11 +816,25 @@ class JobList extends React.Component {
816
816
  }
817
817
  return params;
818
818
  });
819
+ /**
820
+ * Minimum number of items to auto-fill before stopping background fetch.
821
+ * Because DynamoDB pages are unfiltered and the backend filters after
822
+ * query, a single page may yield very few matching results. We keep
823
+ * fetching in the background until we have this many items to display.
824
+ */
825
+ _defineProperty__default["default"](this, "MIN_PAGE_SIZE", 20);
819
826
  /**
820
827
  * Monotonically increasing ID used to ignore stale fetch results.
821
828
  * When a filter changes, fetchJobs() increments this counter. Any
822
- * in-flight fetch checks the counter before applying results —
823
- * if it doesn't match, the results are discarded.
829
+ * in-flight fetch or autoFillPages loop checks the counter before
830
+ * applying results — if it doesn't match, the results are discarded.
831
+ *
832
+ * Alternative: AbortController would actually cancel the HTTP request
833
+ * (axios supports it via the `signal` config option). That would save
834
+ * bandwidth and server load but requires threading `signal` through
835
+ * authedFunction → getJobs2 → fetchPage (3 layers). The fetchId
836
+ * approach is simpler and sufficient — stale requests still complete
837
+ * in the background but their results are ignored.
824
838
  */
825
839
  _defineProperty__default["default"](this, "_fetchId", 0);
826
840
  /**
@@ -836,6 +850,9 @@ class JobList extends React.Component {
836
850
  });
837
851
  /**
838
852
  * Fetch the first page and render immediately.
853
+ * If fewer than MIN_PAGE_SIZE items returned and there's more data,
854
+ * kicks off a background loop that keeps fetching and appending
855
+ * so results appear progressively.
839
856
  */
840
857
  _defineProperty__default["default"](this, "fetchJobs", async () => {
841
858
  const fetchId = ++this._fetchId;
@@ -845,7 +862,8 @@ class JobList extends React.Component {
845
862
  }, async () => {
846
863
  try {
847
864
  const res = await this.fetchPage(null);
848
- if (this._fetchId !== fetchId) return;
865
+ if (this._fetchId !== fetchId) return; // stale fetch
866
+
849
867
  const items = res.data.Items || [];
850
868
  const lastKey = res.data.LastKey || null;
851
869
  this.setState({
@@ -856,8 +874,13 @@ class JobList extends React.Component {
856
874
  });
857
875
  this.props.jobsLoaded(items);
858
876
  this.setRequesters(items);
877
+
878
+ // Auto-fill in background if first page was sparse
879
+ if (lastKey && items.length < this.MIN_PAGE_SIZE) {
880
+ this.autoFillPages(items, lastKey, fetchId);
881
+ }
859
882
  } catch (error) {
860
- if (this._fetchId !== fetchId) return;
883
+ if (this._fetchId !== fetchId) return; // stale fetch
861
884
  console.error('fetchJobs', error);
862
885
  this.setState({
863
886
  loading: false
@@ -865,8 +888,52 @@ class JobList extends React.Component {
865
888
  }
866
889
  });
867
890
  });
891
+ /**
892
+ * Background loop: keep fetching pages and appending results
893
+ * until we have MIN_PAGE_SIZE items or run out of data.
894
+ * Each page is rendered as it arrives so the user sees
895
+ * results appearing progressively.
896
+ */
897
+ _defineProperty__default["default"](this, "autoFillPages", async (existingJobs, startKey, fetchId) => {
898
+ this.setState({
899
+ loadingMore: true
900
+ });
901
+ let currentJobs = existingJobs;
902
+ let currentLastKey = startKey;
903
+ try {
904
+ while (currentLastKey && currentJobs.length < this.MIN_PAGE_SIZE) {
905
+ const res = await this.fetchPage(currentLastKey);
906
+ if (this._fetchId !== fetchId) return; // stale fetch
907
+
908
+ const items = res.data.Items || [];
909
+ currentLastKey = res.data.LastKey || null;
910
+ currentJobs = [...currentJobs, ...items];
911
+
912
+ // Append to UI immediately after each page arrives
913
+ this.setState({
914
+ jobs: currentJobs,
915
+ lastKey: currentLastKey,
916
+ hasMore: !!currentLastKey
917
+ });
918
+ if (items.length > 0) {
919
+ this.props.jobsLoaded(items);
920
+ this.setRequesters(currentJobs);
921
+ }
922
+ }
923
+ } catch (error) {
924
+ if (this._fetchId !== fetchId) return; // stale fetch
925
+ console.error('autoFillPages', error);
926
+ } finally {
927
+ if (this._fetchId === fetchId) {
928
+ this.setState({
929
+ loadingMore: false
930
+ });
931
+ }
932
+ }
933
+ });
868
934
  /**
869
935
  * Load the next batch of jobs when the user clicks "Load More".
936
+ * Fetches one page and also auto-fills in background if sparse.
870
937
  */
871
938
  _defineProperty__default["default"](this, "loadMore", async () => {
872
939
  const fetchId = ++this._fetchId;
@@ -879,21 +946,30 @@ class JobList extends React.Component {
879
946
  }, async () => {
880
947
  try {
881
948
  const res = await this.fetchPage(lastKey);
882
- if (this._fetchId !== fetchId) return;
949
+ if (this._fetchId !== fetchId) return; // stale fetch
950
+
883
951
  const items = res.data.Items || [];
884
952
  const newLastKey = res.data.LastKey || null;
885
953
  const updatedJobs = [...jobs, ...items];
886
954
  this.setState({
887
955
  jobs: updatedJobs,
888
956
  lastKey: newLastKey,
889
- hasMore: !!newLastKey,
890
- loadingMore: false
957
+ hasMore: !!newLastKey
891
958
  });
892
959
  if (items.length > 0) {
893
960
  this.props.jobsLoaded(items);
894
961
  }
962
+
963
+ // Auto-fill in background if this page was sparse
964
+ if (newLastKey && items.length < this.MIN_PAGE_SIZE) {
965
+ this.autoFillPages(updatedJobs, newLastKey, fetchId);
966
+ } else {
967
+ this.setState({
968
+ loadingMore: false
969
+ });
970
+ }
895
971
  } catch (error) {
896
- if (this._fetchId !== fetchId) return;
972
+ if (this._fetchId !== fetchId) return; // stale fetch
897
973
  console.error('loadMore', error);
898
974
  this.setState({
899
975
  loadingMore: false
@@ -1274,7 +1350,7 @@ class JobList extends React.Component {
1274
1350
  // Filters (applied to server-side queries)
1275
1351
  selectedTypeFilter: null,
1276
1352
  selectedPriorityFilter: null,
1277
- selectedStatusFilter: null,
1353
+ selectedStatusFilter: STATUS_IMCOMPLETE,
1278
1354
  selectedTimeFilterStart: null,
1279
1355
  selectedTimeFilterEnd: null,
1280
1356
  selectedTimeFilterText: null,
@@ -1725,24 +1801,16 @@ class JobList extends React.Component {
1725
1801
  }, "Loading more results\u2026"));
1726
1802
  }
1727
1803
  return /*#__PURE__*/React__default["default"].createElement("div", {
1804
+ className: "flex flex-center-row",
1728
1805
  style: {
1729
- margin: '24px 0 40px 0',
1730
- position: 'relative',
1731
- top: -16
1806
+ padding: '16px 0'
1732
1807
  }
1733
1808
  }, /*#__PURE__*/React__default["default"].createElement(Components$7.Button, {
1734
- buttonType: "primary",
1809
+ inline: true,
1810
+ buttonType: "tertiary",
1735
1811
  onClick: this.loadMore,
1736
- isActive: true,
1737
- style: {
1738
- width: '100%'
1739
- }
1740
- }, "Load More Results", /*#__PURE__*/React__default["default"].createElement(FontAwesome__default["default"], {
1741
- name: "plus",
1742
- style: {
1743
- marginLeft: 8
1744
- }
1745
- })));
1812
+ isActive: true
1813
+ }, "Load More"));
1746
1814
  }
1747
1815
  renderContent() {
1748
1816
  const {
package/dist/index.esm.js CHANGED
@@ -785,11 +785,25 @@ class JobList extends Component {
785
785
  }
786
786
  return params;
787
787
  });
788
+ /**
789
+ * Minimum number of items to auto-fill before stopping background fetch.
790
+ * Because DynamoDB pages are unfiltered and the backend filters after
791
+ * query, a single page may yield very few matching results. We keep
792
+ * fetching in the background until we have this many items to display.
793
+ */
794
+ _defineProperty(this, "MIN_PAGE_SIZE", 20);
788
795
  /**
789
796
  * Monotonically increasing ID used to ignore stale fetch results.
790
797
  * When a filter changes, fetchJobs() increments this counter. Any
791
- * in-flight fetch checks the counter before applying results —
792
- * if it doesn't match, the results are discarded.
798
+ * in-flight fetch or autoFillPages loop checks the counter before
799
+ * applying results — if it doesn't match, the results are discarded.
800
+ *
801
+ * Alternative: AbortController would actually cancel the HTTP request
802
+ * (axios supports it via the `signal` config option). That would save
803
+ * bandwidth and server load but requires threading `signal` through
804
+ * authedFunction → getJobs2 → fetchPage (3 layers). The fetchId
805
+ * approach is simpler and sufficient — stale requests still complete
806
+ * in the background but their results are ignored.
793
807
  */
794
808
  _defineProperty(this, "_fetchId", 0);
795
809
  /**
@@ -805,6 +819,9 @@ class JobList extends Component {
805
819
  });
806
820
  /**
807
821
  * Fetch the first page and render immediately.
822
+ * If fewer than MIN_PAGE_SIZE items returned and there's more data,
823
+ * kicks off a background loop that keeps fetching and appending
824
+ * so results appear progressively.
808
825
  */
809
826
  _defineProperty(this, "fetchJobs", async () => {
810
827
  const fetchId = ++this._fetchId;
@@ -814,7 +831,8 @@ class JobList extends Component {
814
831
  }, async () => {
815
832
  try {
816
833
  const res = await this.fetchPage(null);
817
- if (this._fetchId !== fetchId) return;
834
+ if (this._fetchId !== fetchId) return; // stale fetch
835
+
818
836
  const items = res.data.Items || [];
819
837
  const lastKey = res.data.LastKey || null;
820
838
  this.setState({
@@ -825,8 +843,13 @@ class JobList extends Component {
825
843
  });
826
844
  this.props.jobsLoaded(items);
827
845
  this.setRequesters(items);
846
+
847
+ // Auto-fill in background if first page was sparse
848
+ if (lastKey && items.length < this.MIN_PAGE_SIZE) {
849
+ this.autoFillPages(items, lastKey, fetchId);
850
+ }
828
851
  } catch (error) {
829
- if (this._fetchId !== fetchId) return;
852
+ if (this._fetchId !== fetchId) return; // stale fetch
830
853
  console.error('fetchJobs', error);
831
854
  this.setState({
832
855
  loading: false
@@ -834,8 +857,52 @@ class JobList extends Component {
834
857
  }
835
858
  });
836
859
  });
860
+ /**
861
+ * Background loop: keep fetching pages and appending results
862
+ * until we have MIN_PAGE_SIZE items or run out of data.
863
+ * Each page is rendered as it arrives so the user sees
864
+ * results appearing progressively.
865
+ */
866
+ _defineProperty(this, "autoFillPages", async (existingJobs, startKey, fetchId) => {
867
+ this.setState({
868
+ loadingMore: true
869
+ });
870
+ let currentJobs = existingJobs;
871
+ let currentLastKey = startKey;
872
+ try {
873
+ while (currentLastKey && currentJobs.length < this.MIN_PAGE_SIZE) {
874
+ const res = await this.fetchPage(currentLastKey);
875
+ if (this._fetchId !== fetchId) return; // stale fetch
876
+
877
+ const items = res.data.Items || [];
878
+ currentLastKey = res.data.LastKey || null;
879
+ currentJobs = [...currentJobs, ...items];
880
+
881
+ // Append to UI immediately after each page arrives
882
+ this.setState({
883
+ jobs: currentJobs,
884
+ lastKey: currentLastKey,
885
+ hasMore: !!currentLastKey
886
+ });
887
+ if (items.length > 0) {
888
+ this.props.jobsLoaded(items);
889
+ this.setRequesters(currentJobs);
890
+ }
891
+ }
892
+ } catch (error) {
893
+ if (this._fetchId !== fetchId) return; // stale fetch
894
+ console.error('autoFillPages', error);
895
+ } finally {
896
+ if (this._fetchId === fetchId) {
897
+ this.setState({
898
+ loadingMore: false
899
+ });
900
+ }
901
+ }
902
+ });
837
903
  /**
838
904
  * Load the next batch of jobs when the user clicks "Load More".
905
+ * Fetches one page and also auto-fills in background if sparse.
839
906
  */
840
907
  _defineProperty(this, "loadMore", async () => {
841
908
  const fetchId = ++this._fetchId;
@@ -848,21 +915,30 @@ class JobList extends Component {
848
915
  }, async () => {
849
916
  try {
850
917
  const res = await this.fetchPage(lastKey);
851
- if (this._fetchId !== fetchId) return;
918
+ if (this._fetchId !== fetchId) return; // stale fetch
919
+
852
920
  const items = res.data.Items || [];
853
921
  const newLastKey = res.data.LastKey || null;
854
922
  const updatedJobs = [...jobs, ...items];
855
923
  this.setState({
856
924
  jobs: updatedJobs,
857
925
  lastKey: newLastKey,
858
- hasMore: !!newLastKey,
859
- loadingMore: false
926
+ hasMore: !!newLastKey
860
927
  });
861
928
  if (items.length > 0) {
862
929
  this.props.jobsLoaded(items);
863
930
  }
931
+
932
+ // Auto-fill in background if this page was sparse
933
+ if (newLastKey && items.length < this.MIN_PAGE_SIZE) {
934
+ this.autoFillPages(updatedJobs, newLastKey, fetchId);
935
+ } else {
936
+ this.setState({
937
+ loadingMore: false
938
+ });
939
+ }
864
940
  } catch (error) {
865
- if (this._fetchId !== fetchId) return;
941
+ if (this._fetchId !== fetchId) return; // stale fetch
866
942
  console.error('loadMore', error);
867
943
  this.setState({
868
944
  loadingMore: false
@@ -1243,7 +1319,7 @@ class JobList extends Component {
1243
1319
  // Filters (applied to server-side queries)
1244
1320
  selectedTypeFilter: null,
1245
1321
  selectedPriorityFilter: null,
1246
- selectedStatusFilter: null,
1322
+ selectedStatusFilter: STATUS_IMCOMPLETE,
1247
1323
  selectedTimeFilterStart: null,
1248
1324
  selectedTimeFilterEnd: null,
1249
1325
  selectedTimeFilterText: null,
@@ -1694,24 +1770,16 @@ class JobList extends Component {
1694
1770
  }, "Loading more results\u2026"));
1695
1771
  }
1696
1772
  return /*#__PURE__*/React.createElement("div", {
1773
+ className: "flex flex-center-row",
1697
1774
  style: {
1698
- margin: '24px 0 40px 0',
1699
- position: 'relative',
1700
- top: -16
1775
+ padding: '16px 0'
1701
1776
  }
1702
1777
  }, /*#__PURE__*/React.createElement(Components$7.Button, {
1703
- buttonType: "primary",
1778
+ inline: true,
1779
+ buttonType: "tertiary",
1704
1780
  onClick: this.loadMore,
1705
- isActive: true,
1706
- style: {
1707
- width: '100%'
1708
- }
1709
- }, "Load More Results", /*#__PURE__*/React.createElement(FontAwesome, {
1710
- name: "plus",
1711
- style: {
1712
- marginLeft: 8
1713
- }
1714
- })));
1781
+ isActive: true
1782
+ }, "Load More"));
1715
1783
  }
1716
1784
  renderContent() {
1717
1785
  const {
package/dist/index.umd.js CHANGED
@@ -805,11 +805,25 @@
805
805
  }
806
806
  return params;
807
807
  });
808
+ /**
809
+ * Minimum number of items to auto-fill before stopping background fetch.
810
+ * Because DynamoDB pages are unfiltered and the backend filters after
811
+ * query, a single page may yield very few matching results. We keep
812
+ * fetching in the background until we have this many items to display.
813
+ */
814
+ _defineProperty__default["default"](this, "MIN_PAGE_SIZE", 20);
808
815
  /**
809
816
  * Monotonically increasing ID used to ignore stale fetch results.
810
817
  * When a filter changes, fetchJobs() increments this counter. Any
811
- * in-flight fetch checks the counter before applying results —
812
- * if it doesn't match, the results are discarded.
818
+ * in-flight fetch or autoFillPages loop checks the counter before
819
+ * applying results — if it doesn't match, the results are discarded.
820
+ *
821
+ * Alternative: AbortController would actually cancel the HTTP request
822
+ * (axios supports it via the `signal` config option). That would save
823
+ * bandwidth and server load but requires threading `signal` through
824
+ * authedFunction → getJobs2 → fetchPage (3 layers). The fetchId
825
+ * approach is simpler and sufficient — stale requests still complete
826
+ * in the background but their results are ignored.
813
827
  */
814
828
  _defineProperty__default["default"](this, "_fetchId", 0);
815
829
  /**
@@ -825,6 +839,9 @@
825
839
  });
826
840
  /**
827
841
  * Fetch the first page and render immediately.
842
+ * If fewer than MIN_PAGE_SIZE items returned and there's more data,
843
+ * kicks off a background loop that keeps fetching and appending
844
+ * so results appear progressively.
828
845
  */
829
846
  _defineProperty__default["default"](this, "fetchJobs", async () => {
830
847
  const fetchId = ++this._fetchId;
@@ -834,7 +851,8 @@
834
851
  }, async () => {
835
852
  try {
836
853
  const res = await this.fetchPage(null);
837
- if (this._fetchId !== fetchId) return;
854
+ if (this._fetchId !== fetchId) return; // stale fetch
855
+
838
856
  const items = res.data.Items || [];
839
857
  const lastKey = res.data.LastKey || null;
840
858
  this.setState({
@@ -845,8 +863,13 @@
845
863
  });
846
864
  this.props.jobsLoaded(items);
847
865
  this.setRequesters(items);
866
+
867
+ // Auto-fill in background if first page was sparse
868
+ if (lastKey && items.length < this.MIN_PAGE_SIZE) {
869
+ this.autoFillPages(items, lastKey, fetchId);
870
+ }
848
871
  } catch (error) {
849
- if (this._fetchId !== fetchId) return;
872
+ if (this._fetchId !== fetchId) return; // stale fetch
850
873
  console.error('fetchJobs', error);
851
874
  this.setState({
852
875
  loading: false
@@ -854,8 +877,52 @@
854
877
  }
855
878
  });
856
879
  });
880
+ /**
881
+ * Background loop: keep fetching pages and appending results
882
+ * until we have MIN_PAGE_SIZE items or run out of data.
883
+ * Each page is rendered as it arrives so the user sees
884
+ * results appearing progressively.
885
+ */
886
+ _defineProperty__default["default"](this, "autoFillPages", async (existingJobs, startKey, fetchId) => {
887
+ this.setState({
888
+ loadingMore: true
889
+ });
890
+ let currentJobs = existingJobs;
891
+ let currentLastKey = startKey;
892
+ try {
893
+ while (currentLastKey && currentJobs.length < this.MIN_PAGE_SIZE) {
894
+ const res = await this.fetchPage(currentLastKey);
895
+ if (this._fetchId !== fetchId) return; // stale fetch
896
+
897
+ const items = res.data.Items || [];
898
+ currentLastKey = res.data.LastKey || null;
899
+ currentJobs = [...currentJobs, ...items];
900
+
901
+ // Append to UI immediately after each page arrives
902
+ this.setState({
903
+ jobs: currentJobs,
904
+ lastKey: currentLastKey,
905
+ hasMore: !!currentLastKey
906
+ });
907
+ if (items.length > 0) {
908
+ this.props.jobsLoaded(items);
909
+ this.setRequesters(currentJobs);
910
+ }
911
+ }
912
+ } catch (error) {
913
+ if (this._fetchId !== fetchId) return; // stale fetch
914
+ console.error('autoFillPages', error);
915
+ } finally {
916
+ if (this._fetchId === fetchId) {
917
+ this.setState({
918
+ loadingMore: false
919
+ });
920
+ }
921
+ }
922
+ });
857
923
  /**
858
924
  * Load the next batch of jobs when the user clicks "Load More".
925
+ * Fetches one page and also auto-fills in background if sparse.
859
926
  */
860
927
  _defineProperty__default["default"](this, "loadMore", async () => {
861
928
  const fetchId = ++this._fetchId;
@@ -868,21 +935,30 @@
868
935
  }, async () => {
869
936
  try {
870
937
  const res = await this.fetchPage(lastKey);
871
- if (this._fetchId !== fetchId) return;
938
+ if (this._fetchId !== fetchId) return; // stale fetch
939
+
872
940
  const items = res.data.Items || [];
873
941
  const newLastKey = res.data.LastKey || null;
874
942
  const updatedJobs = [...jobs, ...items];
875
943
  this.setState({
876
944
  jobs: updatedJobs,
877
945
  lastKey: newLastKey,
878
- hasMore: !!newLastKey,
879
- loadingMore: false
946
+ hasMore: !!newLastKey
880
947
  });
881
948
  if (items.length > 0) {
882
949
  this.props.jobsLoaded(items);
883
950
  }
951
+
952
+ // Auto-fill in background if this page was sparse
953
+ if (newLastKey && items.length < this.MIN_PAGE_SIZE) {
954
+ this.autoFillPages(updatedJobs, newLastKey, fetchId);
955
+ } else {
956
+ this.setState({
957
+ loadingMore: false
958
+ });
959
+ }
884
960
  } catch (error) {
885
- if (this._fetchId !== fetchId) return;
961
+ if (this._fetchId !== fetchId) return; // stale fetch
886
962
  console.error('loadMore', error);
887
963
  this.setState({
888
964
  loadingMore: false
@@ -1263,7 +1339,7 @@
1263
1339
  // Filters (applied to server-side queries)
1264
1340
  selectedTypeFilter: null,
1265
1341
  selectedPriorityFilter: null,
1266
- selectedStatusFilter: null,
1342
+ selectedStatusFilter: STATUS_IMCOMPLETE,
1267
1343
  selectedTimeFilterStart: null,
1268
1344
  selectedTimeFilterEnd: null,
1269
1345
  selectedTimeFilterText: null,
@@ -1714,24 +1790,16 @@
1714
1790
  }, "Loading more results\u2026"));
1715
1791
  }
1716
1792
  return /*#__PURE__*/React__default["default"].createElement("div", {
1793
+ className: "flex flex-center-row",
1717
1794
  style: {
1718
- margin: '24px 0 40px 0',
1719
- position: 'relative',
1720
- top: -16
1795
+ padding: '16px 0'
1721
1796
  }
1722
1797
  }, /*#__PURE__*/React__default["default"].createElement(Components$7.Button, {
1723
- buttonType: "primary",
1798
+ inline: true,
1799
+ buttonType: "tertiary",
1724
1800
  onClick: this.loadMore,
1725
- isActive: true,
1726
- style: {
1727
- width: '100%'
1728
- }
1729
- }, "Load More Results", /*#__PURE__*/React__default["default"].createElement(FontAwesome__default["default"], {
1730
- name: "plus",
1731
- style: {
1732
- marginLeft: 8
1733
- }
1734
- })));
1801
+ isActive: true
1802
+ }, "Load More"));
1735
1803
  }
1736
1804
  renderContent() {
1737
1805
  const {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plusscommunities/pluss-maintenance-web-forms",
3
- "version": "1.1.37-beta.6",
3
+ "version": "1.1.37-beta.7",
4
4
  "description": "Extension package to enable maintenance on Pluss Communities Platform",
5
5
  "main": "dist/index.cjs.js",
6
6
  "module": "dist/index.esm.js",