@upsnap/strapi 1.0.9 → 1.0.10

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.
@@ -98,6 +98,11 @@ const MONITOR = {
98
98
  LIGHTHOUSE_DEFAULT_INTERVAL_SECONDS: 7 * 86400
99
99
  // 7 days
100
100
  };
101
+ const MONITOR_TYPE_OPTIONS = [
102
+ { value: MONITOR_TYPE.WEBSITE, label: "Website Monitoring" },
103
+ { value: MONITOR_TYPE.PORT, label: "Port Monitoring" },
104
+ { value: MONITOR_TYPE.KEYWORD, label: "Keyword Monitoring" }
105
+ ];
101
106
  const INTEGRATIONS_TYPES = {
102
107
  webhook: {
103
108
  name: "webhook",
@@ -177,6 +182,88 @@ const INCIDENTS_EXPORT_TYPES = {
177
182
  pdf: "pdf"
178
183
  };
179
184
  const INCIDENT_CHECK_TYPE_KEYS = Object.keys(INCIDENT_CHECK_TYPES);
185
+ const generateRandomColor = () => {
186
+ const colors2 = [
187
+ "#d3ed75",
188
+ "#33FF57",
189
+ "#3357FF",
190
+ "#FF33F5",
191
+ "#33FFF5",
192
+ "#eed33b",
193
+ "#47c8ff",
194
+ "#4169E1",
195
+ "#32CD32",
196
+ "#FF1493",
197
+ "#8A2BE2",
198
+ "#00CED1",
199
+ "#FF4500",
200
+ "#2E8B57",
201
+ "#DC143C"
202
+ ];
203
+ return colors2[Math.floor(Math.random() * colors2.length)];
204
+ };
205
+ const STORAGE_KEY = "selectedMonitor";
206
+ function getUserData() {
207
+ if (typeof window === "undefined") return null;
208
+ try {
209
+ const userDataString = localStorage.getItem("userDetails");
210
+ if (!userDataString) return null;
211
+ const userData = JSON.parse(userDataString);
212
+ return userData;
213
+ } catch (error) {
214
+ console.error("Error parsing userData from localStorage:", error);
215
+ return null;
216
+ }
217
+ }
218
+ async function getUserDetailsCached(forceFetchFromMicroservice = false) {
219
+ if (typeof window === "undefined") return null;
220
+ try {
221
+ const userDetailsString = localStorage.getItem("userDetails");
222
+ if (!userDetailsString) return null;
223
+ if (!forceFetchFromMicroservice) {
224
+ try {
225
+ const cached2 = JSON.parse(userDetailsString);
226
+ if (cached2.updated_at) {
227
+ const cachedTime = Date.parse(cached2.updated_at);
228
+ if (!isNaN(cachedTime)) {
229
+ const ageMs = Date.now() - cachedTime;
230
+ if (ageMs < 5 * 60 * 1e3) {
231
+ return cached2;
232
+ }
233
+ }
234
+ }
235
+ } catch (e) {
236
+ console.error("Error parsing cached user details:", e);
237
+ }
238
+ }
239
+ const data = await getUserDetails();
240
+ if (!data) {
241
+ return null;
242
+ }
243
+ setUserDetails(data);
244
+ return data;
245
+ } catch (error) {
246
+ console.error("Error parsing userDetails from localStorage:", error);
247
+ return null;
248
+ }
249
+ }
250
+ function setUserDetails(details) {
251
+ if (typeof window === "undefined") return;
252
+ try {
253
+ const toStore = { ...details, updated_at: (/* @__PURE__ */ new Date()).toISOString() };
254
+ localStorage.setItem("userDetails", JSON.stringify(toStore));
255
+ } catch (error) {
256
+ console.error("Error storing userDetails in localStorage:", error);
257
+ }
258
+ }
259
+ const clearAllStoredMonitors = () => {
260
+ if (typeof window === "undefined") return;
261
+ Object.keys(localStorage).forEach((key) => {
262
+ if (key.startsWith(`${STORAGE_KEY}`)) {
263
+ localStorage.removeItem(key);
264
+ }
265
+ });
266
+ };
180
267
  const request = async (url, options = {}) => {
181
268
  const response = await axios__default.default({
182
269
  url: `/upsnap${url}`,
@@ -342,69 +429,22 @@ const fetchRegionsData = async () => {
342
429
  return [];
343
430
  }
344
431
  };
345
- const STORAGE_KEY = "selectedMonitor";
346
- function getUserData() {
347
- if (typeof window === "undefined") return null;
348
- try {
349
- const userDataString = localStorage.getItem("userDetails");
350
- if (!userDataString) return null;
351
- const userData = JSON.parse(userDataString);
352
- return userData;
353
- } catch (error) {
354
- console.error("Error parsing userData from localStorage:", error);
355
- return null;
356
- }
357
- }
358
- async function getUserDetailsCached(forceFetchFromMicroservice = false) {
359
- if (typeof window === "undefined") return null;
432
+ const fetchTags = async (setIsLoading, setTags) => {
433
+ setIsLoading(true);
360
434
  try {
361
- const userDetailsString = localStorage.getItem("userDetails");
362
- if (!userDetailsString) return null;
363
- if (!forceFetchFromMicroservice) {
364
- try {
365
- const cached2 = JSON.parse(userDetailsString);
366
- if (cached2.updated_at) {
367
- const cachedTime = Date.parse(cached2.updated_at);
368
- if (!isNaN(cachedTime)) {
369
- const ageMs = Date.now() - cachedTime;
370
- if (ageMs < 5 * 60 * 1e3) {
371
- return cached2;
372
- }
373
- }
374
- }
375
- } catch (e) {
376
- console.error("Error parsing cached user details:", e);
377
- }
378
- }
379
- const data = await getUserDetails();
380
- if (!data) {
381
- return null;
435
+ const result = await request("/tags", {
436
+ method: "GET"
437
+ });
438
+ if (!result?.tagsData) {
439
+ throw new Error("Failed to fetch tags");
382
440
  }
383
- setUserDetails(data);
384
- return data;
385
- } catch (error) {
386
- console.error("Error parsing userDetails from localStorage:", error);
387
- return null;
388
- }
389
- }
390
- function setUserDetails(details) {
391
- if (typeof window === "undefined") return;
392
- try {
393
- const toStore = { ...details, updated_at: (/* @__PURE__ */ new Date()).toISOString() };
394
- localStorage.setItem("userDetails", JSON.stringify(toStore));
441
+ setTags(result?.tagsData?.data);
395
442
  } catch (error) {
396
- console.error("Error storing userDetails in localStorage:", error);
443
+ console.error("Error fetching tags:", error);
444
+ } finally {
445
+ setIsLoading(false);
397
446
  }
398
- }
399
- const clearAllStoredMonitors = () => {
400
- if (typeof window === "undefined") return;
401
- Object.keys(localStorage).forEach((key) => {
402
- if (key.startsWith(`${STORAGE_KEY}`)) {
403
- localStorage.removeItem(key);
404
- }
405
- });
406
447
  };
407
- getUserData()?.user?.email ?? "";
408
448
  function MonitorsTable({
409
449
  monitors = [],
410
450
  onChange,
@@ -412,15 +452,15 @@ function MonitorsTable({
412
452
  handleDelete,
413
453
  setBulkDeleteIds
414
454
  }) {
415
- const [open, setOpen] = React.useState(false);
416
- const [channels, setChannels] = React.useState([]);
417
455
  const [selected, setSelected] = React.useState([]);
418
456
  const [loading, setLoading] = React.useState(true);
419
- const [search, setSearch] = React.useState("");
420
- const [defaultEmail, setDefaultEmail] = React.useState();
421
457
  const isInternalUpdate = React.useRef(false);
422
458
  const [primaryMonitorId, setPrimaryMonitorIdState] = React.useState(null);
459
+ const [availableTags, setAvailableTags] = React.useState([]);
423
460
  const navigate = reactRouterDom.useNavigate();
461
+ React.useEffect(() => {
462
+ fetchTags(setLoading, setAvailableTags);
463
+ }, [monitors]);
424
464
  React.useEffect(() => {
425
465
  async function fetchPrimaryMonitorId() {
426
466
  try {
@@ -446,7 +486,7 @@ function MonitorsTable({
446
486
  });
447
487
  };
448
488
  const toggleAll = async () => {
449
- const allMonitorIds = Array.isArray(monitors) ? monitors.filter((m) => m.id !== null).map((m) => m.id.toString()) : [];
489
+ const allMonitorIds = Array.isArray(monitors) ? monitors.filter((monitor) => monitor.id !== null).map((monitor) => monitor.id.toString()) : [];
450
490
  const isAllSelected = allMonitorIds.every((id) => selected.includes(id));
451
491
  setSelected((prev) => {
452
492
  const updated = isAllSelected ? [] : allMonitorIds;
@@ -454,10 +494,6 @@ function MonitorsTable({
454
494
  return updated;
455
495
  });
456
496
  };
457
- Array.isArray(channels) ? channels.filter((ch) => {
458
- const email2 = ch.config?.recipients?.to ?? "";
459
- return ch.name.toLowerCase().includes(search.toLowerCase()) || email2.toLowerCase().includes(search.toLowerCase());
460
- }) : [];
461
497
  React.useEffect(() => {
462
498
  if (isInternalUpdate.current) ;
463
499
  setBulkDeleteIds(selected);
@@ -483,7 +519,9 @@ function MonitorsTable({
483
519
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { children: /* @__PURE__ */ jsxRuntime.jsx(
484
520
  designSystem.Checkbox,
485
521
  {
486
- checked: monitors.length > 0 && monitors.every((c) => c.id !== null && selected.includes(c.id.toString())),
522
+ checked: monitors.length > 0 && monitors.every(
523
+ (monitor) => monitor.id !== null && selected.includes(monitor.id.toString())
524
+ ),
487
525
  onCheckedChange: toggleAll
488
526
  }
489
527
  ) }),
@@ -501,7 +539,35 @@ function MonitorsTable({
501
539
  ) }),
502
540
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, alignItems: "self-start", direction: "column", children: [
503
541
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "semiBold", children: monitor.name }),
504
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral500", children: monitor.config.meta.url })
542
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "row", gap: 1, children: [
543
+ /* @__PURE__ */ jsxRuntime.jsx(
544
+ designSystem.Badge,
545
+ {
546
+ size: "S",
547
+ active: monitor.is_enabled,
548
+ textColor: "primary500",
549
+ background: "neutral150",
550
+ children: monitor.service_type
551
+ }
552
+ ),
553
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral500", children: monitor.config.meta.url }),
554
+ monitor.tag_ids && monitor.tag_ids.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { wrap: "wrap", gap: 1, width: "300px", children: monitor.tag_ids.map((tagId) => {
555
+ const tag = availableTags.find((tag2) => tag2.id === tagId);
556
+ if (!tag) return null;
557
+ return /* @__PURE__ */ jsxRuntime.jsx(
558
+ designSystem.Badge,
559
+ {
560
+ size: "S",
561
+ style: {
562
+ backgroundColor: `${tag.color}20`,
563
+ border: `1px solid ${tag.color}40`
564
+ },
565
+ children: tag.name
566
+ },
567
+ tagId
568
+ );
569
+ }) })
570
+ ] })
505
571
  ] }) }),
506
572
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsx(
507
573
  designSystem.Badge,
@@ -4894,7 +4960,7 @@ function MonitorIntervalSlider({
4894
4960
  const effectiveValue = userPlan === PLAN_TYPES.TRIAL && value < minMonitoringInterval ? minMonitoringInterval : value;
4895
4961
  const sliderPercent = secondsToSlider(effectiveValue);
4896
4962
  return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { width: "100%", children: [
4897
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", fontWeight: "bold", children: "Monitor interval" }),
4963
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "delta", fontWeight: "bold", children: "Monitor interval" }),
4898
4964
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { paddingTop: 2, paddingBottom: 3, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Typography, { variant: "omega", textColor: "neutral600", children: [
4899
4965
  "Your monitor will be checked every ",
4900
4966
  /* @__PURE__ */ jsxRuntime.jsx("strong", { children: format(effectiveValue) }),
@@ -4941,7 +5007,7 @@ function MonitorIntervalSlider({
4941
5007
  style: {
4942
5008
  left: `${pos}%`,
4943
5009
  transform: "translateX(-50%)",
4944
- fontSize: 11,
5010
+ fontSize: 10,
4945
5011
  color: disabled ? "#C0C0CF" : "#666687",
4946
5012
  cursor: disabled ? "not-allowed" : "default"
4947
5013
  },
@@ -4992,7 +5058,7 @@ function IntervalSlider({
4992
5058
  const safeValue = Math.max(value, minAllowedSeconds);
4993
5059
  const sliderPercent = secondsToSlider(safeValue);
4994
5060
  return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { width: "100%", children: [
4995
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", fontWeight: "bold", children: "Monitor interval" }),
5061
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "delta", fontWeight: "bold", children: "Monitor interval" }),
4996
5062
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { paddingTop: 2, paddingBottom: 3, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Typography, { variant: "omega", textColor: "neutral600", children: [
4997
5063
  "Your monitor will be checked every ",
4998
5064
  /* @__PURE__ */ jsxRuntime.jsx("strong", { children: formatSeconds(safeValue) }),
@@ -5152,7 +5218,7 @@ function AdvancedSettings({
5152
5218
  }
5153
5219
  fetchUser();
5154
5220
  }, []);
5155
- const getPercent = (value) => (value - 6) / 55 * 100;
5221
+ const getPercent = (value) => (value - 5) / 55 * 100;
5156
5222
  return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { width: "100%", children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Accordion.Root, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Accordion.Item, { value: "advanced-settings", children: [
5157
5223
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Accordion.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(
5158
5224
  designSystem.Accordion.Trigger,
@@ -5163,7 +5229,7 @@ function AdvancedSettings({
5163
5229
  }
5164
5230
  ) }),
5165
5231
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Accordion.Content, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { padding: 4, direction: "column", gap: 6, width: "100%", alignItems: "flex-start", children: [
5166
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { maxWidth: "60%", children: [
5232
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { maxWidth: "60%", paddingLeft: 4, children: [
5167
5233
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "beta", fontWeight: "bold", children: "Request timeout" }),
5168
5234
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { paddingTop: 2, paddingBottom: 3, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Typography, { variant: "omega", textColor: "neutral600", children: [
5169
5235
  "The request timeout is ",
@@ -5216,7 +5282,7 @@ function AdvancedSettings({
5216
5282
  value
5217
5283
  )) })
5218
5284
  ] }),
5219
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { children: [
5285
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { paddingLeft: 6, children: [
5220
5286
  /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { alignItems: "center", gap: 3, children: [
5221
5287
  /* @__PURE__ */ jsxRuntime.jsx(
5222
5288
  designSystem.Switch,
@@ -5227,12 +5293,12 @@ function AdvancedSettings({
5227
5293
  }
5228
5294
  }
5229
5295
  ),
5230
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "beta", fontWeight: "bold", children: "Follow redirection" })
5296
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "delta", fontWeight: "bold", children: "Follow redirection" })
5231
5297
  ] }),
5232
5298
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { paddingTop: 1, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", textColor: "neutral600", children: "If disabled, we return redirection HTTP codes (3xx)." }) })
5233
5299
  ] }),
5234
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { width: "100%", children: [
5235
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "alpha", fontWeight: "bold", children: "Healthcheck settings" }),
5300
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { width: "100%", paddingLeft: 5, children: [
5301
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "beta", fontWeight: "bold", children: "Healthcheck settings" }),
5236
5302
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { paddingTop: 4, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 6, wrap: "wrap", direction: { initial: "column", medium: "row" }, children: [
5237
5303
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { width: { initial: "100%", medium: "48%" }, children: /* @__PURE__ */ jsxRuntime.jsx(
5238
5304
  HealthcheckServiceBlock,
@@ -5533,67 +5599,51 @@ function NotificationChannelsIntegration({
5533
5599
  ] }) }) })
5534
5600
  ] }) }) });
5535
5601
  }
5536
- const RegionsMultiSelect = ({
5537
- selectedRegionIds,
5538
- onRegionsChange,
5539
- placeholder = "Select regions...",
5540
- primaryRegionId,
5541
- onPrimaryRegionChange
5602
+ const TagMultiSelect = ({
5603
+ selectedTagIds,
5604
+ onTagsChange,
5605
+ placeholder = "Select or create tags...",
5606
+ apiEndpoint = "/tags"
5542
5607
  }) => {
5543
5608
  const [isOpen, setIsOpen] = React.useState(false);
5544
5609
  const [searchInput, setSearchInput] = React.useState("");
5545
- const [availableRegions, setAvailableRegions] = React.useState([]);
5610
+ const [availableTags, setAvailableTags] = React.useState([]);
5546
5611
  const [isLoading, setIsLoading] = React.useState(false);
5547
- const [isTrialUser, setIsTrialUser] = React.useState(false);
5612
+ const [isCreating, setIsCreating] = React.useState(false);
5548
5613
  const dropdownRef = React.useRef(null);
5549
5614
  const inputRef = React.useRef(null);
5550
5615
  React.useEffect(() => {
5551
- fetchRegions();
5616
+ fetchTags(setIsLoading, setAvailableTags);
5552
5617
  }, []);
5553
- const fetchRegions = async () => {
5554
- setIsLoading(true);
5618
+ const createTag = async (tagName) => {
5619
+ setIsCreating(true);
5555
5620
  try {
5556
- let userDetails = await getUserDetailsCached();
5557
- if (!userDetails) {
5558
- userDetails = await getUserDetails();
5559
- }
5560
- const isTrial = userDetails?.user?.subscription_type === PLAN_TYPES.TRIAL;
5561
- setIsTrialUser(isTrial);
5562
- const result = await request("/regions", {
5563
- method: "GET"
5621
+ const result = await request(apiEndpoint, {
5622
+ method: "POST",
5623
+ data: {
5624
+ name: tagName,
5625
+ color: generateRandomColor()
5626
+ }
5564
5627
  });
5565
- if (!result) return;
5566
- if (!result) {
5567
- throw new Error("Failed to fetch regions");
5568
- }
5569
- const regions = result.regionsData.data.slice();
5570
- const defaultIndex = regions.findIndex((r) => r.id === DEFAULT_REGION.id);
5571
- if (defaultIndex > 0) {
5572
- const [defaultRegion] = regions.splice(defaultIndex, 1);
5573
- regions.unshift(defaultRegion);
5574
- }
5575
- setAvailableRegions(regions);
5628
+ if (!result?.tagsData) return null;
5629
+ const newTag = result?.tagsData?.data;
5630
+ setAvailableTags((prev) => [...prev, newTag]);
5631
+ return newTag;
5576
5632
  } catch (error) {
5577
- console.error("Error fetching regions:", error);
5633
+ console.error("Error creating tag:", error);
5634
+ return null;
5578
5635
  } finally {
5579
- setIsLoading(false);
5636
+ setIsCreating(false);
5580
5637
  }
5581
5638
  };
5582
- const selectedRegions = availableRegions.filter(
5583
- (region) => selectedRegionIds.includes(String(region.id))
5639
+ const selectedTags = availableTags.filter((tag) => selectedTagIds.includes(String(tag.id)));
5640
+ const filteredTags = availableTags.filter(
5641
+ (tag) => tag.name.toLowerCase().includes(searchInput.toLowerCase())
5584
5642
  );
5585
- const filteredRegions = availableRegions.filter(
5586
- (region) => region.name.toLowerCase().includes(searchInput.toLowerCase())
5643
+ const exactMatch = availableTags.find(
5644
+ (tag) => tag.name.toLowerCase() === searchInput.toLowerCase()
5587
5645
  );
5588
- const handleSetPrimary = (regionId) => {
5589
- if (isTrialUser && regionId !== DEFAULT_REGION.id) {
5590
- return;
5591
- }
5592
- if (!selectedRegionIds.includes(regionId)) {
5593
- onRegionsChange([...selectedRegionIds, regionId]);
5594
- }
5595
- onPrimaryRegionChange?.(regionId);
5596
- };
5646
+ const showCreateOption = searchInput.trim() && !exactMatch;
5597
5647
  React.useEffect(() => {
5598
5648
  const handleClickOutside = (event) => {
5599
5649
  if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
@@ -5604,41 +5654,46 @@ const RegionsMultiSelect = ({
5604
5654
  document.addEventListener("mousedown", handleClickOutside);
5605
5655
  return () => document.removeEventListener("mousedown", handleClickOutside);
5606
5656
  }, []);
5607
- const handleToggleRegion = (regionId) => {
5608
- if (isTrialUser && regionId !== DEFAULT_REGION.id) {
5609
- return;
5610
- }
5611
- if (selectedRegionIds.includes(regionId)) {
5612
- const updated = selectedRegionIds.filter((id) => id !== regionId);
5613
- onRegionsChange(updated);
5614
- if (primaryRegionId === regionId) {
5615
- onPrimaryRegionChange?.(updated[0] ?? null);
5616
- }
5657
+ const handleToggleTag = (tagId) => {
5658
+ const idStr = String(tagId);
5659
+ if (selectedTagIds.includes(idStr)) {
5660
+ onTagsChange(selectedTagIds.filter((id) => id !== idStr));
5617
5661
  } else {
5618
- onRegionsChange([...selectedRegionIds, regionId]);
5662
+ onTagsChange([...selectedTagIds, idStr]);
5619
5663
  }
5620
5664
  };
5621
- const handleRemoveRegion = (regionId, e) => {
5665
+ const handleRemoveTag = (tagId, e) => {
5622
5666
  e?.stopPropagation();
5623
- const updated = selectedRegionIds.filter((id) => id !== regionId);
5624
- onRegionsChange(updated);
5625
- if (primaryRegionId === regionId) {
5626
- onPrimaryRegionChange?.(updated[0] ?? null);
5667
+ const idStr = String(tagId);
5668
+ onTagsChange(selectedTagIds.filter((id) => id !== idStr));
5669
+ };
5670
+ const handleCreateTag = async () => {
5671
+ if (!searchInput.trim() || isCreating) return;
5672
+ const newTag = await createTag(searchInput.trim());
5673
+ if (newTag) {
5674
+ onTagsChange([...selectedTagIds, String(newTag.id)]);
5675
+ setSearchInput("");
5676
+ inputRef.current?.focus();
5627
5677
  }
5628
5678
  };
5629
5679
  const handleKeyDown = (e) => {
5630
- if (e.key === "Enter" && filteredRegions.length === 1) {
5631
- handleToggleRegion(filteredRegions[0].id);
5632
- setSearchInput("");
5633
- } else if (e.key === "Backspace" && !searchInput && selectedRegions.length > 0) {
5634
- handleRemoveRegion(selectedRegions[selectedRegions.length - 1].id);
5680
+ if (e.key === "Enter") {
5681
+ e.preventDefault();
5682
+ if (showCreateOption) {
5683
+ handleCreateTag();
5684
+ } else if (filteredTags.length === 1) {
5685
+ handleToggleTag(filteredTags[0].id);
5686
+ setSearchInput("");
5687
+ }
5688
+ } else if (e.key === "Backspace" && !searchInput && selectedTags.length > 0) {
5689
+ handleRemoveTag(selectedTags[selectedTags.length - 1].id);
5635
5690
  }
5636
5691
  };
5637
5692
  return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { position: "relative", ref: dropdownRef, width: "100%", children: [
5638
5693
  /* @__PURE__ */ jsxRuntime.jsx(
5639
5694
  designSystem.Box,
5640
5695
  {
5641
- padding: 3,
5696
+ padding: 2,
5642
5697
  borderColor: isOpen ? "primary200" : "neutral200",
5643
5698
  background: "neutral0",
5644
5699
  hasRadius: true,
@@ -5650,39 +5705,291 @@ const RegionsMultiSelect = ({
5650
5705
  width: "100%",
5651
5706
  children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { alignItems: "center", gap: 2, width: "100%", children: [
5652
5707
  /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { wrap: "wrap", gap: 2, flex: "1", width: "100%", children: [
5653
- selectedRegions.map((region) => {
5654
- const isPrimary = primaryRegionId === region.id;
5655
- return /* @__PURE__ */ jsxRuntime.jsxs(
5656
- designSystem.Flex,
5657
- {
5658
- gap: 1,
5659
- padding: 1,
5660
- background: "primary100",
5661
- borderColor: "primary200",
5662
- hasRadius: true,
5663
- alignItems: "center",
5664
- children: [
5665
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "semiBold", textColor: "primary700", children: region.name || region.id }),
5666
- isPrimary && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Badge, { background: "warning100", textColor: "warning700", children: "Primary" }),
5667
- /* @__PURE__ */ jsxRuntime.jsx(
5668
- designSystem.IconButton,
5669
- {
5670
- label: "Remove region",
5671
- onClick: (e) => handleRemoveRegion(region.id, e),
5672
- size: "S",
5673
- variant: "ghost",
5674
- children: /* @__PURE__ */ jsxRuntime.jsx(icons.Cross, {})
5675
- }
5676
- )
5677
- ]
5678
- },
5679
- region.id
5680
- );
5681
- }),
5682
- isOpen && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { width: "70%", children: /* @__PURE__ */ jsxRuntime.jsx(
5683
- designSystem.TextInput,
5708
+ selectedTags.map((tag) => /* @__PURE__ */ jsxRuntime.jsxs(
5709
+ designSystem.Flex,
5684
5710
  {
5685
- ref: inputRef,
5711
+ gap: 1,
5712
+ padding: 1,
5713
+ hasRadius: true,
5714
+ alignItems: "center",
5715
+ style: {
5716
+ backgroundColor: `${tag.color}20`,
5717
+ border: `1px solid ${tag.color}40`
5718
+ },
5719
+ children: [
5720
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "semiBold", style: { color: tag.color }, children: formatTitleToUppercase(tag.name) }),
5721
+ /* @__PURE__ */ jsxRuntime.jsx(
5722
+ designSystem.IconButton,
5723
+ {
5724
+ label: "Remove tag",
5725
+ onClick: (e) => handleRemoveTag(tag.id, e),
5726
+ size: "S",
5727
+ variant: "ghost",
5728
+ children: /* @__PURE__ */ jsxRuntime.jsx(icons.Cross, {})
5729
+ }
5730
+ )
5731
+ ]
5732
+ },
5733
+ tag.id
5734
+ )),
5735
+ isOpen && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { width: "70%", children: /* @__PURE__ */ jsxRuntime.jsx(
5736
+ designSystem.TextInput,
5737
+ {
5738
+ ref: inputRef,
5739
+ value: searchInput,
5740
+ onChange: (e) => setSearchInput(e.target.value),
5741
+ onKeyDown: handleKeyDown,
5742
+ onFocus: () => setIsOpen(true),
5743
+ placeholder: selectedTags.length === 0 ? placeholder : "",
5744
+ disabled: isLoading,
5745
+ startAction: /* @__PURE__ */ jsxRuntime.jsx(icons.Search, {}),
5746
+ size: "M"
5747
+ }
5748
+ ) })
5749
+ ] }),
5750
+ /* @__PURE__ */ jsxRuntime.jsx(
5751
+ designSystem.IconButton,
5752
+ {
5753
+ label: "Toggle dropdown",
5754
+ onClick: (e) => {
5755
+ e.stopPropagation();
5756
+ setIsOpen(!isOpen);
5757
+ },
5758
+ variant: "ghost",
5759
+ children: /* @__PURE__ */ jsxRuntime.jsx(icons.ChevronDown, {})
5760
+ }
5761
+ )
5762
+ ] })
5763
+ }
5764
+ ),
5765
+ isOpen && /* @__PURE__ */ jsxRuntime.jsx(
5766
+ designSystem.Box,
5767
+ {
5768
+ position: "absolute",
5769
+ zIndex: 2,
5770
+ width: "100%",
5771
+ marginTop: 2,
5772
+ background: "neutral0",
5773
+ borderColor: "neutral200",
5774
+ hasRadius: true,
5775
+ shadow: "tableShadow",
5776
+ maxHeight: "240px",
5777
+ overflow: "auto",
5778
+ children: isLoading ? /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { padding: 4, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textAlign: "center", textColor: "neutral500", children: "Loading tags…" }) }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
5779
+ filteredTags.length > 0 ? filteredTags.map((tag) => {
5780
+ const isSelected = selectedTagIds.includes(String(tag.id));
5781
+ return /* @__PURE__ */ jsxRuntime.jsxs(
5782
+ designSystem.Flex,
5783
+ {
5784
+ padding: 3,
5785
+ gap: 3,
5786
+ alignItems: "center",
5787
+ background: isSelected ? "primary100" : "neutral0",
5788
+ style: { cursor: "pointer" },
5789
+ onClick: () => handleToggleTag(tag.id),
5790
+ children: [
5791
+ /* @__PURE__ */ jsxRuntime.jsx(
5792
+ designSystem.Checkbox,
5793
+ {
5794
+ checked: isSelected,
5795
+ onCheckedChange: () => handleToggleTag(tag.id)
5796
+ }
5797
+ ),
5798
+ /* @__PURE__ */ jsxRuntime.jsx(
5799
+ "div",
5800
+ {
5801
+ style: {
5802
+ width: "12px",
5803
+ height: "12px",
5804
+ borderRadius: "50%",
5805
+ backgroundColor: tag.color
5806
+ }
5807
+ }
5808
+ ),
5809
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { flex: "1", children: formatTitleToUppercase(tag.name) })
5810
+ ]
5811
+ },
5812
+ tag.id
5813
+ );
5814
+ }) : searchInput ? /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { padding: 4, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textAlign: "center", textColor: "neutral500", children: "No tags found" }) }) : null,
5815
+ showCreateOption && /* @__PURE__ */ jsxRuntime.jsx(
5816
+ designSystem.Box,
5817
+ {
5818
+ style: {
5819
+ borderTop: "1px solid #D0D3E0"
5820
+ },
5821
+ children: /* @__PURE__ */ jsxRuntime.jsx(
5822
+ designSystem.Button,
5823
+ {
5824
+ variant: "ghost",
5825
+ fullWidth: true,
5826
+ onClick: handleCreateTag,
5827
+ disabled: isCreating,
5828
+ startIcon: /* @__PURE__ */ jsxRuntime.jsx(icons.Plus, {}),
5829
+ style: {
5830
+ justifyContent: "flex-start",
5831
+ padding: "12px 16px"
5832
+ },
5833
+ children: isCreating ? "Creating..." : `Create "${searchInput}"`
5834
+ }
5835
+ )
5836
+ }
5837
+ )
5838
+ ] })
5839
+ }
5840
+ )
5841
+ ] });
5842
+ };
5843
+ const RegionsMultiSelect = ({
5844
+ selectedRegionIds,
5845
+ onRegionsChange,
5846
+ placeholder = "Select regions...",
5847
+ primaryRegionId,
5848
+ onPrimaryRegionChange
5849
+ }) => {
5850
+ const [isOpen, setIsOpen] = React.useState(false);
5851
+ const [searchInput, setSearchInput] = React.useState("");
5852
+ const [availableRegions, setAvailableRegions] = React.useState([]);
5853
+ const [isLoading, setIsLoading] = React.useState(false);
5854
+ const [isTrialUser, setIsTrialUser] = React.useState(false);
5855
+ const dropdownRef = React.useRef(null);
5856
+ const inputRef = React.useRef(null);
5857
+ React.useEffect(() => {
5858
+ fetchRegions();
5859
+ }, []);
5860
+ const fetchRegions = async () => {
5861
+ setIsLoading(true);
5862
+ try {
5863
+ let userDetails = await getUserDetailsCached();
5864
+ if (!userDetails) {
5865
+ userDetails = await getUserDetails();
5866
+ }
5867
+ const isTrial = userDetails?.user?.subscription_type === PLAN_TYPES.TRIAL;
5868
+ setIsTrialUser(isTrial);
5869
+ const result = await request("/regions", {
5870
+ method: "GET"
5871
+ });
5872
+ if (!result) return;
5873
+ if (!result) {
5874
+ throw new Error("Failed to fetch regions");
5875
+ }
5876
+ const regions = result.regionsData.data.slice();
5877
+ const defaultIndex = regions.findIndex((r) => r.id === DEFAULT_REGION.id);
5878
+ if (defaultIndex > 0) {
5879
+ const [defaultRegion] = regions.splice(defaultIndex, 1);
5880
+ regions.unshift(defaultRegion);
5881
+ }
5882
+ setAvailableRegions(regions);
5883
+ } catch (error) {
5884
+ console.error("Error fetching regions:", error);
5885
+ } finally {
5886
+ setIsLoading(false);
5887
+ }
5888
+ };
5889
+ const selectedRegions = availableRegions.filter(
5890
+ (region) => selectedRegionIds.includes(String(region.id))
5891
+ );
5892
+ const filteredRegions = availableRegions.filter(
5893
+ (region) => region.name.toLowerCase().includes(searchInput.toLowerCase())
5894
+ );
5895
+ const handleSetPrimary = (regionId) => {
5896
+ if (isTrialUser && regionId !== DEFAULT_REGION.id) {
5897
+ return;
5898
+ }
5899
+ if (!selectedRegionIds.includes(regionId)) {
5900
+ onRegionsChange([...selectedRegionIds, regionId]);
5901
+ }
5902
+ onPrimaryRegionChange?.(regionId);
5903
+ };
5904
+ React.useEffect(() => {
5905
+ const handleClickOutside = (event) => {
5906
+ if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
5907
+ setIsOpen(false);
5908
+ setSearchInput("");
5909
+ }
5910
+ };
5911
+ document.addEventListener("mousedown", handleClickOutside);
5912
+ return () => document.removeEventListener("mousedown", handleClickOutside);
5913
+ }, []);
5914
+ const handleToggleRegion = (regionId) => {
5915
+ if (isTrialUser && regionId !== DEFAULT_REGION.id) {
5916
+ return;
5917
+ }
5918
+ if (selectedRegionIds.includes(regionId)) {
5919
+ const updated = selectedRegionIds.filter((id) => id !== regionId);
5920
+ onRegionsChange(updated);
5921
+ if (primaryRegionId === regionId) {
5922
+ onPrimaryRegionChange?.(updated[0] ?? null);
5923
+ }
5924
+ } else {
5925
+ onRegionsChange([...selectedRegionIds, regionId]);
5926
+ }
5927
+ };
5928
+ const handleRemoveRegion = (regionId, e) => {
5929
+ e?.stopPropagation();
5930
+ const updated = selectedRegionIds.filter((id) => id !== regionId);
5931
+ onRegionsChange(updated);
5932
+ if (primaryRegionId === regionId) {
5933
+ onPrimaryRegionChange?.(updated[0] ?? null);
5934
+ }
5935
+ };
5936
+ const handleKeyDown = (e) => {
5937
+ if (e.key === "Enter" && filteredRegions.length === 1) {
5938
+ handleToggleRegion(filteredRegions[0].id);
5939
+ setSearchInput("");
5940
+ } else if (e.key === "Backspace" && !searchInput && selectedRegions.length > 0) {
5941
+ handleRemoveRegion(selectedRegions[selectedRegions.length - 1].id);
5942
+ }
5943
+ };
5944
+ return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { position: "relative", ref: dropdownRef, width: "100%", children: [
5945
+ /* @__PURE__ */ jsxRuntime.jsx(
5946
+ designSystem.Box,
5947
+ {
5948
+ padding: 3,
5949
+ borderColor: isOpen ? "primary200" : "neutral200",
5950
+ background: "neutral0",
5951
+ hasRadius: true,
5952
+ style: { cursor: "text" },
5953
+ onClick: () => {
5954
+ setIsOpen(true);
5955
+ inputRef.current?.focus();
5956
+ },
5957
+ width: "100%",
5958
+ children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { alignItems: "center", gap: 2, width: "100%", children: [
5959
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { wrap: "wrap", gap: 2, flex: "1", width: "100%", children: [
5960
+ selectedRegions.map((region) => {
5961
+ const isPrimary = primaryRegionId === region.id;
5962
+ return /* @__PURE__ */ jsxRuntime.jsxs(
5963
+ designSystem.Flex,
5964
+ {
5965
+ gap: 1,
5966
+ padding: 1,
5967
+ background: "primary100",
5968
+ borderColor: "primary200",
5969
+ hasRadius: true,
5970
+ alignItems: "center",
5971
+ children: [
5972
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "semiBold", textColor: "primary700", children: region.name || region.id }),
5973
+ isPrimary && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Badge, { background: "warning100", textColor: "warning700", children: "Primary" }),
5974
+ /* @__PURE__ */ jsxRuntime.jsx(
5975
+ designSystem.IconButton,
5976
+ {
5977
+ label: "Remove region",
5978
+ onClick: (e) => handleRemoveRegion(region.id, e),
5979
+ size: "S",
5980
+ variant: "ghost",
5981
+ children: /* @__PURE__ */ jsxRuntime.jsx(icons.Cross, {})
5982
+ }
5983
+ )
5984
+ ]
5985
+ },
5986
+ region.id
5987
+ );
5988
+ }),
5989
+ isOpen && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { width: "70%", children: /* @__PURE__ */ jsxRuntime.jsx(
5990
+ designSystem.TextInput,
5991
+ {
5992
+ ref: inputRef,
5686
5993
  value: searchInput,
5687
5994
  onChange: (e) => setSearchInput(e.target.value),
5688
5995
  onKeyDown: handleKeyDown,
@@ -5692,98 +5999,524 @@ const RegionsMultiSelect = ({
5692
5999
  startAction: /* @__PURE__ */ jsxRuntime.jsx(icons.Search, {}),
5693
6000
  size: "M"
5694
6001
  }
5695
- ) })
5696
- ] }),
5697
- /* @__PURE__ */ jsxRuntime.jsx(
5698
- designSystem.IconButton,
5699
- {
5700
- label: "Toggle dropdown",
5701
- onClick: (e) => {
5702
- e.stopPropagation();
5703
- setIsOpen(!isOpen);
5704
- },
5705
- variant: "ghost",
5706
- children: /* @__PURE__ */ jsxRuntime.jsx(icons.ChevronDown, {})
5707
- }
5708
- )
5709
- ] })
6002
+ ) })
6003
+ ] }),
6004
+ /* @__PURE__ */ jsxRuntime.jsx(
6005
+ designSystem.IconButton,
6006
+ {
6007
+ label: "Toggle dropdown",
6008
+ onClick: (e) => {
6009
+ e.stopPropagation();
6010
+ setIsOpen(!isOpen);
6011
+ },
6012
+ variant: "ghost",
6013
+ children: /* @__PURE__ */ jsxRuntime.jsx(icons.ChevronDown, {})
6014
+ }
6015
+ )
6016
+ ] })
6017
+ }
6018
+ ),
6019
+ isOpen && /* @__PURE__ */ jsxRuntime.jsx(
6020
+ designSystem.Box,
6021
+ {
6022
+ position: "absolute",
6023
+ zIndex: 2,
6024
+ width: "100%",
6025
+ marginTop: 2,
6026
+ background: "neutral0",
6027
+ borderColor: "neutral200",
6028
+ hasRadius: true,
6029
+ shadow: "tableShadow",
6030
+ maxHeight: "240px",
6031
+ overflow: "auto",
6032
+ children: isLoading ? /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { padding: 4, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textAlign: "center", textColor: "neutral500", children: "Loading regions…" }) }) : /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: filteredRegions.length > 0 ? filteredRegions.map((region) => {
6033
+ const isSelected = selectedRegionIds.includes(String(region.id));
6034
+ const isPrimary = primaryRegionId === region.id;
6035
+ const isDisabled = isTrialUser && region.id !== DEFAULT_REGION.id;
6036
+ return isDisabled ? /* @__PURE__ */ jsxRuntime.jsx(
6037
+ designSystem.Tooltip,
6038
+ {
6039
+ description: "Upgrade to a paid plan to enable global monitoring.",
6040
+ children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { children: /* @__PURE__ */ jsxRuntime.jsxs(
6041
+ designSystem.Flex,
6042
+ {
6043
+ padding: 3,
6044
+ gap: 3,
6045
+ alignItems: "center",
6046
+ background: isSelected ? "primary100" : "neutral0",
6047
+ style: {
6048
+ cursor: "not-allowed",
6049
+ opacity: 0.5
6050
+ },
6051
+ children: [
6052
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Checkbox, { checked: isSelected, disabled: true }),
6053
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { flex: "1", children: region.name || region.id }),
6054
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Checkbox, { checked: isPrimary, disabled: true, children: "Primary" })
6055
+ ]
6056
+ }
6057
+ ) })
6058
+ },
6059
+ region.id
6060
+ ) : /* @__PURE__ */ jsxRuntime.jsxs(
6061
+ designSystem.Flex,
6062
+ {
6063
+ padding: 3,
6064
+ gap: 3,
6065
+ alignItems: "center",
6066
+ background: isSelected ? "primary100" : "neutral0",
6067
+ style: { cursor: "pointer" },
6068
+ children: [
6069
+ /* @__PURE__ */ jsxRuntime.jsx(
6070
+ designSystem.Checkbox,
6071
+ {
6072
+ checked: isSelected,
6073
+ onChange: () => handleToggleRegion(region.id)
6074
+ }
6075
+ ),
6076
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { flex: "1", children: region.name || region.id }),
6077
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Checkbox, { checked: isPrimary, onChange: () => handleSetPrimary(region.id), children: "Primary" })
6078
+ ]
6079
+ },
6080
+ region.id
6081
+ );
6082
+ }) : searchInput ? /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { padding: 4, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textAlign: "center", textColor: "neutral500", children: "No regions found" }) }) : null })
6083
+ }
6084
+ )
6085
+ ] });
6086
+ };
6087
+ function PortAdvancedSettings({
6088
+ timeout,
6089
+ onTimeoutChange,
6090
+ monitorInterval,
6091
+ onMonitorIntervalChange
6092
+ }) {
6093
+ const min = 5;
6094
+ const max = 60;
6095
+ const [minMonitoringInterval, setMinMonitoringInterval] = React.useState(60);
6096
+ const [userPlan, setUserPlan] = React.useState(PLAN_TYPES.TRIAL);
6097
+ React.useEffect(() => {
6098
+ async function fetchUser() {
6099
+ try {
6100
+ const details = await getUserDetailsCached(true);
6101
+ const userMinMonitoringIntervalInMins = details?.plan_limits?.min_monitoring_interval;
6102
+ setMinMonitoringInterval(
6103
+ userMinMonitoringIntervalInMins ? userMinMonitoringIntervalInMins * 60 : 60
6104
+ );
6105
+ setUserPlan(details?.user?.subscription_type || PLAN_TYPES.TRIAL);
6106
+ } catch (error) {
6107
+ console.error("Failed to fetch user details in PortAdvancedSettings", error);
6108
+ }
6109
+ }
6110
+ fetchUser();
6111
+ }, []);
6112
+ const getPercent = (value) => (value - min) / (max - min) * 100;
6113
+ return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { width: "100%", children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Accordion.Root, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Accordion.Item, { value: "port-advanced-settings", children: [
6114
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Accordion.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(
6115
+ designSystem.Accordion.Trigger,
6116
+ {
6117
+ caretPosition: "right",
6118
+ description: "Configure monitor interval and connection timeout",
6119
+ children: "Advanced settings"
6120
+ }
6121
+ ) }),
6122
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Accordion.Content, { children: /* @__PURE__ */ jsxRuntime.jsx(
6123
+ designSystem.Flex,
6124
+ {
6125
+ paddingLeft: 6,
6126
+ paddingTop: 4,
6127
+ paddingBottom: 8,
6128
+ direction: "column",
6129
+ gap: 6,
6130
+ width: "100%",
6131
+ alignItems: "flex-start",
6132
+ children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: { initial: "column", medium: "row" }, gap: 6, width: "100%", children: [
6133
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { width: { initial: "100%", medium: "48%" }, children: /* @__PURE__ */ jsxRuntime.jsx(
6134
+ MonitorIntervalSlider,
6135
+ {
6136
+ value: monitorInterval,
6137
+ onChange: onMonitorIntervalChange,
6138
+ minSeconds: 60,
6139
+ maxSeconds: 86400,
6140
+ minMonitoringInterval,
6141
+ userPlan
6142
+ }
6143
+ ) }),
6144
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { width: { initial: "100%", medium: "48%" }, children: [
6145
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "beta", fontWeight: "bold", children: "Connection timeout" }),
6146
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { paddingTop: 2, paddingBottom: 3, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Typography, { variant: "omega", textColor: "neutral600", children: [
6147
+ "The connection timeout is ",
6148
+ /* @__PURE__ */ jsxRuntime.jsxs("strong", { children: [
6149
+ timeout,
6150
+ " seconds"
6151
+ ] }),
6152
+ "."
6153
+ ] }) }),
6154
+ /* @__PURE__ */ jsxRuntime.jsx(
6155
+ "input",
6156
+ {
6157
+ type: "range",
6158
+ min,
6159
+ max,
6160
+ step: "1",
6161
+ value: timeout,
6162
+ onChange: (e) => onTimeoutChange(parseInt(e.target.value)),
6163
+ style: {
6164
+ width: "100%",
6165
+ height: 6,
6166
+ borderRadius: 4,
6167
+ appearance: "none",
6168
+ cursor: "pointer",
6169
+ background: `linear-gradient(
6170
+ to right,
6171
+ #4945FF 0%,
6172
+ #4945FF ${getPercent(timeout)}%,
6173
+ #EAEAEA ${getPercent(timeout)}%,
6174
+ #EAEAEA 100%
6175
+ )`
6176
+ }
6177
+ }
6178
+ ),
6179
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { position: "relative", paddingTop: 3, height: 20, children: [5, 15, 30, 45, 60].map((value) => /* @__PURE__ */ jsxRuntime.jsxs(
6180
+ designSystem.Box,
6181
+ {
6182
+ position: "absolute",
6183
+ style: {
6184
+ left: `${getPercent(value)}%`,
6185
+ transform: "translateX(-50%)",
6186
+ fontSize: 10,
6187
+ color: "#666687"
6188
+ },
6189
+ children: [
6190
+ value,
6191
+ "s"
6192
+ ]
6193
+ },
6194
+ value
6195
+ )) })
6196
+ ] })
6197
+ ] })
6198
+ }
6199
+ ) })
6200
+ ] }) }) });
6201
+ }
6202
+ function KeywordInput({
6203
+ keywords,
6204
+ onKeywordsChange,
6205
+ error,
6206
+ matchAll,
6207
+ onMatchAllChange
6208
+ }) {
6209
+ const [keywordInput, setKeywordInput] = React.useState("");
6210
+ const handleAddKeyword = () => {
6211
+ const trimmedInput = keywordInput.trim();
6212
+ if (!trimmedInput) return;
6213
+ const newKeyword = {
6214
+ text: trimmedInput,
6215
+ type: "must_contain",
6216
+ case_sensitive: false,
6217
+ is_regex: false
6218
+ };
6219
+ onKeywordsChange([...keywords, newKeyword]);
6220
+ setKeywordInput("");
6221
+ };
6222
+ const handleRemoveKeyword = (indexToRemove) => {
6223
+ onKeywordsChange(keywords.filter((_, index) => index !== indexToRemove));
6224
+ };
6225
+ const handleKeywordChange = (index, field, value) => {
6226
+ const updatedKeywords = [...keywords];
6227
+ updatedKeywords[index] = {
6228
+ ...updatedKeywords[index],
6229
+ [field]: value
6230
+ };
6231
+ onKeywordsChange(updatedKeywords);
6232
+ };
6233
+ const handleKeyPress = (e) => {
6234
+ if (e.key === "Enter") {
6235
+ e.preventDefault();
6236
+ handleAddKeyword();
6237
+ }
6238
+ };
6239
+ return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { width: "100%", children: [
6240
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { marginBottom: 4, children: [
6241
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { alignItems: "center", justifyContent: "space-between", marginBottom: 2, children: [
6242
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "beta", fontWeight: "bold", children: "Keywords / Text" }),
6243
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { alignItems: "center", gap: 3, children: [
6244
+ /* @__PURE__ */ jsxRuntime.jsx(
6245
+ designSystem.Switch,
6246
+ {
6247
+ checked: matchAll,
6248
+ onCheckedChange: (checked) => onMatchAllChange(checked)
6249
+ }
6250
+ ),
6251
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", fontWeight: "500", children: "Match All Keywords" })
6252
+ ] })
6253
+ ] }),
6254
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 2, children: [
6255
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { flex: 1, children: /* @__PURE__ */ jsxRuntime.jsx(
6256
+ designSystem.TextInput,
6257
+ {
6258
+ type: "text",
6259
+ placeholder: "Enter keyword",
6260
+ value: keywordInput,
6261
+ onChange: (e) => setKeywordInput(e.target.value),
6262
+ onKeyDown: handleKeyPress
6263
+ }
6264
+ ) }),
6265
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { disabled: !keywordInput.trim(), onClick: handleAddKeyword, children: "Add" })
6266
+ ] }),
6267
+ error && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { marginTop: 2, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", textColor: "danger600", children: error }) })
6268
+ ] }),
6269
+ keywords.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { children: [
6270
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { paddingBottom: 3, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Typography, { variant: "beta", fontWeight: "bold", marginBottom: 3, children: [
6271
+ "Added Keywords (",
6272
+ keywords.length,
6273
+ ")"
6274
+ ] }) }),
6275
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { direction: "column", gap: 2, width: "800px", children: keywords.map((keyword, index) => /* @__PURE__ */ jsxRuntime.jsxs(
6276
+ designSystem.Box,
6277
+ {
6278
+ padding: 4,
6279
+ borderColor: "neutral200",
6280
+ hasRadius: true,
6281
+ borderRadius: 2,
6282
+ width: "800px",
6283
+ children: [
6284
+ /* @__PURE__ */ jsxRuntime.jsxs(
6285
+ designSystem.Flex,
6286
+ {
6287
+ alignItems: "flex-start",
6288
+ justifyContent: "space-between",
6289
+ gap: 3,
6290
+ marginBottom: 4,
6291
+ children: [
6292
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { children: [
6293
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { paddingBottom: 2, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", textColor: "neutral600", marginBottom: 1, children: "Keyword" }) }),
6294
+ /* @__PURE__ */ jsxRuntime.jsx(
6295
+ designSystem.Box,
6296
+ {
6297
+ style: {
6298
+ fontFamily: "monospace",
6299
+ fontSize: "14px",
6300
+ backgroundColor: "#F2F4F7",
6301
+ padding: "6px 12px",
6302
+ borderRadius: "4px",
6303
+ color: "#32324D",
6304
+ wordBreak: "break-all"
6305
+ },
6306
+ children: keyword.text
6307
+ }
6308
+ )
6309
+ ] }),
6310
+ /* @__PURE__ */ jsxRuntime.jsx(
6311
+ designSystem.Button,
6312
+ {
6313
+ style: {
6314
+ padding: "0",
6315
+ minWidth: "32px",
6316
+ width: "32px",
6317
+ height: "32px"
6318
+ },
6319
+ variant: "tertiary",
6320
+ onClick: () => handleRemoveKeyword(index),
6321
+ title: "Remove keyword",
6322
+ children: /* @__PURE__ */ jsxRuntime.jsx(icons.Trash, {})
6323
+ }
6324
+ )
6325
+ ]
6326
+ }
6327
+ ),
6328
+ /* @__PURE__ */ jsxRuntime.jsxs(
6329
+ designSystem.Flex,
6330
+ {
6331
+ direction: { initial: "column", medium: "row" },
6332
+ gap: 5,
6333
+ alignItems: "flex-end",
6334
+ children: [
6335
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { flex: 1, children: /* @__PURE__ */ jsxRuntime.jsxs(
6336
+ designSystem.SingleSelect,
6337
+ {
6338
+ value: keyword.type,
6339
+ onChange: (value) => {
6340
+ handleKeywordChange(
6341
+ index,
6342
+ "type",
6343
+ value
6344
+ );
6345
+ },
6346
+ children: [
6347
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "must_contain", children: "Start incident when keyword exists" }),
6348
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: "must_not_contain", children: "Start incident when keyword does not exist" })
6349
+ ]
6350
+ }
6351
+ ) }),
6352
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { flex: 1, children: [
6353
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { alignItems: "center", gap: 3, marginBottom: 2, children: [
6354
+ /* @__PURE__ */ jsxRuntime.jsx(
6355
+ designSystem.Switch,
6356
+ {
6357
+ checked: keyword.is_regex,
6358
+ onCheckedChange: (checked) => handleKeywordChange(index, "is_regex", checked)
6359
+ }
6360
+ ),
6361
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", fontWeight: "500", children: "Regex" })
6362
+ ] }),
6363
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral600", children: "Use regular expression matching" })
6364
+ ] }),
6365
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { flex: 1, children: [
6366
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { alignItems: "center", gap: 3, marginBottom: 2, children: [
6367
+ /* @__PURE__ */ jsxRuntime.jsx(
6368
+ designSystem.Switch,
6369
+ {
6370
+ checked: keyword.case_sensitive,
6371
+ onCheckedChange: (checked) => handleKeywordChange(index, "case_sensitive", checked)
6372
+ }
6373
+ ),
6374
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", fontWeight: "500", children: "Case Sensitive" })
6375
+ ] }),
6376
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral600", children: "Match exact letter case" })
6377
+ ] })
6378
+ ]
6379
+ }
6380
+ )
6381
+ ]
6382
+ },
6383
+ index
6384
+ )) })
6385
+ ] })
6386
+ ] });
6387
+ }
6388
+ function KeywordAdvancedSettings({
6389
+ timeout,
6390
+ onTimeoutChange,
6391
+ followRedirects,
6392
+ onFollowRedirectsChange,
6393
+ monitorInterval,
6394
+ onMonitorIntervalChange
6395
+ }) {
6396
+ const min = 5;
6397
+ const max = 60;
6398
+ const [minMonitoringInterval, setMinMonitoringInterval] = React.useState(60);
6399
+ const [userPlan, setUserPlan] = React.useState(PLAN_TYPES.TRIAL);
6400
+ React.useEffect(() => {
6401
+ async function fetchUser() {
6402
+ try {
6403
+ const details = await getUserDetailsCached(true);
6404
+ const userMinMonitoringIntervalInMins = details?.plan_limits?.min_monitoring_interval;
6405
+ setMinMonitoringInterval(
6406
+ userMinMonitoringIntervalInMins ? userMinMonitoringIntervalInMins * 60 : 60
6407
+ );
6408
+ setUserPlan(details?.user?.subscription_type || PLAN_TYPES.TRIAL);
6409
+ } catch (error) {
6410
+ console.error("Failed to fetch user details in KeywordAdvancedSettings", error);
5710
6411
  }
5711
- ),
5712
- isOpen && /* @__PURE__ */ jsxRuntime.jsx(
5713
- designSystem.Box,
6412
+ }
6413
+ fetchUser();
6414
+ }, []);
6415
+ const getPercent = (value) => (value - min) / (max - min) * 100;
6416
+ return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { width: "100%", children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Accordion.Root, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Accordion.Item, { value: "keyword-advanced-settings", children: [
6417
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Accordion.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(
6418
+ designSystem.Accordion.Trigger,
5714
6419
  {
5715
- position: "absolute",
5716
- zIndex: 2,
6420
+ caretPosition: "right",
6421
+ description: "Configure monitor interval and request timeout",
6422
+ children: "Advanced settings"
6423
+ }
6424
+ ) }),
6425
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Accordion.Content, { children: /* @__PURE__ */ jsxRuntime.jsxs(
6426
+ designSystem.Flex,
6427
+ {
6428
+ paddingLeft: 6,
6429
+ paddingBottom: 8,
6430
+ paddingTop: 4,
6431
+ direction: "column",
6432
+ gap: 6,
5717
6433
  width: "100%",
5718
- marginTop: 2,
5719
- background: "neutral0",
5720
- borderColor: "neutral200",
5721
- hasRadius: true,
5722
- shadow: "tableShadow",
5723
- maxHeight: "240px",
5724
- overflow: "auto",
5725
- children: isLoading ? /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { padding: 4, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textAlign: "center", textColor: "neutral500", children: "Loading regions…" }) }) : /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: filteredRegions.length > 0 ? filteredRegions.map((region) => {
5726
- const isSelected = selectedRegionIds.includes(String(region.id));
5727
- const isPrimary = primaryRegionId === region.id;
5728
- const isDisabled = isTrialUser && region.id !== DEFAULT_REGION.id;
5729
- return isDisabled ? /* @__PURE__ */ jsxRuntime.jsx(
5730
- designSystem.Tooltip,
5731
- {
5732
- description: "Upgrade to a paid plan to enable global monitoring.",
5733
- children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { children: /* @__PURE__ */ jsxRuntime.jsxs(
5734
- designSystem.Flex,
6434
+ alignItems: "flex-start",
6435
+ children: [
6436
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: { initial: "column", medium: "row" }, gap: 6, width: "100%", children: [
6437
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { width: { initial: "100%", medium: "48%" }, children: /* @__PURE__ */ jsxRuntime.jsx(
6438
+ MonitorIntervalSlider,
6439
+ {
6440
+ value: monitorInterval,
6441
+ onChange: onMonitorIntervalChange,
6442
+ minSeconds: 60,
6443
+ maxSeconds: 86400,
6444
+ minMonitoringInterval,
6445
+ userPlan
6446
+ }
6447
+ ) }),
6448
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { width: { initial: "100%", medium: "48%" }, children: [
6449
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "delta", fontWeight: "bold", children: "Request timeout" }),
6450
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { paddingTop: 2, paddingBottom: 3, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Typography, { variant: "omega", textColor: "neutral600", children: [
6451
+ "The request timeout is ",
6452
+ /* @__PURE__ */ jsxRuntime.jsxs("strong", { children: [
6453
+ timeout,
6454
+ " seconds"
6455
+ ] }),
6456
+ "."
6457
+ ] }) }),
6458
+ /* @__PURE__ */ jsxRuntime.jsx(
6459
+ "input",
5735
6460
  {
5736
- padding: 3,
5737
- gap: 3,
5738
- alignItems: "center",
5739
- background: isSelected ? "primary100" : "neutral0",
6461
+ type: "range",
6462
+ min,
6463
+ max,
6464
+ step: "1",
6465
+ value: timeout,
6466
+ onChange: (e) => onTimeoutChange(parseInt(e.target.value)),
5740
6467
  style: {
5741
- cursor: "not-allowed",
5742
- opacity: 0.5
6468
+ width: "100%",
6469
+ height: 6,
6470
+ borderRadius: 4,
6471
+ appearance: "none",
6472
+ cursor: "pointer",
6473
+ background: `linear-gradient(
6474
+ to right,
6475
+ #4945FF 0%,
6476
+ #4945FF ${getPercent(timeout)}%,
6477
+ #EAEAEA ${getPercent(timeout)}%,
6478
+ #EAEAEA 100%
6479
+ )`
6480
+ }
6481
+ }
6482
+ ),
6483
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { position: "relative", paddingTop: 3, height: 20, children: [5, 15, 30, 45, 60].map((value) => /* @__PURE__ */ jsxRuntime.jsxs(
6484
+ designSystem.Box,
6485
+ {
6486
+ position: "absolute",
6487
+ style: {
6488
+ left: `${getPercent(value)}%`,
6489
+ transform: "translateX(-50%)",
6490
+ fontSize: 10,
6491
+ color: "#666687"
5743
6492
  },
5744
6493
  children: [
5745
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Checkbox, { checked: isSelected, disabled: true }),
5746
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { flex: "1", children: region.name || region.id }),
5747
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Checkbox, { checked: isPrimary, disabled: true, children: "Primary" })
6494
+ value,
6495
+ "s"
5748
6496
  ]
6497
+ },
6498
+ value
6499
+ )) })
6500
+ ] })
6501
+ ] }),
6502
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { children: [
6503
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { alignItems: "center", gap: 3, marginBottom: 2, children: [
6504
+ /* @__PURE__ */ jsxRuntime.jsx(
6505
+ designSystem.Switch,
6506
+ {
6507
+ checked: followRedirects,
6508
+ onCheckedChange: (checked) => onFollowRedirectsChange(checked)
5749
6509
  }
5750
- ) })
5751
- },
5752
- region.id
5753
- ) : /* @__PURE__ */ jsxRuntime.jsxs(
5754
- designSystem.Flex,
5755
- {
5756
- padding: 3,
5757
- gap: 3,
5758
- alignItems: "center",
5759
- background: isSelected ? "primary100" : "neutral0",
5760
- style: { cursor: "pointer" },
5761
- children: [
5762
- /* @__PURE__ */ jsxRuntime.jsx(
5763
- designSystem.Checkbox,
5764
- {
5765
- checked: isSelected,
5766
- onChange: () => handleToggleRegion(region.id)
5767
- }
5768
- ),
5769
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { flex: "1", children: region.name || region.id }),
5770
- /* @__PURE__ */ jsxRuntime.jsx(
5771
- designSystem.Checkbox,
5772
- {
5773
- checked: isPrimary,
5774
- onChange: () => handleSetPrimary(region.id),
5775
- children: "Primary"
5776
- }
5777
- )
5778
- ]
5779
- },
5780
- region.id
5781
- );
5782
- }) : searchInput ? /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { padding: 4, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textAlign: "center", textColor: "neutral500", children: "No regions found" }) }) : null })
6510
+ ),
6511
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "delta", fontWeight: "bold", children: "Follow redirects" })
6512
+ ] }),
6513
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "omega", textColor: "neutral600", children: "Automatically follow HTTP redirects when checking the URL." })
6514
+ ] })
6515
+ ]
5783
6516
  }
