@easyteam/auto-scheduler-modal-ui 0.1.2 → 0.1.3

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 CHANGED
@@ -1361,7 +1361,7 @@ function buildRulesPayload(selectedConstraintIds, constraintValues, selectedOpti
1361
1361
  return { ruleIds: allSelectedRuleIds, ruleOverrides };
1362
1362
  }
1363
1363
  function toApiShift(shift, includeEmployeePreferences) {
1364
- var _a, _b;
1364
+ var _a;
1365
1365
  const startDateTime = "startDateTime" in shift ? shift.startDateTime : shift.startTime;
1366
1366
  const endDateTime = "endDateTime" in shift ? shift.endDateTime : shift.endTime;
1367
1367
  return {
@@ -1369,8 +1369,8 @@ function toApiShift(shift, includeEmployeePreferences) {
1369
1369
  startDateTime,
1370
1370
  endDateTime,
1371
1371
  ...shift.employeeId ? { employeeId: String(shift.employeeId) } : {},
1372
- requiredPosition: (_a = shift.requiredPosition) != null ? _a : void 0,
1373
- requiredCount: (_b = shift.requiredCount) != null ? _b : 1,
1372
+ requiredPosition: shift.requiredPosition || void 0,
1373
+ requiredCount: (_a = shift.requiredCount) != null ? _a : 1,
1374
1374
  location: shift.location ? {
1375
1375
  id: String(shift.location.id),
1376
1376
  timezone: "timezone" in shift.location ? shift.location.timezone : void 0,
@@ -1700,12 +1700,15 @@ function ViolatedConstraintsPanel({
1700
1700
  onSecondaryButtonClick,
1701
1701
  generateRecommendationsURLAndHeaders,
1702
1702
  styles: stylesProp,
1703
- styleOverrides
1703
+ styleOverrides,
1704
+ errorToast
1704
1705
  }) {
1705
1706
  const [showRecommendations, setShowRecommendations] = (0, import_react.useState)(false);
1706
1707
  const [isExpanded, setIsExpanded] = (0, import_react.useState)(true);
1707
1708
  const [recommendations, setRecommendations] = (0, import_react.useState)(null);
1708
1709
  const [isLoadingRecommendations, setIsLoadingRecommendations] = (0, import_react.useState)(false);
1710
+ const [isDisabledRecommendations, setIsDisabledRecommendations] = (0, import_react.useState)(false);
1711
+ const [recommendationsButtonText, setRecommendationsButtonText] = (0, import_react.useState)("Show recommendations");
1709
1712
  const styles = (0, import_react.useMemo)(() => {
1710
1713
  if (stylesProp) return stylesProp;
1711
1714
  return buildStyles(defaultStyles, styleOverrides);
@@ -1716,12 +1719,10 @@ function ViolatedConstraintsPanel({
1716
1719
  const displayRecommendations = recommendations !== null ? recommendations : violatedConstraints.recommendedFixes;
1717
1720
  const hasRecommendations = displayRecommendations.length > 0;
1718
1721
  const handleToggleRecommendations = (0, import_react.useCallback)(async () => {
1719
- var _a, _b;
1720
1722
  if (showRecommendations) {
1721
1723
  setShowRecommendations(false);
1722
1724
  return;
1723
1725
  }
1724
- setShowRecommendations(true);
1725
1726
  if (recommendations !== null) {
1726
1727
  return;
1727
1728
  }
@@ -1741,9 +1742,21 @@ function ViolatedConstraintsPanel({
1741
1742
  }
1742
1743
  }
1743
1744
  );
1744
- const data = (_b = (_a = recResponse.data) == null ? void 0 : _a.data) != null ? _b : recResponse.data;
1745
- if (data) {
1746
- setRecommendations(data.map((r) => r.recommendation));
1745
+ const { success, data, msg } = recResponse.data;
1746
+ const { isExpired, recommendations: recommendations2 } = data != null ? data : {};
1747
+ if (!success) {
1748
+ const errorMsg = msg || "Failed to fetch recommendations";
1749
+ errorToast == null ? void 0 : errorToast(errorMsg);
1750
+ if (isExpired) {
1751
+ setIsDisabledRecommendations(true);
1752
+ setRecommendationsButtonText("Daily limit reached");
1753
+ }
1754
+ return;
1755
+ }
1756
+ setShowRecommendations(true);
1757
+ const fetchedRecommendations = recommendations2;
1758
+ if (fetchedRecommendations) {
1759
+ setRecommendations(fetchedRecommendations.map((r) => r.recommendation));
1747
1760
  } else {
1748
1761
  setRecommendations([]);
1749
1762
  }
@@ -1758,7 +1771,8 @@ function ViolatedConstraintsPanel({
1758
1771
  recommendations,
1759
1772
  canFetchRecommendations,
1760
1773
  violatedConstraints.recommendationPayload,
1761
- generateRecommendationsURLAndHeaders
1774
+ generateRecommendationsURLAndHeaders,
1775
+ errorToast
1762
1776
  ]);
1763
1777
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react2.Box, { sx: styles.violationPanel, children: [
1764
1778
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_react2.HStack, { sx: styles.violationHeaderRow, children: [
@@ -1810,9 +1824,9 @@ function ViolatedConstraintsPanel({
1810
1824
  variant: "outline",
1811
1825
  size: "xs",
1812
1826
  onClick: handleToggleRecommendations,
1813
- isDisabled: isLoadingRecommendations,
1827
+ isDisabled: isLoadingRecommendations || isDisabledRecommendations,
1814
1828
  sx: { ...styles.recommendationsToggle, minWidth: "140px" },
1815
- children: isLoadingRecommendations ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react2.Spinner, { size: "sm", thickness: "2px" }) : showRecommendations ? "Hide recommendations" : "Show recommendations"
1829
+ children: isLoadingRecommendations ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react2.Spinner, { size: "sm", thickness: "2px" }) : showRecommendations ? "Hide recommendations" : recommendationsButtonText
1816
1830
  }
1817
1831
  ) : null,
1818
1832
  showSecondaryButton && secondaryButtonTitle && onSecondaryButtonClick ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
@@ -1854,7 +1868,8 @@ function AutoSchedulerModal({
1854
1868
  getTokenURLAndHeaders,
1855
1869
  onSolution,
1856
1870
  getStoredConfigForLocations,
1857
- persistConfigForLocations
1871
+ persistConfigForLocations,
1872
+ errorToast
1858
1873
  }) {
1859
1874
  const baseTheme = (0, import_react4.useTheme)();
1860
1875
  const { chakraOverride, styleOverrides } = (0, import_react3.useMemo)(
@@ -1891,6 +1906,11 @@ function AutoSchedulerModal({
1891
1906
  (total, jurisdiction) => total + jurisdiction.selectedLocations.length,
1892
1907
  0
1893
1908
  );
1909
+ const locationIdsWithOpenShifts = (0, import_react3.useMemo)(() => {
1910
+ return new Set(
1911
+ openShifts.filter((shift) => !shift.employeeId).map((shift) => shift.location.id)
1912
+ );
1913
+ }, [openShifts]);
1894
1914
  const selectedConstraints = (0, import_react3.useMemo)(
1895
1915
  () => HARD_CONSTRAINT_OPTIONS.filter((option) => selectedConstraintIds.includes(option.id)),
1896
1916
  [selectedConstraintIds]
@@ -1995,6 +2015,12 @@ function AutoSchedulerModal({
1995
2015
  }
1996
2016
  }, [selectedLocationIds, initialConfig, getStoredConfigForLocations]);
1997
2017
  (0, import_react3.useEffect)(() => () => clearTimers(), []);
2018
+ (0, import_react3.useEffect)(() => {
2019
+ setSelectedLocationIds((previous) => {
2020
+ const filtered = previous.filter((id) => locationIdsWithOpenShifts.has(id));
2021
+ return filtered.length === previous.length ? previous : filtered;
2022
+ });
2023
+ }, [locationIdsWithOpenShifts]);
1998
2024
  const stepStatusForIndex = (index) => {
1999
2025
  if (index <= completedStepIndex) {
2000
2026
  return "done";
@@ -2178,6 +2204,9 @@ function AutoSchedulerModal({
2178
2204
  setScreen("configure");
2179
2205
  };
2180
2206
  const handleToggleLocation = (locationId) => {
2207
+ if (!locationIdsWithOpenShifts.has(locationId)) {
2208
+ return;
2209
+ }
2181
2210
  if (selectedLocationIds.includes(locationId)) {
2182
2211
  setSelectedLocationIds(selectedLocationIds.filter((id) => id !== locationId));
2183
2212
  return;
@@ -2241,6 +2270,7 @@ function AutoSchedulerModal({
2241
2270
  violatedConstraints: lastFailure,
2242
2271
  title: violationTitle,
2243
2272
  subtitle: "",
2273
+ errorToast,
2244
2274
  generateRecommendationsURLAndHeaders,
2245
2275
  styles
2246
2276
  }
@@ -2300,13 +2330,18 @@ function AutoSchedulerModal({
2300
2330
  import_react4.HStack,
2301
2331
  {
2302
2332
  as: "label",
2303
- sx: { ...styles.optionRow, cursor: "pointer" },
2333
+ sx: {
2334
+ ...styles.optionRow,
2335
+ cursor: locationIdsWithOpenShifts.has(location.id) ? "pointer" : "not-allowed",
2336
+ opacity: locationIdsWithOpenShifts.has(location.id) ? 1 : 0.55
2337
+ },
2304
2338
  children: [
2305
2339
  /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2306
2340
  import_react4.Checkbox,
2307
2341
  {
2308
2342
  id: `location-${location.id}`,
2309
2343
  isChecked: selectedLocationIds.includes(location.id),
2344
+ isDisabled: !locationIdsWithOpenShifts.has(location.id),
2310
2345
  onChange: () => handleToggleLocation(location.id)
2311
2346
  }
2312
2347
  ),