@procore/saved-views 1.0.0 → 1.0.1-alpha.1

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.
@@ -11385,7 +11385,7 @@ var SavedViewCollectionMenuItem = (props) => {
11385
11385
  loading: props.isUpdateProcessing
11386
11386
  },
11387
11387
  i18n.t("savedViews.actions.update")
11388
- )), props.item.view_level !== "default" && props.selected && !props.canUpdate && props.item.id !== "temporary" && /* @__PURE__ */ React15.createElement("div", null, /* @__PURE__ */ React15.createElement(
11388
+ )), (props.enableSharingViews ?? true) && props.item.view_level !== "default" && props.selected && !props.canUpdate && props.item.id !== "temporary" && /* @__PURE__ */ React15.createElement("div", null, /* @__PURE__ */ React15.createElement(
11389
11389
  Button2,
11390
11390
  {
11391
11391
  onClick: copyShareLink,
@@ -11433,176 +11433,13 @@ var ExpandedPanel = styled_components_esm_default(Panel)`
11433
11433
  `;
11434
11434
 
11435
11435
  // src/components/panels/PanelContent.tsx
11436
- import { Flex as Flex3, useI18nContext as useI18nContext5 } from "@procore/core-react";
11436
+ import { Flex as Flex3, useI18nContext as useI18nContext4 } from "@procore/core-react";
11437
11437
  import { useToastAlertContext as useToastAlertContext2 } from "@procore/toast-alert";
11438
11438
  import React17 from "react";
11439
11439
 
11440
- // node_modules/@procore/core-http/dist/modern/index.js
11441
- function getCSRFToken() {
11442
- const token = document.cookie.match("(^|;)\\s*csrf_token\\s*=\\s*([^;]+)");
11443
- return token ? decodeURIComponent(token.pop() || "") : "";
11444
- }
11445
- function getCSRFHeader() {
11446
- const csrfToken = getCSRFToken();
11447
- return csrfToken ? { "X-CSRF-TOKEN": csrfToken } : {};
11448
- }
11449
- function removeLeadingSlash(url) {
11450
- return url.startsWith("/") ? url.substring(1, url.length) : url;
11451
- }
11452
- function removeTrailingSlash(url) {
11453
- return url.endsWith("/") ? url.substring(0, url.length - 1) : url;
11454
- }
11455
- function applyBaseUrl(url, baseUrl) {
11456
- return `${removeTrailingSlash(baseUrl)}/${removeLeadingSlash(url)}`;
11457
- }
11458
- function getOptions({ headers, ...options }) {
11459
- const opts = {
11460
- credentials: "same-origin",
11461
- headers: {
11462
- ...getCSRFHeader(),
11463
- ...headers
11464
- },
11465
- mode: "same-origin",
11466
- ...options
11467
- };
11468
- return opts;
11469
- }
11470
- function getUrl(url, baseUrl) {
11471
- return baseUrl ? applyBaseUrl(url, baseUrl) : url;
11472
- }
11473
- function request(url, { baseUrl, ...options } = {}) {
11474
- return fetch(getUrl(url, baseUrl), getOptions(options));
11475
- }
11476
- function requestJSON(url, requestParams = {}) {
11477
- return request(url, requestParams).then(
11478
- (response) => response.json()
11479
- );
11480
- }
11481
-
11482
- // src/utils/api/queries.ts
11483
- import { useQuery } from "@tanstack/react-query";
11484
-
11485
- // src/utils/api/queriesHandler.ts
11486
- import { useMutation, useQueryClient } from "@tanstack/react-query";
11487
- import { useI18nContext as useI18nContext3 } from "@procore/core-react";
11488
- var useApiRequest = (props, method, mutationKey) => {
11489
- const { projectId, companyId, domain, tableName } = props;
11490
- const queryClient2 = useQueryClient();
11491
- const { locale: locale2 } = useI18nContext3();
11492
- return useMutation({
11493
- mutationKey,
11494
- mutationFn: async (savedView) => {
11495
- let url = "";
11496
- if (method === "DELETE" || method === "PUT") {
11497
- url = `/rest/v2.0/companies/${companyId}/projects/${projectId}/saved_views/${savedView.share_token}?permissions_domain=${domain}`;
11498
- } else {
11499
- url = `/rest/v2.0/companies/${companyId}/projects/${projectId}/saved_views?table_name=${tableName}&permissions_domain=${domain}`;
11500
- }
11501
- const response = await requestJSON(url, {
11502
- method,
11503
- body: JSON.stringify(savedView),
11504
- headers: {
11505
- "Content-Type": "application/json",
11506
- "Accept-Language": locale2
11507
- }
11508
- });
11509
- if (response.error) {
11510
- throw response.error;
11511
- }
11512
- return response.data;
11513
- },
11514
- onSuccess: (savedView) => {
11515
- if (method === "DELETE" || method === "POST") {
11516
- queryClient2.invalidateQueries({
11517
- queryKey: ["savedViews", domain, tableName]
11518
- });
11519
- return;
11520
- } else {
11521
- const oldData = queryClient2.getQueryData([
11522
- "savedViews",
11523
- domain,
11524
- tableName
11525
- ]);
11526
- const oldView = oldData?.find(
11527
- (item) => item.share_token === savedView.share_token
11528
- );
11529
- if (oldView?.name !== savedView.name) {
11530
- queryClient2.invalidateQueries({
11531
- queryKey: ["savedViews", domain, tableName]
11532
- });
11533
- return;
11534
- }
11535
- }
11536
- queryClient2.setQueryData(
11537
- ["savedViews", domain, tableName],
11538
- (oldData) => {
11539
- if (!oldData)
11540
- return [savedView];
11541
- return oldData.map(
11542
- (item) => item.share_token === savedView.share_token ? savedView : item
11543
- );
11544
- }
11545
- );
11546
- }
11547
- });
11548
- };
11549
-
11550
11440
  // src/utils/constants/viewLevels.ts
11551
11441
  var VIEW_LEVELS = ["company", "project", "personal"];
11552
11442
 
11553
- // src/utils/api/queries.ts
11554
- var PAGE_SIZE = 50 * VIEW_LEVELS.length;
11555
- var useSavedViewsQuery = (props) => {
11556
- const { projectId, companyId, domain, tableName } = props;
11557
- const url = `/rest/v2.0/companies/${companyId}/projects/${projectId}/saved_views?table_name=${tableName}&permissions_domain=${domain}`;
11558
- return useQuery({
11559
- queryKey: ["savedViews", domain, tableName],
11560
- queryFn: async () => {
11561
- const getUrl2 = `${url}&per_page=${PAGE_SIZE}`;
11562
- const response = await requestJSON(getUrl2);
11563
- return response.data;
11564
- }
11565
- });
11566
- };
11567
- var useSavedViewsPermissions = (props) => {
11568
- const { projectId, companyId, domain } = props;
11569
- const url = `/rest/v2.0/companies/${companyId}/projects/${projectId}/saved_views/permissions?permissions_domain=${domain}`;
11570
- return useQuery({
11571
- queryKey: ["savedViewsConfig", domain],
11572
- queryFn: async () => {
11573
- const response = await requestJSON(url);
11574
- return response.data;
11575
- }
11576
- });
11577
- };
11578
- var useCreateSavedView = (props) => useApiRequest(props, "POST", [
11579
- "createSavedView",
11580
- props.domain,
11581
- props.tableName
11582
- ]);
11583
- var useUpdateSavedView = (props) => useApiRequest(props, "PUT", [
11584
- "updateSavedView",
11585
- props.domain,
11586
- props.tableName
11587
- ]);
11588
- var useDeleteSavedView = (props) => useApiRequest(props, "DELETE", [
11589
- "deleteSavedView",
11590
- props.domain,
11591
- props.tableName
11592
- ]);
11593
- var useFetchSavedViewById = (savedViewToken, queryInput, enabled = true) => {
11594
- const { projectId, companyId } = queryInput;
11595
- return useQuery({
11596
- enabled: enabled && Boolean(savedViewToken),
11597
- queryKey: ["savedView", savedViewToken],
11598
- queryFn: async () => {
11599
- const url = `/rest/v2.0/companies/${companyId}/projects/${projectId}/saved_views/${savedViewToken}`;
11600
- const response = await requestJSON(url);
11601
- return response.data;
11602
- }
11603
- });
11604
- };
11605
-
11606
11443
  // src/components/panels/PanelContentUtils.ts
11607
11444
  var import_lodash = __toESM(require_lodash());
11608
11445
 
@@ -11752,12 +11589,13 @@ var normalizeForComparison = (config) => {
11752
11589
  if (!config?.columnState)
11753
11590
  return config;
11754
11591
  return {
11755
- ...config,
11592
+ ...import_lodash.default.omit(config, ["enableRowGrouping", "enableColumnGrouping"]),
11756
11593
  columnState: config.columnState.map((col) => {
11594
+ const res = import_lodash.default.omit(col, ["aggFunc"]);
11757
11595
  if (col.flex) {
11758
- return import_lodash.default.omit(col, ["width", "flex"]);
11596
+ return import_lodash.default.omit(res, ["width", "flex"]);
11759
11597
  }
11760
- return col;
11598
+ return res;
11761
11599
  })
11762
11600
  };
11763
11601
  };
@@ -11770,10 +11608,9 @@ var isEqual = (viewTableConfig, tableConfig, defaultViewConfig, provider) => {
11770
11608
  );
11771
11609
  const normalizedViewConfig = normalizeForComparison(syncedViewTableConfig);
11772
11610
  const normalizedCurrentConfig = normalizeForComparison(tableConfig);
11773
- return import_lodash.default.isEqual(
11774
- cleanObject(normalizedViewConfig, provider),
11775
- cleanObject(normalizedCurrentConfig, provider)
11776
- );
11611
+ const cleanedViewConfig = cleanObject(normalizedViewConfig, provider);
11612
+ const cleanedCurrentConfig = cleanObject(normalizedCurrentConfig, provider);
11613
+ return import_lodash.default.isEqual(cleanedViewConfig, cleanedCurrentConfig);
11777
11614
  };
11778
11615
  var hasPermissionForViewLevel = (viewLevel, permissions) => {
11779
11616
  switch (viewLevel) {
@@ -11806,7 +11643,7 @@ import {
11806
11643
  Flex as Flex2,
11807
11644
  spacing,
11808
11645
  Typography,
11809
- useI18nContext as useI18nContext4
11646
+ useI18nContext as useI18nContext3
11810
11647
  } from "@procore/core-react";
11811
11648
  import React16 from "react";
11812
11649
  var groupIcon = (group) => {
@@ -11826,7 +11663,7 @@ var Header = styled_components_esm_default(Flex2)`
11826
11663
  }
11827
11664
  `;
11828
11665
  var ViewLevelHeader = ({ expanded, toggleGroup, group }) => {
11829
- const I18n = useI18nContext4();
11666
+ const I18n = useI18nContext3();
11830
11667
  return /* @__PURE__ */ React16.createElement(
11831
11668
  Header,
11832
11669
  {
@@ -11883,9 +11720,9 @@ var Panel2 = styled_components_esm_default(DetailPage.Card)`
11883
11720
  var PanelContent = (props) => {
11884
11721
  const { queryInput, selectedSavedView, tableConfig } = props;
11885
11722
  const { showToast } = useToastAlertContext2();
11886
- const I18n = useI18nContext5();
11887
- const { data: savedViewsFromQuery, error: savedViewsError } = useSavedViewsQuery(props.queryInput);
11888
- const updateMutation = useUpdateSavedView(queryInput);
11723
+ const I18n = useI18nContext4();
11724
+ const { data: savedViewsFromQuery, error: savedViewsError } = props.backend.useSavedViewsQuery(props.queryInput);
11725
+ const updateMutation = props.backend.useUpdateSavedView(queryInput);
11889
11726
  const { mutate: updateSavedView } = updateMutation;
11890
11727
  const isUpdateLoading = "isPending" in updateMutation ? updateMutation.isPending : updateMutation.isLoading ?? false;
11891
11728
  const savedViews = props.savedViews ?? savedViewsFromQuery;
@@ -11896,7 +11733,9 @@ var PanelContent = (props) => {
11896
11733
  errorToastRef.current = savedViewsError;
11897
11734
  }
11898
11735
  }, [savedViewsError, showToast, I18n]);
11899
- const { data: permissions } = useSavedViewsPermissions(props.queryInput);
11736
+ const { data: permissions } = props.backend.useSavedViewsPermissions(
11737
+ props.queryInput
11738
+ );
11900
11739
  const selectedRowRef = useScrollToRef(savedViews);
11901
11740
  const { groups, toggleGroup } = useGroups();
11902
11741
  const isTemporarySelected = selectedSavedView?.id === "temporary";
@@ -11930,7 +11769,8 @@ var PanelContent = (props) => {
11930
11769
  {
11931
11770
  item: temporaryView,
11932
11771
  selected: isTemporarySelected,
11933
- onClearTemporary: props.onClearTemporary
11772
+ onClearTemporary: props.onClearTemporary,
11773
+ enableSharingViews: false
11934
11774
  }
11935
11775
  )
11936
11776
  ), presetViews.map((presetView) => {
@@ -11947,7 +11787,8 @@ var PanelContent = (props) => {
11947
11787
  SavedViewCollectionMenuItem,
11948
11788
  {
11949
11789
  item: presetView,
11950
- selected: isSelected
11790
+ selected: isSelected,
11791
+ enableSharingViews: false
11951
11792
  }
11952
11793
  )
11953
11794
  );
@@ -11995,7 +11836,8 @@ var PanelContent = (props) => {
11995
11836
  isUpdateProcessing: isUpdateLoading,
11996
11837
  onEdit: () => props.openModal("update" /* UPDATE */),
11997
11838
  onDelete: props.onDelete,
11998
- permissions
11839
+ permissions,
11840
+ enableSharingViews: false
11999
11841
  }
12000
11842
  )
12001
11843
  );
@@ -12012,7 +11854,7 @@ import {
12012
11854
  Tooltip,
12013
11855
  useI18nContext as useI18nContext11
12014
11856
  } from "@procore/core-react";
12015
- import React22, { useState as useState4, useEffect as useEffect3, useCallback as useCallback3 } from "react";
11857
+ import React22, { useState as useState4, useEffect as useEffect4, useCallback as useCallback3 } from "react";
12016
11858
  import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
12017
11859
  import { useToastAlertContext as useToastAlertContext3, ToastAlertProvider } from "@procore/toast-alert";
12018
11860
 
@@ -12022,7 +11864,7 @@ import {
12022
11864
  ConfirmModal,
12023
11865
  Modal,
12024
11866
  P as P2,
12025
- useI18nContext as useI18nContext6
11867
+ useI18nContext as useI18nContext5
12026
11868
  } from "@procore/core-react";
12027
11869
  import React18 from "react";
12028
11870
  var SavedViewsDeleteConfirmationModalShared = ({
@@ -12030,7 +11872,7 @@ var SavedViewsDeleteConfirmationModalShared = ({
12030
11872
  onDelete,
12031
11873
  open
12032
11874
  }) => {
12033
- const i18n = useI18nContext6();
11875
+ const i18n = useI18nContext5();
12034
11876
  return /* @__PURE__ */ React18.createElement(
12035
11877
  ConfirmModal,
12036
11878
  {
@@ -12061,7 +11903,7 @@ import {
12061
11903
  Modal as Modal2,
12062
11904
  spacing as spacing3,
12063
11905
  Typography as Typography2,
12064
- useI18nContext as useI18nContext7
11906
+ useI18nContext as useI18nContext6
12065
11907
  } from "@procore/core-react";
12066
11908
  import * as React19 from "react";
12067
11909
 
@@ -14391,6 +14233,7 @@ function extractMessage(error, I18n) {
14391
14233
  }
14392
14234
 
14393
14235
  // src/components/modals/form-modal/FormModalBase.tsx
14236
+ var { useEffect: useEffect2, useRef: useRef2 } = React19;
14394
14237
  var ScrollContainer = styled_components_esm_default("div")`
14395
14238
  overflow: auto;
14396
14239
  `;
@@ -14407,22 +14250,38 @@ var FormModalBase = ({
14407
14250
  defaultView,
14408
14251
  selectedSavedView,
14409
14252
  setOpenEditCreateModal,
14410
- onSelect
14253
+ onSelect,
14254
+ backend
14411
14255
  }) => {
14412
- const I18n = useI18nContext7();
14256
+ const I18n = useI18nContext6();
14413
14257
  const NAME_MAX_LENGTH = 150;
14258
+ const originalBodyWidth = useRef2("");
14259
+ useEffect2(() => {
14260
+ if (open) {
14261
+ originalBodyWidth.current = document.body.style.width || "";
14262
+ document.body.style.width = "100%";
14263
+ } else {
14264
+ document.body.style.width = originalBodyWidth.current;
14265
+ }
14266
+ return () => {
14267
+ if (originalBodyWidth.current !== void 0) {
14268
+ document.body.style.width = originalBodyWidth.current;
14269
+ }
14270
+ };
14271
+ }, [open]);
14272
+ const { useCreateSavedView: useCreateSavedView2, useUpdateSavedView: useUpdateSavedView2, useSavedViewsPermissions: useSavedViewsPermissions2 } = backend;
14414
14273
  const {
14415
14274
  mutate: createSavedView,
14416
14275
  isPending: isCreating,
14417
14276
  error: createError,
14418
14277
  reset: resetCreateMutation
14419
- } = useCreateSavedView(queryInput);
14278
+ } = useCreateSavedView2(queryInput);
14420
14279
  const {
14421
14280
  mutate: updateSavedView,
14422
14281
  isPending: isUpdating,
14423
14282
  error: updateError,
14424
14283
  reset: resetUpdateMutation
14425
- } = useUpdateSavedView(queryInput);
14284
+ } = useUpdateSavedView2(queryInput);
14426
14285
  const resetMutations = () => {
14427
14286
  resetCreateMutation();
14428
14287
  resetUpdateMutation();
@@ -14431,7 +14290,7 @@ var FormModalBase = ({
14431
14290
  resetMutations();
14432
14291
  onCancel();
14433
14292
  };
14434
- const { data: permissions } = useSavedViewsPermissions(queryInput);
14293
+ const { data: permissions } = useSavedViewsPermissions2(queryInput);
14435
14294
  const isLoading = isCreating || isUpdating;
14436
14295
  const errors = extractMessage(createError || updateError, I18n);
14437
14296
  const handleOnSubmit = (data) => {
@@ -14542,6 +14401,7 @@ var FormModalBase = ({
14542
14401
  Form.Select,
14543
14402
  {
14544
14403
  name: "view_level",
14404
+ qa: { label: "view-level" },
14545
14405
  options: viewLevelOptions,
14546
14406
  label: I18n.t("savedViews.modal.fields.viewLevel"),
14547
14407
  colWidth: 12,
@@ -14565,7 +14425,7 @@ var FormModalBase = ({
14565
14425
  };
14566
14426
 
14567
14427
  // src/components/modals/form-modal/FormModal.tsx
14568
- import { useI18nContext as useI18nContext8 } from "@procore/core-react";
14428
+ import { useI18nContext as useI18nContext7 } from "@procore/core-react";
14569
14429
  var FormModal = ({
14570
14430
  open,
14571
14431
  mode,
@@ -14576,9 +14436,10 @@ var FormModal = ({
14576
14436
  selectedSavedView,
14577
14437
  setOpenEditCreateModal,
14578
14438
  onSelect,
14579
- defaultView
14439
+ defaultView,
14440
+ backend
14580
14441
  }) => {
14581
- const i18n = useI18nContext8();
14442
+ const i18n = useI18nContext7();
14582
14443
  return /* @__PURE__ */ React20.createElement(
14583
14444
  FormModalBase,
14584
14445
  {
@@ -14594,7 +14455,8 @@ var FormModal = ({
14594
14455
  selectedSavedView,
14595
14456
  setOpenEditCreateModal,
14596
14457
  onSelect,
14597
- defaultView
14458
+ defaultView,
14459
+ backend
14598
14460
  }
14599
14461
  );
14600
14462
  };
@@ -14611,7 +14473,7 @@ import {
14611
14473
  P as P3,
14612
14474
  spacing as spacing4,
14613
14475
  Typography as Typography3,
14614
- useI18nContext as useI18nContext9
14476
+ useI18nContext as useI18nContext8
14615
14477
  } from "@procore/core-react";
14616
14478
  import * as React21 from "react";
14617
14479
  var SharedViewFormModal = ({
@@ -14624,7 +14486,7 @@ var SharedViewFormModal = ({
14624
14486
  isCreating,
14625
14487
  resetCreateError
14626
14488
  }) => {
14627
- const I18n = useI18nContext9();
14489
+ const I18n = useI18nContext8();
14628
14490
  const NAME_MAX_LENGTH = 150;
14629
14491
  const errors = extractMessage(createError, I18n);
14630
14492
  const handleNameChange = () => {
@@ -14754,9 +14616,9 @@ var SharedViewFormModal = ({
14754
14616
  };
14755
14617
 
14756
14618
  // src/utils/hooks/useViewSelection.ts
14757
- import { useState as useState3, useCallback as useCallback2, useEffect as useEffect2, useRef as useRef2, useMemo } from "react";
14619
+ import { useState as useState3, useCallback as useCallback2, useEffect as useEffect3, useRef as useRef3, useMemo } from "react";
14758
14620
  import { useSearchParams } from "react-router-dom";
14759
- import { useI18nContext as useI18nContext10 } from "@procore/core-react";
14621
+ import { useI18nContext as useI18nContext9 } from "@procore/core-react";
14760
14622
 
14761
14623
  // src/utils/viewStorage.ts
14762
14624
  var ViewStorage = {
@@ -14819,11 +14681,11 @@ var restoreUrlParameter = (currentParam, previousParam, setSearchParams) => {
14819
14681
  }
14820
14682
  };
14821
14683
  var useViewSelection = (config, savedViews, presetViews, openSharedViewModal) => {
14822
- const I18n = useI18nContext10();
14684
+ const I18n = useI18nContext9();
14823
14685
  const storageKey = `savedView_${config.domain}_${config.tableName}_${config.companyId}_${config.projectId}_${config.userId}`;
14824
14686
  const temporaryStorageKey = `${storageKey}-temporary`;
14825
14687
  const [searchParams, setSearchParams] = useSearchParams();
14826
- const previousSavedViewParamRef = useRef2(null);
14688
+ const previousSavedViewParamRef = useRef3(null);
14827
14689
  const [selectedSavedView, setSelectedSavedView] = useState3(() => {
14828
14690
  const stored = ViewStorage.load(storageKey, config.defaultView);
14829
14691
  return stored ?? config.defaultView;
@@ -14894,7 +14756,7 @@ var useViewSelection = (config, savedViews, presetViews, openSharedViewModal) =>
14894
14756
  },
14895
14757
  [isViewAlreadySelected, openSharedViewModal, allViews, selectView]
14896
14758
  );
14897
- useEffect2(() => {
14759
+ useEffect3(() => {
14898
14760
  const savedViewId = searchParams.get("saved-view");
14899
14761
  restoreUrlParameter(
14900
14762
  savedViewId,
@@ -14918,6 +14780,177 @@ var useViewSelection = (config, savedViews, presetViews, openSharedViewModal) =>
14918
14780
  };
14919
14781
  };
14920
14782
 
14783
+ // node_modules/@procore/core-http/dist/modern/index.js
14784
+ function getCSRFToken() {
14785
+ const token = document.cookie.match("(^|;)\\s*csrf_token\\s*=\\s*([^;]+)");
14786
+ return token ? decodeURIComponent(token.pop() || "") : "";
14787
+ }
14788
+ function getCSRFHeader() {
14789
+ const csrfToken = getCSRFToken();
14790
+ return csrfToken ? { "X-CSRF-TOKEN": csrfToken } : {};
14791
+ }
14792
+ function removeLeadingSlash(url) {
14793
+ return url.startsWith("/") ? url.substring(1, url.length) : url;
14794
+ }
14795
+ function removeTrailingSlash(url) {
14796
+ return url.endsWith("/") ? url.substring(0, url.length - 1) : url;
14797
+ }
14798
+ function applyBaseUrl(url, baseUrl) {
14799
+ return `${removeTrailingSlash(baseUrl)}/${removeLeadingSlash(url)}`;
14800
+ }
14801
+ function getOptions({ headers, ...options }) {
14802
+ const opts = {
14803
+ credentials: "same-origin",
14804
+ headers: {
14805
+ ...getCSRFHeader(),
14806
+ ...headers
14807
+ },
14808
+ mode: "same-origin",
14809
+ ...options
14810
+ };
14811
+ return opts;
14812
+ }
14813
+ function getUrl(url, baseUrl) {
14814
+ return baseUrl ? applyBaseUrl(url, baseUrl) : url;
14815
+ }
14816
+ function request(url, { baseUrl, ...options } = {}) {
14817
+ return fetch(getUrl(url, baseUrl), getOptions(options));
14818
+ }
14819
+ function requestJSON(url, requestParams = {}) {
14820
+ return request(url, requestParams).then(
14821
+ (response) => response.json()
14822
+ );
14823
+ }
14824
+
14825
+ // src/utils/api/queries.ts
14826
+ import { useQuery } from "@tanstack/react-query";
14827
+
14828
+ // src/utils/api/queriesHandler.ts
14829
+ import { useMutation, useQueryClient } from "@tanstack/react-query";
14830
+ import { useI18nContext as useI18nContext10 } from "@procore/core-react";
14831
+ var useApiRequest = (props, method, mutationKey) => {
14832
+ const { projectId, companyId, domain, tableName } = props;
14833
+ const queryClient2 = useQueryClient();
14834
+ const { locale: locale2 } = useI18nContext10();
14835
+ return useMutation({
14836
+ mutationKey,
14837
+ mutationFn: async (savedView) => {
14838
+ let url = "";
14839
+ if (method === "DELETE" || method === "PUT") {
14840
+ url = `/rest/v2.0/companies/${companyId}/projects/${projectId}/saved_views/${savedView.share_token}?permissions_domain=${domain}`;
14841
+ } else {
14842
+ url = `/rest/v2.0/companies/${companyId}/projects/${projectId}/saved_views?table_name=${tableName}&permissions_domain=${domain}`;
14843
+ }
14844
+ const response = await requestJSON(url, {
14845
+ method,
14846
+ body: JSON.stringify(savedView),
14847
+ headers: {
14848
+ "Content-Type": "application/json",
14849
+ "Accept-Language": locale2
14850
+ }
14851
+ });
14852
+ if (response.error) {
14853
+ throw response.error;
14854
+ }
14855
+ return response.data;
14856
+ },
14857
+ onSuccess: (savedView) => {
14858
+ if (method === "DELETE" || method === "POST") {
14859
+ queryClient2.invalidateQueries({
14860
+ queryKey: ["savedViews", domain, tableName]
14861
+ });
14862
+ return;
14863
+ } else {
14864
+ const oldData = queryClient2.getQueryData([
14865
+ "savedViews",
14866
+ domain,
14867
+ tableName
14868
+ ]);
14869
+ const oldView = oldData?.find(
14870
+ (item) => item.share_token === savedView.share_token
14871
+ );
14872
+ if (oldView?.name !== savedView.name) {
14873
+ queryClient2.invalidateQueries({
14874
+ queryKey: ["savedViews", domain, tableName]
14875
+ });
14876
+ return;
14877
+ }
14878
+ }
14879
+ queryClient2.setQueryData(
14880
+ ["savedViews", domain, tableName],
14881
+ (oldData) => {
14882
+ if (!oldData)
14883
+ return [savedView];
14884
+ return oldData.map(
14885
+ (item) => item.share_token === savedView.share_token ? savedView : item
14886
+ );
14887
+ }
14888
+ );
14889
+ }
14890
+ });
14891
+ };
14892
+
14893
+ // src/utils/api/queries.ts
14894
+ var PAGE_SIZE = 50 * VIEW_LEVELS.length;
14895
+ var useSavedViewsQuery = (props) => {
14896
+ const { projectId, companyId, domain, tableName } = props;
14897
+ const url = `/rest/v2.0/companies/${companyId}/projects/${projectId}/saved_views?table_name=${tableName}&permissions_domain=${domain}`;
14898
+ return useQuery({
14899
+ queryKey: ["savedViews", domain, tableName],
14900
+ queryFn: async () => {
14901
+ const getUrl2 = `${url}&per_page=${PAGE_SIZE}`;
14902
+ const response = await requestJSON(getUrl2);
14903
+ return response.data;
14904
+ }
14905
+ });
14906
+ };
14907
+ var useSavedViewsPermissions = (props) => {
14908
+ const { projectId, companyId, domain } = props;
14909
+ const url = `/rest/v2.0/companies/${companyId}/projects/${projectId}/saved_views/permissions?permissions_domain=${domain}`;
14910
+ return useQuery({
14911
+ queryKey: ["savedViewsConfig", domain],
14912
+ queryFn: async () => {
14913
+ const response = await requestJSON(url);
14914
+ return response.data;
14915
+ }
14916
+ });
14917
+ };
14918
+ var useCreateSavedView = (props) => useApiRequest(props, "POST", [
14919
+ "createSavedView",
14920
+ props.domain,
14921
+ props.tableName
14922
+ ]);
14923
+ var useUpdateSavedView = (props) => useApiRequest(props, "PUT", [
14924
+ "updateSavedView",
14925
+ props.domain,
14926
+ props.tableName
14927
+ ]);
14928
+ var useDeleteSavedView = (props) => useApiRequest(props, "DELETE", [
14929
+ "deleteSavedView",
14930
+ props.domain,
14931
+ props.tableName
14932
+ ]);
14933
+ var useFetchSavedViewById = (savedViewToken, queryInput, enabled = true) => {
14934
+ const { projectId, companyId } = queryInput;
14935
+ return useQuery({
14936
+ enabled: enabled && Boolean(savedViewToken),
14937
+ queryKey: ["savedView", savedViewToken],
14938
+ queryFn: async () => {
14939
+ const url = `/rest/v2.0/companies/${companyId}/projects/${projectId}/saved_views/${savedViewToken}`;
14940
+ const response = await requestJSON(url);
14941
+ return response.data;
14942
+ }
14943
+ });
14944
+ };
14945
+ var createQueries = (customBackend) => ({
14946
+ useSavedViewsQuery: customBackend?.useSavedViewsQuery ?? useSavedViewsQuery,
14947
+ useSavedViewsPermissions: customBackend?.useSavedViewsPermissions ?? useSavedViewsPermissions,
14948
+ useCreateSavedView: customBackend?.useCreateSavedView ?? useCreateSavedView,
14949
+ useUpdateSavedView: customBackend?.useUpdateSavedView ?? useUpdateSavedView,
14950
+ useDeleteSavedView: customBackend?.useDeleteSavedView ?? useDeleteSavedView,
14951
+ useFetchSavedViewById: customBackend?.useFetchSavedViewById ?? useFetchSavedViewById
14952
+ });
14953
+
14921
14954
  // src/components/saved-views/SavedViews.tsx
14922
14955
  var StyledPanel = styled_components_esm_default.div`
14923
14956
  border: ${({ provider }) => provider === "data-table" ? "1px solid #d6dadc" : "none"};
@@ -14925,14 +14958,15 @@ var StyledPanel = styled_components_esm_default.div`
14925
14958
  var queryClient = new QueryClient();
14926
14959
  var SavedViewsContent = (props) => {
14927
14960
  const { projectId, companyId } = props;
14961
+ const backend = createQueries(props.backend);
14928
14962
  const queryInput = {
14929
14963
  domain: props.domain,
14930
14964
  tableName: props.tableName,
14931
14965
  projectId,
14932
14966
  companyId
14933
14967
  };
14934
- const { data: savedViews } = useSavedViewsQuery(queryInput);
14935
- const { mutate: deleteSavedView } = useDeleteSavedView(queryInput);
14968
+ const { data: savedViews } = backend.useSavedViewsQuery(queryInput);
14969
+ const { mutate: deleteSavedView } = backend.useDeleteSavedView(queryInput);
14936
14970
  const { showToast } = useToastAlertContext3();
14937
14971
  const i18n = useI18nContext11();
14938
14972
  const [activeModal, setActiveModal] = useState4(null);
@@ -14969,7 +15003,7 @@ var SavedViewsContent = (props) => {
14969
15003
  props.presetViews,
14970
15004
  openSharedViewModal
14971
15005
  );
14972
- const { data: fetchedView, isError: fetchError } = useFetchSavedViewById(
15006
+ const { data: fetchedView, isError: fetchError } = backend.useFetchSavedViewById(
14973
15007
  modalData?.viewId ?? null,
14974
15008
  queryInput,
14975
15009
  Boolean(modalData?.viewId)
@@ -14979,8 +15013,8 @@ var SavedViewsContent = (props) => {
14979
15013
  isPending: isCreating,
14980
15014
  error: createError,
14981
15015
  reset: resetCreateError
14982
- } = useCreateSavedView(queryInput);
14983
- useEffect3(() => {
15016
+ } = backend.useCreateSavedView(queryInput);
15017
+ useEffect4(() => {
14984
15018
  if (fetchError) {
14985
15019
  showToast.error(i18n.t("savedViews.errors.notFound"));
14986
15020
  selectView(selectedView ?? props.defaultView);
@@ -15066,7 +15100,8 @@ var SavedViewsContent = (props) => {
15066
15100
  savedViews: allViews,
15067
15101
  provider: props.provider,
15068
15102
  userId: props.userId,
15069
- onClearTemporary: clearTemporaryView
15103
+ onClearTemporary: clearTemporaryView,
15104
+ backend
15070
15105
  }
15071
15106
  ))
15072
15107
  ), (isModalOpen("create" /* CREATE */) || isModalOpen("update" /* UPDATE */)) && /* @__PURE__ */ React22.createElement(
@@ -15081,7 +15116,8 @@ var SavedViewsContent = (props) => {
15081
15116
  selectedSavedView: selectedView,
15082
15117
  onSelect: selectView,
15083
15118
  setOpenEditCreateModal: closeModal,
15084
- defaultView: props.defaultView
15119
+ defaultView: props.defaultView,
15120
+ backend
15085
15121
  }
15086
15122
  ), selectedView && isModalOpen("delete" /* DELETE */) && /* @__PURE__ */ React22.createElement(
15087
15123
  SavedViewsDeleteConfirmationModalShared,
@@ -15126,26 +15162,37 @@ var DEFAULT_COLUMN_STATE = {
15126
15162
  rowGroupIndex: null,
15127
15163
  flex: null
15128
15164
  };
15165
+ var isColGroupDef = (colDef) => {
15166
+ return "children" in colDef && Array.isArray(colDef.children);
15167
+ };
15129
15168
  var getColumnStateFromDefs = (columnDefs) => {
15130
- return columnDefs.map((colDef) => {
15131
- const field = colDef.field ?? colDef.colId;
15132
- if (!field)
15133
- return null;
15134
- return {
15135
- colId: field,
15136
- hide: colDef.hide ?? false,
15137
- pinned: colDef.pinned ?? null,
15138
- width: colDef.width ?? colDef.minWidth ?? DEFAULT_COLUMN_STATE.width,
15139
- sort: null,
15140
- sortIndex: null,
15141
- pivot: false,
15142
- pivotIndex: null,
15143
- aggFunc: null,
15144
- rowGroup: false,
15145
- rowGroupIndex: null,
15146
- flex: colDef.flex ?? null
15147
- };
15148
- }).filter((col) => col !== null);
15169
+ return columnDefs.flatMap((colDef) => {
15170
+ if (isColGroupDef(colDef)) {
15171
+ return getColumnStateFromDefs(colDef.children);
15172
+ }
15173
+ return getColumnStateFromSingleDef(colDef);
15174
+ }).filter(
15175
+ (col) => col !== null
15176
+ );
15177
+ };
15178
+ var getColumnStateFromSingleDef = (colDef) => {
15179
+ const field = colDef.field ?? colDef.colId;
15180
+ if (!field)
15181
+ return null;
15182
+ return {
15183
+ colId: field,
15184
+ hide: colDef.hide ?? false,
15185
+ pinned: colDef.pinned ?? null,
15186
+ width: colDef.width ?? colDef.minWidth ?? DEFAULT_COLUMN_STATE.width,
15187
+ sort: null,
15188
+ sortIndex: null,
15189
+ pivot: false,
15190
+ pivotIndex: null,
15191
+ aggFunc: null,
15192
+ rowGroup: false,
15193
+ rowGroupIndex: null,
15194
+ flex: colDef.flex ?? null
15195
+ };
15149
15196
  };
15150
15197
  var extractDefaultView = (gridApi, receivedConfig) => {
15151
15198
  const columnDefs = gridApi.getColumnDefs() ?? [];
@@ -15172,7 +15219,7 @@ var useNormalizedDefaultViews = (defaultViews, gridApi) => {
15172
15219
  };
15173
15220
 
15174
15221
  // src/components/adapters/smart-grid/useSmartGridConfig.ts
15175
- import { useState as useState5, useEffect as useEffect4 } from "react";
15222
+ import { useState as useState5, useEffect as useEffect5, useRef as useRef4 } from "react";
15176
15223
  var GRID_STATE_EVENTS = [
15177
15224
  "sortChanged",
15178
15225
  "filterOpened",
@@ -15191,10 +15238,14 @@ var useSmartGridConfig = (gridApi) => {
15191
15238
  const [config, setConfig] = useState5(
15192
15239
  () => getSmartGridConfig(gridApi)
15193
15240
  );
15194
- useEffect4(() => {
15241
+ const eventListenersDisabledRef = useRef4(false);
15242
+ useEffect5(() => {
15195
15243
  if (!gridApi)
15196
15244
  return;
15197
15245
  const updateConfig = () => {
15246
+ if (eventListenersDisabledRef.current) {
15247
+ return;
15248
+ }
15198
15249
  setConfig(getSmartGridConfig(gridApi));
15199
15250
  };
15200
15251
  GRID_STATE_EVENTS.forEach((event) => {
@@ -15206,7 +15257,13 @@ var useSmartGridConfig = (gridApi) => {
15206
15257
  });
15207
15258
  };
15208
15259
  }, [gridApi]);
15209
- return { config, setConfig };
15260
+ const disableEventListeners = () => {
15261
+ eventListenersDisabledRef.current = true;
15262
+ };
15263
+ const enableEventListeners = () => {
15264
+ eventListenersDisabledRef.current = false;
15265
+ };
15266
+ return { config, setConfig, disableEventListeners, enableEventListeners };
15210
15267
  };
15211
15268
 
15212
15269
  // src/components/adapters/smart-grid/SmartGridSavedViews.tsx
@@ -15250,7 +15307,8 @@ var SmartGridSavedViews = (props) => {
15250
15307
  defaultView,
15251
15308
  presetViews,
15252
15309
  tableName: props.tableName,
15253
- tableConfig
15310
+ tableConfig,
15311
+ backend: props.backend
15254
15312
  }
15255
15313
  );
15256
15314
  };