5784
- )
5785
- ] });
5786
- };
6517
+ ) })
6518
+ ] }) }) });
6519
+ }
5787
6520
  function MonitorForm({ monitor, mode, handleCancelEdit, load }) {
5788
6521
  const [monitorType, setMonitorType] = React.useState(MONITOR_TYPE.WEBSITE);
5789
6522
  const navigate = reactRouterDom.useNavigate();
@@ -6022,6 +6755,8 @@ function MonitorForm({ monitor, mode, handleCancelEdit, load }) {
6022
6755
  setIsSubmitting(true);
6023
6756
  try {
6024
6757
  let result;
6758
+ let url = mode === "create" ? "/monitors" : `/monitors/${monitor?.id}`;
6759
+ let method = mode === "create" ? "POST" : "PUT";
6025
6760
  if (monitorType === MONITOR_TYPE.PORT) {
6026
6761
  const portNumber = parseInt(portFormData.port, 10);
6027
6762
  const fieldErrors = {};
@@ -6064,8 +6799,8 @@ function MonitorForm({ monitor, mode, handleCancelEdit, load }) {
6064
6799
  tag_ids: selectedTagIds,
6065
6800
  ...mode === "create" ? { is_enabled: true } : { id: monitor?.id }
6066
6801
  };
6067
- result = await request("/monitors", {
6068
- method: mode === "create" ? "POST" : "PATCH",
6802
+ result = await request(url, {
6803
+ method,
6069
6804
  data: payload
6070
6805
  });
6071
6806
  } else if (monitorType === MONITOR_TYPE.KEYWORD) {
@@ -6112,8 +6847,8 @@ function MonitorForm({ monitor, mode, handleCancelEdit, load }) {
6112
6847
  tag_ids: selectedTagIds,
6113
6848
  ...mode === "create" ? { is_enabled: true } : { id: monitor?.id }
6114
6849
  };
6115
- result = await request("/monitors", {
6116
- method: mode === "create" ? "POST" : "PUT",
6850
+ result = await request(url, {
6851
+ method,
6117
6852
  data: payload
6118
6853
  });
6119
6854
  } else {
@@ -6135,8 +6870,8 @@ function MonitorForm({ monitor, mode, handleCancelEdit, load }) {
6135
6870
  regions: buildRegionsPayload(),
6136
6871
  is_enabled: true
6137
6872
  };
6138
- result = await request("/monitors", {
6139
- method: "POST",
6873
+ result = await request(url, {
6874
+ method,
6140
6875
  data: payload
6141
6876
  });
6142
6877
  } else {
@@ -6155,8 +6890,8 @@ function MonitorForm({ monitor, mode, handleCancelEdit, load }) {
6155
6890
  tag_ids: selectedTagIds,
6156
6891
  regions: buildRegionsPayload()
6157
6892
  };
6158
- result = await request(`/monitors/${monitor?.id}`, {
6159
- method: "PUT",
6893
+ result = await request(url, {
6894
+ method,
6160
6895
  data: payload
6161
6896
  });
6162
6897
  }
@@ -6239,6 +6974,21 @@ function MonitorForm({ monitor, mode, handleCancelEdit, load }) {
6239
6974
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
6240
6975
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "beta", marginBottom: 4, marginTop: 2, children: mode === "create" ? "Create Monitor" : "Edit Monitor" }),
6241
6976
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Card, { marginTop: 3, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.CardBody, { width: "100%", children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", gap: 6, width: "100%", children: [
6977
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { width: "100%", children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Root, { children: [
6978
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: "Monitor Type" }),
6979
+ /* @__PURE__ */ jsxRuntime.jsx(
6980
+ designSystem.SingleSelect,
6981
+ {
6982
+ value: monitorType,
6983
+ onChange: (value) => {
6984
+ setMonitorType(value);
6985
+ setErrors({});
6986
+ },
6987
+ disabled: mode === "edit",
6988
+ children: MONITOR_TYPE_OPTIONS.map((option) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.SingleSelectOption, { value: option.value, children: option.label }, option.value))
6989
+ }
6990
+ )
6991
+ ] }) }),
6242
6992
  monitorType === MONITOR_TYPE.WEBSITE && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
6243
6993
  /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", gap: 4, width: "100%", children: [
6244
6994
  /* @__PURE__ */ jsxRuntime.jsxs(
@@ -6316,53 +7066,362 @@ function MonitorForm({ monitor, mode, handleCancelEdit, load }) {
6316
7066
  }
6317
7067
  }
6318
7068
  }
6319
- ),
6320
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Error, {})
6321
- ] }) })
6322
- ]
7069
+ ),
7070
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Error, {})
7071
+ ] }) })
7072
+ ]
7073
+ }
7074
+ ),
7075
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { width: "100%", children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { paddingTop: 4, width: "100%", children: [
7076
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", gap: 1, marginBottom: 2, alignItems: "start", children: [
7077
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "epsilon", children: "Monitoring regions" }),
7078
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "neutral600", variant: "pi", children: "Choose the regions where this monitor should be active" })
7079
+ ] }),
7080
+ /* @__PURE__ */ jsxRuntime.jsx(
7081
+ RegionsMultiSelect,
7082
+ {
7083
+ selectedRegionIds,
7084
+ onRegionsChange: setSelectedRegionIds,
7085
+ primaryRegionId,
7086
+ onPrimaryRegionChange: handlePrimaryRegionChange
7087
+ }
7088
+ ),
7089
+ errors.primaryRegion && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "danger600", variant: "pi", children: errors.primaryRegion })
7090
+ ] }) }),
7091
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { width: "100%", children: [
7092
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", gap: 1, marginBottom: 2, alignItems: "start", children: [
7093
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "epsilon", children: "Add tags" }),
7094
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "neutral600", variant: "pi", children: "Tags will enable you to organize your monitors in a better way" })
7095
+ ] }),
7096
+ /* @__PURE__ */ jsxRuntime.jsx(
7097
+ TagMultiSelect,
7098
+ {
7099
+ selectedTagIds,
7100
+ onTagsChange: setSelectedTagIds
7101
+ }
7102
+ )
7103
+ ] }),
7104
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { width: "100%", direction: "column", gap: 2, alignItems: "start", children: [
7105
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "epsilon", children: "Notifications" }),
7106
+ /* @__PURE__ */ jsxRuntime.jsx(
7107
+ NotificationChannelsIntegration,
7108
+ {
7109
+ value: formData.channel_ids,
7110
+ onChange: (ids) => updateNotificationChannels(ids)
7111
+ }
7112
+ )
7113
+ ] }),
7114
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { width: "100%", direction: "column", gap: 2, alignItems: "start", children: [
7115
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "epsilon", children: "Advanced settings" }),
7116
+ /* @__PURE__ */ jsxRuntime.jsx(
7117
+ AdvancedSettings,
7118
+ {
7119
+ services: formData.config.services,
7120
+ onServiceChange: updateService,
7121
+ meta: formData.config.meta,
7122
+ updateMeta
7123
+ }
7124
+ )
7125
+ ] })
7126
+ ] }),
7127
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "tw-mt-6" })
7128
+ ] }),
7129
+ monitorType === MONITOR_TYPE.PORT && /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", gap: 4, width: "100%", children: [
7130
+ /* @__PURE__ */ jsxRuntime.jsxs(
7131
+ designSystem.Flex,
7132
+ {
7133
+ direction: { initial: "column", medium: "row" },
7134
+ gap: 5,
7135
+ marginBottom: 3,
7136
+ width: "100%",
7137
+ children: [
7138
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { width: "100%", children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Root, { error: errors.name, children: [
7139
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: "Monitor name" }),
7140
+ /* @__PURE__ */ jsxRuntime.jsx(
7141
+ designSystem.Field.Input,
7142
+ {
7143
+ type: "text",
7144
+ size: "M",
7145
+ name: "portName",
7146
+ placeholder: "Monitor name",
7147
+ value: portFormData.name,
7148
+ onChange: (e) => {
7149
+ setPortFormData((prev) => ({
7150
+ ...prev,
7151
+ name: e.target.value
7152
+ }));
7153
+ if (errors.name) {
7154
+ setErrors((prev) => ({
7155
+ ...prev,
7156
+ name: void 0
7157
+ }));
7158
+ }
7159
+ }
7160
+ }
7161
+ ),
7162
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Error, {})
7163
+ ] }) }),
7164
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { width: "100%", children: [
7165
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Root, { error: errors.host, children: [
7166
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: "Host / Address" }),
7167
+ /* @__PURE__ */ jsxRuntime.jsx(
7168
+ designSystem.Field.Input,
7169
+ {
7170
+ type: "text",
7171
+ size: "M",
7172
+ name: "host",
7173
+ placeholder: "example.com or 192.168.1.1",
7174
+ value: portFormData.host,
7175
+ onChange: (e) => {
7176
+ setPortFormData((prev) => ({
7177
+ ...prev,
7178
+ host: e.target.value.trim()
7179
+ }));
7180
+ if (errors.host) {
7181
+ setErrors((prev) => ({
7182
+ ...prev,
7183
+ host: void 0
7184
+ }));
7185
+ }
7186
+ }
7187
+ }
7188
+ ),
7189
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Error, {})
7190
+ ] }),
7191
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral600", marginTop: 1, children: "Enter domain or IP only (no protocol or paths)" })
7192
+ ] })
7193
+ ]
7194
+ }
7195
+ ),
7196
+ /* @__PURE__ */ jsxRuntime.jsxs(
7197
+ designSystem.Flex,
7198
+ {
7199
+ direction: { initial: "column", medium: "row" },
7200
+ gap: 5,
7201
+ marginBottom: 3,
7202
+ width: "100%",
7203
+ children: [
7204
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { width: "100%", children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Root, { error: errors.port, children: [
7205
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: "Port" }),
7206
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral600", marginBottom: 2, children: "The network port to monitor (e.g. 80, 443, 3306). Port range: 1-65535" }),
7207
+ /* @__PURE__ */ jsxRuntime.jsx(
7208
+ designSystem.Field.Input,
7209
+ {
7210
+ type: "number",
7211
+ size: "M",
7212
+ name: "port",
7213
+ min: 1,
7214
+ max: 65535,
7215
+ placeholder: "Port",
7216
+ value: portFormData.port,
7217
+ onChange: (e) => {
7218
+ setPortFormData((prev) => ({
7219
+ ...prev,
7220
+ port: e.target.value
7221
+ }));
7222
+ if (errors.port) {
7223
+ setErrors((prev) => ({
7224
+ ...prev,
7225
+ port: void 0
7226
+ }));
7227
+ }
7228
+ }
7229
+ }
7230
+ ),
7231
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Error, {})
7232
+ ] }) }),
7233
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { width: "100%", children: [
7234
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", gap: 1, marginBottom: 2, alignItems: "start", children: [
7235
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "epsilon", children: "Add tags" }),
7236
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "neutral600", variant: "pi", children: "Tags will enable you to organize your monitors in a better way" })
7237
+ ] }),
7238
+ /* @__PURE__ */ jsxRuntime.jsx(
7239
+ TagMultiSelect,
7240
+ {
7241
+ selectedTagIds,
7242
+ onTagsChange: setSelectedTagIds
7243
+ }
7244
+ )
7245
+ ] })
7246
+ ]
7247
+ }
7248
+ ),
7249
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { width: "100%", direction: "column", gap: 2, alignItems: "start", children: [
7250
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "epsilon", children: "Notifications" }),
7251
+ /* @__PURE__ */ jsxRuntime.jsx(
7252
+ NotificationChannelsIntegration,
7253
+ {
7254
+ value: formData.channel_ids,
7255
+ onChange: (ids) => updateNotificationChannels(ids)
6323
7256
  }
6324
- ),
6325
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { width: "100%", children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { paddingTop: 4, width: "100%", children: [
6326
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", gap: 1, marginBottom: 2, alignItems: "start", children: [
6327
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "epsilon", children: "Monitoring regions" }),
6328
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "neutral600", variant: "pi", children: "Choose the regions where this monitor should be active" })
6329
- ] }),
6330
- /* @__PURE__ */ jsxRuntime.jsx(
6331
- RegionsMultiSelect,
6332
- {
6333
- selectedRegionIds,
6334
- onRegionsChange: setSelectedRegionIds,
6335
- primaryRegionId,
6336
- onPrimaryRegionChange: handlePrimaryRegionChange
6337
- }
6338
- ),
6339
- errors.primaryRegion && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "danger600", variant: "pi", children: errors.primaryRegion })
6340
- ] }) }),
6341
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { width: "100%", direction: "column", gap: 2, alignItems: "start", children: [
6342
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "epsilon", children: "Notifications" }),
6343
- /* @__PURE__ */ jsxRuntime.jsx(
6344
- NotificationChannelsIntegration,
6345
- {
6346
- value: formData.channel_ids,
6347
- onChange: (ids) => updateNotificationChannels(ids)
7257
+ )
7258
+ ] }),
7259
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { width: "100%", direction: "column", gap: 2, alignItems: "start", children: [
7260
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "epsilon", children: "Advanced settings" }),
7261
+ /* @__PURE__ */ jsxRuntime.jsx(
7262
+ PortAdvancedSettings,
7263
+ {
7264
+ timeout: portFormData.timeout,
7265
+ onTimeoutChange: (value) => {
7266
+ setPortFormData((prev) => ({
7267
+ ...prev,
7268
+ timeout: value
7269
+ }));
7270
+ },
7271
+ monitorInterval: portFormData.monitor_interval,
7272
+ onMonitorIntervalChange: (value) => {
7273
+ setPortFormData((prev) => ({
7274
+ ...prev,
7275
+ monitor_interval: value
7276
+ }));
6348
7277
  }
6349
- )
7278
+ }
7279
+ )
7280
+ ] })
7281
+ ] }) }),
7282
+ monitorType === MONITOR_TYPE.KEYWORD && /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", gap: 4, width: "100%", children: [
7283
+ /* @__PURE__ */ jsxRuntime.jsxs(
7284
+ designSystem.Flex,
7285
+ {
7286
+ direction: { initial: "column", medium: "row" },
7287
+ gap: 5,
7288
+ marginBottom: 3,
7289
+ width: "100%",
7290
+ children: [
7291
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { width: "100%", children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Root, { error: errors.name, children: [
7292
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: "Monitor name" }),
7293
+ /* @__PURE__ */ jsxRuntime.jsx(
7294
+ designSystem.Field.Input,
7295
+ {
7296
+ type: "text",
7297
+ size: "M",
7298
+ name: "keywordName",
7299
+ placeholder: "Monitor name",
7300
+ value: keywordFormData.name,
7301
+ onChange: (e) => {
7302
+ setKeywordFormData((prev) => ({
7303
+ ...prev,
7304
+ name: e.target.value
7305
+ }));
7306
+ if (errors.name) {
7307
+ setErrors((prev) => ({
7308
+ ...prev,
7309
+ name: void 0
7310
+ }));
7311
+ }
7312
+ }
7313
+ }
7314
+ ),
7315
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Error, {})
7316
+ ] }) }),
7317
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { width: "100%", children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Root, { error: errors.url, children: [
7318
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: "URL" }),
7319
+ /* @__PURE__ */ jsxRuntime.jsx(
7320
+ designSystem.Field.Input,
7321
+ {
7322
+ type: "text",
7323
+ size: "M",
7324
+ name: "keywordUrl",
7325
+ placeholder: "https://example.com",
7326
+ value: keywordFormData.url,
7327
+ onChange: (e) => {
7328
+ setKeywordFormData((prev) => ({
7329
+ ...prev,
7330
+ url: e.target.value
7331
+ }));
7332
+ if (errors.url) {
7333
+ setErrors((prev) => ({
7334
+ ...prev,
7335
+ url: void 0
7336
+ }));
7337
+ }
7338
+ }
7339
+ }
7340
+ ),
7341
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Error, {})
7342
+ ] }) })
7343
+ ]
7344
+ }
7345
+ ),
7346
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { width: "100%", children: [
7347
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", gap: 1, marginBottom: 2, alignItems: "start", children: [
7348
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "epsilon", children: "Add tags" }),
7349
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "neutral600", variant: "pi", children: "Tags will enable you to organize your monitors in a better way" })
6350
7350
  ] }),
6351
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { width: "100%", direction: "column", gap: 2, alignItems: "start", children: [
6352
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "epsilon", children: "Advanced settings" }),
6353
- /* @__PURE__ */ jsxRuntime.jsx(
6354
- AdvancedSettings,
6355
- {
6356
- services: formData.config.services,
6357
- onServiceChange: updateService,
6358
- meta: formData.config.meta,
6359
- updateMeta
7351
+ /* @__PURE__ */ jsxRuntime.jsx(
7352
+ TagMultiSelect,
7353
+ {
7354
+ selectedTagIds,
7355
+ onTagsChange: setSelectedTagIds
7356
+ }
7357
+ )
7358
+ ] }),
7359
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { width: "100%", children: /* @__PURE__ */ jsxRuntime.jsx(
7360
+ KeywordInput,
7361
+ {
7362
+ keywords: keywordFormData.keywords,
7363
+ onKeywordsChange: (keywords) => {
7364
+ setKeywordFormData((prev) => ({
7365
+ ...prev,
7366
+ keywords
7367
+ }));
7368
+ if (errors.keywords) {
7369
+ setErrors((prev) => ({
7370
+ ...prev,
7371
+ keywords: void 0
7372
+ }));
6360
7373
  }
6361
- )
6362
- ] })
7374
+ },
7375
+ error: errors.keywords,
7376
+ matchAll: keywordFormData.matchAll,
7377
+ onMatchAllChange: (value) => {
7378
+ setKeywordFormData((prev) => ({
7379
+ ...prev,
7380
+ matchAll: value
7381
+ }));
7382
+ }
7383
+ }
7384
+ ) }),
7385
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { width: "100%", direction: "column", gap: 2, alignItems: "start", children: [
7386
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "epsilon", children: "Notifications" }),
7387
+ /* @__PURE__ */ jsxRuntime.jsx(
7388
+ NotificationChannelsIntegration,
7389
+ {
7390
+ value: formData.channel_ids,
7391
+ onChange: (ids) => updateNotificationChannels(ids)
7392
+ }
7393
+ )
6363
7394
  ] }),
6364
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "tw-mt-6" })
6365
- ] }),
7395
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { width: "100%", direction: "column", gap: 2, alignItems: "start", children: [
7396
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "epsilon", children: "Advanced settings" }),
7397
+ /* @__PURE__ */ jsxRuntime.jsx(
7398
+ KeywordAdvancedSettings,
7399
+ {
7400
+ timeout: keywordFormData.timeout,
7401
+ onTimeoutChange: (value) => {
7402
+ setKeywordFormData((prev) => ({
7403
+ ...prev,
7404
+ timeout: value
7405
+ }));
7406
+ },
7407
+ followRedirects: keywordFormData.followRedirects,
7408
+ onFollowRedirectsChange: (value) => {
7409
+ setKeywordFormData((prev) => ({
7410
+ ...prev,
7411
+ followRedirects: value
7412
+ }));
7413
+ },
7414
+ monitorInterval: keywordFormData.monitor_interval,
7415
+ onMonitorIntervalChange: (value) => {
7416
+ setKeywordFormData((prev) => ({
7417
+ ...prev,
7418
+ monitor_interval: value
7419
+ }));
7420
+ }
7421
+ }
7422
+ )
7423
+ ] })
7424
+ ] }) }),
6366
7425
  /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { justifyContent: "flex-end", gap: 3, marginTop: 2, width: "100%", marginBottom: 4, children: [
6367
7426
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { variant: "danger-light", size: "M", onClick: () => handleCancel(), children: "Cancel" }),
6368
7427
  /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { disabled: isSubmitting, size: "M", onClick: handleSubmit, children: isSubmitting ? "Saving..." : mode === "create" ? "Create Monitor" : "Update Monitor" })
@@ -6625,8 +7684,8 @@ const setNestedValue = (obj, path, value) => {
6625
7684
  const keys = path.split(".");
6626
7685
  const result = { ...obj };
6627
7686
  let current = result;
6628
- for (let i = 0; i < keys.length - 1; i++) {
6629
- const key = keys[i];
7687
+ for (let index = 0; index < keys.length - 1; index++) {
7688
+ const key = keys[index];
6630
7689
  current[key] = current[key] ? { ...current[key] } : {};
6631
7690
  current = current[key];
6632
7691
  }
@@ -6664,11 +7723,11 @@ function IntegrationFormModal({
6664
7723
  } else {
6665
7724
  const keys = field.name.split(".");
6666
7725
  let current = initialData;
6667
- for (let i = 0; i < keys.length - 1; i++) {
6668
- if (!current[keys[i]]) {
6669
- current[keys[i]] = {};
7726
+ for (let index = 0; index < keys.length - 1; index++) {
7727
+ if (!current[keys[index]]) {
7728
+ current[keys[index]] = {};
6670
7729
  }
6671
- current = current[keys[i]];
7730
+ current = current[keys[index]];
6672
7731
  }
6673
7732
  current[keys[keys.length - 1]] = "";
6674
7733
  }
@@ -6692,11 +7751,11 @@ function IntegrationFormModal({
6692
7751
  if (value !== void 0) {
6693
7752
  const keys = field.name.split(".");
6694
7753
  let current = populatedData;
6695
- for (let i = 0; i < keys.length - 1; i++) {
6696
- if (!current[keys[i]]) {
6697
- current[keys[i]] = {};
7754
+ for (let index = 0; index < keys.length - 1; index++) {
7755
+ if (!current[keys[index]]) {
7756
+ current[keys[index]] = {};
6698
7757
  }
6699
- current = current[keys[i]];
7758
+ current = current[keys[index]];
6700
7759
  }
6701
7760
  current[keys[keys.length - 1]] = value;
6702
7761
  }
@@ -6778,11 +7837,11 @@ function IntegrationFormModal({
6778
7837
  if (value !== void 0 && value !== "") {
6779
7838
  const keys = field.name.split(".");
6780
7839
  let current = config2;
6781
- for (let i = 0; i < keys.length - 1; i++) {
6782
- if (!current[keys[i]]) {
6783
- current[keys[i]] = {};
7840
+ for (let index = 0; index < keys.length - 1; index++) {
7841
+ if (!current[keys[index]]) {
7842
+ current[keys[index]] = {};
6784
7843
  }
6785
- current = current[keys[i]];
7844
+ current = current[keys[index]];
6786
7845
  }
6787
7846
  current[keys[keys.length - 1]] = value;
6788
7847
  }
@@ -6928,43 +7987,52 @@ function IntegrationFormModal({
6928
7987
  channel.config_schema.fields.map((field) => {
6929
7988
  const isDisabled = isFieldDisabled(field);
6930
7989
  const isPassword = field.type === "password";
6931
- return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { width: "100%", children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Root, { name: field.name, error: errors[field.name], hint: field.description && !errors[field.name] ? field.description : void 0, children: [
6932
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: field.label }),
6933
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { position: "relative", children: [
6934
- /* @__PURE__ */ jsxRuntime.jsx(
6935
- designSystem.Field.Input,
6936
- {
6937
- type: getInputType(field.type, field.name),
6938
- placeholder: field.placeholder,
6939
- value: getDisplayValue(field),
6940
- disabled: isDisabled,
6941
- onChange: (e) => {
6942
- if (!isDisabled) {
6943
- updateFieldValue(field.name, e.target.value);
7990
+ return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { width: "100%", children: /* @__PURE__ */ jsxRuntime.jsxs(
7991
+ designSystem.Field.Root,
7992
+ {
7993
+ name: field.name,
7994
+ error: errors[field.name],
7995
+ hint: field.description && !errors[field.name] ? field.description : void 0,
7996
+ children: [
7997
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: field.label }),
7998
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { position: "relative", children: [
7999
+ /* @__PURE__ */ jsxRuntime.jsx(
8000
+ designSystem.Field.Input,
8001
+ {
8002
+ type: getInputType(field.type, field.name),
8003
+ placeholder: field.placeholder,
8004
+ value: getDisplayValue(field),
8005
+ disabled: isDisabled,
8006
+ onChange: (e) => {
8007
+ if (!isDisabled) {
8008
+ updateFieldValue(field.name, e.target.value);
8009
+ }
8010
+ }
6944
8011
  }
6945
- }
6946
- }
6947
- ),
6948
- isPassword && /* @__PURE__ */ jsxRuntime.jsx(
6949
- designSystem.Button,
6950
- {
6951
- variant: "ghost",
6952
- size: "S",
6953
- onClick: () => togglePasswordVisibility(field.name),
6954
- style: {
6955
- position: "absolute",
6956
- right: 8,
6957
- top: "50%",
6958
- transform: "translateY(-50%)"
6959
- },
6960
- "aria-label": showPassword[field.name] ? "Hide password" : "Show password",
6961
- children: showPassword[field.name] ? /* @__PURE__ */ jsxRuntime.jsx(icons.EyeStriked, {}) : /* @__PURE__ */ jsxRuntime.jsx(icons.Eye, {})
6962
- }
6963
- )
6964
- ] }),
6965
- field.description && !errors[field.name] && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Hint, {}),
6966
- errors[field.name] && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Error, {})
6967
- ] }, field.name) });
8012
+ ),
8013
+ isPassword && /* @__PURE__ */ jsxRuntime.jsx(
8014
+ designSystem.Button,
8015
+ {
8016
+ variant: "ghost",
8017
+ size: "S",
8018
+ onClick: () => togglePasswordVisibility(field.name),
8019
+ style: {
8020
+ position: "absolute",
8021
+ right: 8,
8022
+ top: "50%",
8023
+ transform: "translateY(-50%)"
8024
+ },
8025
+ "aria-label": showPassword[field.name] ? "Hide password" : "Show password",
8026
+ children: showPassword[field.name] ? /* @__PURE__ */ jsxRuntime.jsx(icons.EyeStriked, {}) : /* @__PURE__ */ jsxRuntime.jsx(icons.Eye, {})
8027
+ }
8028
+ )
8029
+ ] }),
8030
+ field.description && !errors[field.name] && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Hint, {}),
8031
+ errors[field.name] && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Error, {})
8032
+ ]
8033
+ },
8034
+ field.name
8035
+ ) });
6968
8036
  })
6969
8037
  ] }) }),
6970
8038
  /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Modal.Footer, { children: [
@@ -7295,153 +8363,187 @@ const IntegrationsPage = () => {
7295
8363
  }
7296
8364
  };
7297
8365
  return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { padding: 2, children: [
7298
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: { initial: "column", medium: "row" }, alignItems: "stretch", gap: 4, height: "100%", children: [
7299
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { background: "neutral0", padding: 4, borderRadius: "8px", width: { initial: "100%", medium: "260px" }, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { direction: "column", gap: 2, alignItems: "stretch", children: filterCategories.map((filter) => /* @__PURE__ */ jsxRuntime.jsx(
7300
- designSystem.Button,
7301
- {
7302
- variant: activeFilter === filter.id ? "secondary" : "tertiary",
7303
- disabled: !filter.enabled,
7304
- justifyContent: "flex-start",
7305
- onClick: () => filter.enabled && setActiveFilter(filter.id),
7306
- children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", children: filter.name })
7307
- },
7308
- filter.id
7309
- )) }) }),
7310
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { background: "neutral0", padding: 4, borderRadius: "8px", flex: "1", overflow: "auto", children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { maxWidth: { initial: "100%", medium: "900px" }, margin: "auto", children: [
7311
- /* @__PURE__ */ jsxRuntime.jsxs(
7312
- designSystem.Flex,
7313
- {
7314
- direction: { initial: "column", medium: "row" },
7315
- justifyContent: "space-between",
7316
- alignItems: { initial: "stretch", medium: "center" },
7317
- gap: 4,
7318
- marginBottom: 6,
7319
- children: [
7320
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { alignItems: "center", gap: 3, children: [
7321
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "beta", children: "Integrations" }),
7322
- planLimits && /* @__PURE__ */ jsxRuntime.jsx(
7323
- designSystem.Box,
7324
- {
7325
- background: "neutral100",
7326
- paddingLeft: 3,
7327
- paddingRight: 3,
7328
- paddingTop: 1,
7329
- paddingBottom: 1,
7330
- borderRadius: "20px",
7331
- children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Typography, { variant: "pi", textColor: "neutral600", children: [
7332
- planLimits.used_integrations,
7333
- "/",
7334
- planLimits.max_integrations,
7335
- " used"
7336
- ] })
7337
- }
7338
- )
7339
- ] }),
7340
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { width: { initial: "100%", medium: "280px" }, children: /* @__PURE__ */ jsxRuntime.jsx(
7341
- designSystem.TextInput,
8366
+ /* @__PURE__ */ jsxRuntime.jsxs(
8367
+ designSystem.Flex,
8368
+ {
8369
+ direction: { initial: "column", medium: "row" },
8370
+ alignItems: "stretch",
8371
+ gap: 4,
8372
+ height: "100%",
8373
+ children: [
8374
+ /* @__PURE__ */ jsxRuntime.jsx(
8375
+ designSystem.Box,
8376
+ {
8377
+ background: "neutral0",
8378
+ padding: 4,
8379
+ borderRadius: "8px",
8380
+ width: { initial: "100%", medium: "260px" },
8381
+ children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { direction: "column", gap: 2, alignItems: "stretch", children: filterCategories.map((filter) => /* @__PURE__ */ jsxRuntime.jsx(
8382
+ designSystem.Button,
7342
8383
  {
7343
- placeholder: "Search by integration type…",
7344
- value: searchQuery,
7345
- onChange: (e) => setSearchQuery(e.target.value),
7346
- startAction: /* @__PURE__ */ jsxRuntime.jsx(icons.Search, {})
7347
- }
7348
- ) })
7349
- ]
7350
- }
7351
- ),
7352
- channelsLoading ? /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { padding: { initial: 2, medium: 8 }, textAlign: "center", children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "neutral500", children: "Loading integrations…" }) }) : activeFilter === "my" ? integrations.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { padding: { initial: 2, medium: 8 }, textAlign: "center", width: "100%", children: /* @__PURE__ */ jsxRuntime.jsxs(
7353
- designSystem.Flex,
7354
- {
7355
- direction: "column",
7356
- alignItems: "center",
7357
- gap: 3,
7358
- marginBottom: 4,
7359
- width: "100%",
7360
- children: [
7361
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "delta", children: "No integrations found" }),
7362
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral500", children: "Please add an integration to get started" })
7363
- ]
7364
- }
7365
- ) }) : /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { direction: "column", gap: 3, width: "100%", children: integrations.map((integration) => /* @__PURE__ */ jsxRuntime.jsx(
7366
- IntegrationCard,
7367
- {
7368
- integration,
7369
- onEdit: handleEdit,
7370
- onDelete: handleDelete,
7371
- onTest: handleTest,
7372
- onToggle: handleToggleIntegration
7373
- },
7374
- integration.id
7375
- )) }) : filteredChannels.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { padding: { initial: 2, medium: 8 }, textAlign: "center", children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "center", gap: 3, marginBottom: 4, width: "100%", children: [
7376
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "delta", children: "No integrations available" }),
7377
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral500", children: searchQuery ? "Try a different search term" : "No integrations match this filter" })
7378
- ] }) }) : (
7379
- /* CATEGORY ACCORDIONS */
7380
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Accordion.Root, { children: filteredChannels.map((channel) => {
7381
- const channelIntegrations = getIntegrationsByChannelType(channel.type);
7382
- return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Accordion.Item, { value: channel.type, children: [
7383
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Accordion.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Accordion.Trigger, { caretPosition: "left", description: channel.description, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { alignItems: "center", gap: 3, width: { initial: "100%", medium: "542px" }, children: [
7384
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { children: getIntegrationIcon(channel.icon) }),
7385
- /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { width: { initial: "100%", medium: "542px" }, gap: 3, justifyContent: "space-between", children: [
7386
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "semiBold", children: channel.label }),
7387
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "flex-end", children: !planLimits?.can_add_more ? /* @__PURE__ */ jsxRuntime.jsx(designSystem.Tooltip, { label: "Max integrations limit reached for your plan.", children: /* @__PURE__ */ jsxRuntime.jsx(
7388
- designSystem.Button,
8384
+ variant: activeFilter === filter.id ? "secondary" : "tertiary",
8385
+ disabled: !filter.enabled,
8386
+ justifyContent: "flex-start",
8387
+ onClick: () => filter.enabled && setActiveFilter(filter.id),
8388
+ children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", children: filter.name })
8389
+ },
8390
+ filter.id
8391
+ )) })
8392
+ }
8393
+ ),
8394
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { background: "neutral0", padding: 4, borderRadius: "8px", flex: "1", overflow: "auto", children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { maxWidth: { initial: "100%", medium: "900px" }, margin: "auto", children: [
8395
+ /* @__PURE__ */ jsxRuntime.jsxs(
8396
+ designSystem.Flex,
8397
+ {
8398
+ direction: { initial: "column", medium: "row" },
8399
+ justifyContent: "space-between",
8400
+ alignItems: { initial: "stretch", medium: "center" },
8401
+ gap: 4,
8402
+ marginBottom: 6,
8403
+ children: [
8404
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { alignItems: "center", gap: 3, children: [
8405
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "beta", children: "Integrations" }),
8406
+ planLimits && /* @__PURE__ */ jsxRuntime.jsx(
8407
+ designSystem.Box,
8408
+ {
8409
+ background: "neutral100",
8410
+ paddingLeft: 3,
8411
+ paddingRight: 3,
8412
+ paddingTop: 1,
8413
+ paddingBottom: 1,
8414
+ borderRadius: "20px",
8415
+ children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Typography, { variant: "pi", textColor: "neutral600", children: [
8416
+ planLimits.used_integrations,
8417
+ "/",
8418
+ planLimits.max_integrations,
8419
+ " used"
8420
+ ] })
8421
+ }
8422
+ )
8423
+ ] }),
8424
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { width: { initial: "100%", medium: "280px" }, children: /* @__PURE__ */ jsxRuntime.jsx(
8425
+ designSystem.TextInput,
7389
8426
  {
7390
- startIcon: /* @__PURE__ */ jsxRuntime.jsx(icons.Plus, {}),
7391
- disabled: !planLimits?.can_add_more,
7392
- onClick: (e) => {
7393
- e.stopPropagation();
7394
- handleAddClick(channel);
7395
- },
7396
- style: { cursor: "not-allowed" },
7397
- children: "Add"
8427
+ placeholder: "Search by integration type…",
8428
+ value: searchQuery,
8429
+ onChange: (e) => setSearchQuery(e.target.value),
8430
+ startAction: /* @__PURE__ */ jsxRuntime.jsx(icons.Search, {})
7398
8431
  }
7399
- ) }) : /* @__PURE__ */ jsxRuntime.jsx(
7400
- designSystem.Button,
8432
+ ) })
8433
+ ]
8434
+ }
8435
+ ),
8436
+ channelsLoading ? /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { padding: { initial: 2, medium: 8 }, textAlign: "center", children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "neutral500", children: "Loading integrations…" }) }) : activeFilter === "my" ? integrations.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { padding: { initial: 2, medium: 8 }, textAlign: "center", width: "100%", children: /* @__PURE__ */ jsxRuntime.jsxs(
8437
+ designSystem.Flex,
8438
+ {
8439
+ direction: "column",
8440
+ alignItems: "center",
8441
+ gap: 3,
8442
+ marginBottom: 4,
8443
+ width: "100%",
8444
+ children: [
8445
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "delta", children: "No integrations found" }),
8446
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral500", children: "Please add an integration to get started" })
8447
+ ]
8448
+ }
8449
+ ) }) : /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { direction: "column", gap: 3, width: "100%", children: integrations.map((integration) => /* @__PURE__ */ jsxRuntime.jsx(
8450
+ IntegrationCard,
8451
+ {
8452
+ integration,
8453
+ onEdit: handleEdit,
8454
+ onDelete: handleDelete,
8455
+ onTest: handleTest,
8456
+ onToggle: handleToggleIntegration
8457
+ },
8458
+ integration.id
8459
+ )) }) : filteredChannels.length === 0 ? /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { padding: { initial: 2, medium: 8 }, textAlign: "center", children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "center", gap: 3, marginBottom: 4, width: "100%", children: [
8460
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "delta", children: "No integrations available" }),
8461
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral500", children: searchQuery ? "Try a different search term" : "No integrations match this filter" })
8462
+ ] }) }) : (
8463
+ /* CATEGORY ACCORDIONS */
8464
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Accordion.Root, { children: filteredChannels.map((channel) => {
8465
+ const channelIntegrations = getIntegrationsByChannelType(channel.type);
8466
+ return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Accordion.Item, { value: channel.type, children: [
8467
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Accordion.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Accordion.Trigger, { caretPosition: "left", description: channel.description, children: /* @__PURE__ */ jsxRuntime.jsxs(
8468
+ designSystem.Flex,
7401
8469
  {
7402
- startIcon: /* @__PURE__ */ jsxRuntime.jsx(icons.Plus, {}),
7403
- disabled: !planLimits?.can_add_more,
7404
- onClick: (e) => {
7405
- e.stopPropagation();
7406
- handleAddClick(channel);
7407
- },
7408
- children: "Add"
8470
+ alignItems: "center",
8471
+ gap: 3,
8472
+ width: { initial: "100%", medium: "542px" },
8473
+ children: [
8474
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { children: getIntegrationIcon(channel.icon) }),
8475
+ /* @__PURE__ */ jsxRuntime.jsxs(
8476
+ designSystem.Flex,
8477
+ {
8478
+ width: { initial: "100%", medium: "542px" },
8479
+ gap: 3,
8480
+ justifyContent: "space-between",
8481
+ children: [
8482
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "semiBold", children: channel.label }),
8483
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "flex-end", children: !planLimits?.can_add_more ? /* @__PURE__ */ jsxRuntime.jsx(designSystem.Tooltip, { label: "Max integrations limit reached for your plan.", children: /* @__PURE__ */ jsxRuntime.jsx(
8484
+ designSystem.Button,
8485
+ {
8486
+ startIcon: /* @__PURE__ */ jsxRuntime.jsx(icons.Plus, {}),
8487
+ disabled: !planLimits?.can_add_more,
8488
+ onClick: (e) => {
8489
+ e.stopPropagation();
8490
+ handleAddClick(channel);
8491
+ },
8492
+ style: { cursor: "not-allowed" },
8493
+ children: "Add"
8494
+ }
8495
+ ) }) : /* @__PURE__ */ jsxRuntime.jsx(
8496
+ designSystem.Button,
8497
+ {
8498
+ startIcon: /* @__PURE__ */ jsxRuntime.jsx(icons.Plus, {}),
8499
+ disabled: !planLimits?.can_add_more,
8500
+ onClick: (e) => {
8501
+ e.stopPropagation();
8502
+ handleAddClick(channel);
8503
+ },
8504
+ children: "Add"
8505
+ }
8506
+ ) })
8507
+ ]
8508
+ }
8509
+ )
8510
+ ]
7409
8511
  }
7410
- ) })
7411
- ] })
7412
- ] }) }) }),
7413
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Accordion.Content, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", gap: 3, paddingTop: 4, children: [
7414
- channelIntegrations.length === 0 && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { padding: { initial: 2, medium: 8 }, textAlign: "center", children: /* @__PURE__ */ jsxRuntime.jsxs(
7415
- designSystem.Flex,
7416
- {
7417
- direction: "column",
7418
- alignItems: "center",
7419
- gap: 3,
7420
- marginBottom: 4,
7421
- width: "100%",
7422
- children: [
7423
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "delta", children: "No integrations found" }),
7424
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral500", children: 'No integrations for this channel yet. Click "Add" to create one.' })
7425
- ]
7426
- }
7427
- ) }),
7428
- channelIntegrations.map((integration) => /* @__PURE__ */ jsxRuntime.jsx(
7429
- IntegrationCard,
7430
- {
7431
- integration,
7432
- onEdit: handleEdit,
7433
- onDelete: handleDelete,
7434
- onTest: handleTest,
7435
- onToggle: handleToggleIntegration
7436
- },
7437
- integration.id
7438
- ))
7439
- ] }) })
7440
- ] }, channel.type);
7441
- }) })
7442
- )
7443
- ] }) })
7444
- ] }),
8512
+ ) }) }),
8513
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Accordion.Content, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", gap: 3, paddingTop: 4, children: [
8514
+ channelIntegrations.length === 0 && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { padding: { initial: 2, medium: 8 }, textAlign: "center", children: /* @__PURE__ */ jsxRuntime.jsxs(
8515
+ designSystem.Flex,
8516
+ {
8517
+ direction: "column",
8518
+ alignItems: "center",
8519
+ gap: 3,
8520
+ marginBottom: 4,
8521
+ width: "100%",
8522
+ children: [
8523
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "delta", children: "No integrations found" }),
8524
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral500", children: 'No integrations for this channel yet. Click "Add" to create one.' })
8525
+ ]
8526
+ }
8527
+ ) }),
8528
+ channelIntegrations.map((integration) => /* @__PURE__ */ jsxRuntime.jsx(
8529
+ IntegrationCard,
8530
+ {
8531
+ integration,
8532
+ onEdit: handleEdit,
8533
+ onDelete: handleDelete,
8534
+ onTest: handleTest,
8535
+ onToggle: handleToggleIntegration
8536
+ },
8537
+ integration.id
8538
+ ))
8539
+ ] }) })
8540
+ ] }, channel.type);
8541
+ }) })
8542
+ )
8543
+ ] }) })
8544
+ ]
8545
+ }
8546
+ ),
7445
8547
  /* @__PURE__ */ jsxRuntime.jsx(
7446
8548
  IntegrationFormModal,
7447
8549
  {
@@ -8914,7 +10016,7 @@ function Dashboard() {
8914
10016
  ]
8915
10017
  }
8916
10018
  ) }),
8917
- /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { width: "100%", children: /* @__PURE__ */ jsxRuntime.jsx(HealthCards, { monitorData, isLoading }) })
10019
+ monitorData?.monitor?.service_type === "website" && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { width: "100%", children: /* @__PURE__ */ jsxRuntime.jsx(HealthCards, { monitorData, isLoading }) })
8918
10020
  ]
8919
10021
  }
8920
10022
  ),
@@ -11108,7 +12210,7 @@ const fetchIncidentsFromBackend = async (params, timeout = 1e4) => {
11108
12210
  return null;
11109
12211
  }
11110
12212
  if (!result?.incidentsData) {
11111
- console.error("Failed to fetch incidents:", result.status);
12213
+ console.error("Failed to fetch incidents: incidentsData missing in response", result);
11112
12214
  return null;
11113
12215
  }
11114
12216
  if (result?.incidentsData?.status === "success") {