@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.
@@ -11387,7 +11387,7 @@ var SavedViewCollectionMenuItem = (props) => {
11387
11387
  loading: props.isUpdateProcessing
11388
11388
  },
11389
11389
  i18n.t("savedViews.actions.update")
11390
- )), props.item.view_level !== "default" && props.selected && !props.canUpdate && props.item.id !== "temporary" && /* @__PURE__ */ React15.createElement("div", null, /* @__PURE__ */ React15.createElement(
11390
+ )), (props.enableSharingViews ?? true) && props.item.view_level !== "default" && props.selected && !props.canUpdate && props.item.id !== "temporary" && /* @__PURE__ */ React15.createElement("div", null, /* @__PURE__ */ React15.createElement(
11391
11391
  Button2,
11392
11392
  {
11393
11393
  onClick: copyShareLink,
@@ -11436,176 +11436,13 @@ var ExpandedPanel = styled_components_esm_default(Panel)`
11436
11436
  `;
11437
11437
 
11438
11438
  // src/components/panels/PanelContent.tsx
11439
- import { Flex as Flex3, useI18nContext as useI18nContext5 } from "@procore/core-react";
11439
+ import { Flex as Flex3, useI18nContext as useI18nContext4 } from "@procore/core-react";
11440
11440
  import { useToastAlertContext as useToastAlertContext2 } from "@procore/toast-alert";
11441
11441
  import React17 from "react";
11442
11442
 
11443
- // node_modules/@procore/core-http/dist/modern/index.js
11444
- function getCSRFToken() {
11445
- const token = document.cookie.match("(^|;)\\s*csrf_token\\s*=\\s*([^;]+)");
11446
- return token ? decodeURIComponent(token.pop() || "") : "";
11447
- }
11448
- function getCSRFHeader() {
11449
- const csrfToken = getCSRFToken();
11450
- return csrfToken ? { "X-CSRF-TOKEN": csrfToken } : {};
11451
- }
11452
- function removeLeadingSlash(url) {
11453
- return url.startsWith("/") ? url.substring(1, url.length) : url;
11454
- }
11455
- function removeTrailingSlash(url) {
11456
- return url.endsWith("/") ? url.substring(0, url.length - 1) : url;
11457
- }
11458
- function applyBaseUrl(url, baseUrl) {
11459
- return `${removeTrailingSlash(baseUrl)}/${removeLeadingSlash(url)}`;
11460
- }
11461
- function getOptions({ headers, ...options }) {
11462
- const opts = {
11463
- credentials: "same-origin",
11464
- headers: {
11465
- ...getCSRFHeader(),
11466
- ...headers
11467
- },
11468
- mode: "same-origin",
11469
- ...options
11470
- };
11471
- return opts;
11472
- }
11473
- function getUrl(url, baseUrl) {
11474
- return baseUrl ? applyBaseUrl(url, baseUrl) : url;
11475
- }
11476
- function request(url, { baseUrl, ...options } = {}) {
11477
- return fetch(getUrl(url, baseUrl), getOptions(options));
11478
- }
11479
- function requestJSON(url, requestParams = {}) {
11480
- return request(url, requestParams).then(
11481
- (response) => response.json()
11482
- );
11483
- }
11484
-
11485
- // src/utils/api/queries.ts
11486
- import { useQuery } from "@tanstack/react-query";
11487
-
11488
- // src/utils/api/queriesHandler.ts
11489
- import { useMutation, useQueryClient } from "@tanstack/react-query";
11490
- import { useI18nContext as useI18nContext3 } from "@procore/core-react";
11491
- var useApiRequest = (props, method, mutationKey) => {
11492
- const { projectId, companyId, domain, tableName } = props;
11493
- const queryClient2 = useQueryClient();
11494
- const { locale: locale2 } = useI18nContext3();
11495
- return useMutation({
11496
- mutationKey,
11497
- mutationFn: async (savedView) => {
11498
- let url = "";
11499
- if (method === "DELETE" || method === "PUT") {
11500
- url = `/rest/v2.0/companies/${companyId}/projects/${projectId}/saved_views/${savedView.share_token}?permissions_domain=${domain}`;
11501
- } else {
11502
- url = `/rest/v2.0/companies/${companyId}/projects/${projectId}/saved_views?table_name=${tableName}&permissions_domain=${domain}`;
11503
- }
11504
- const response = await requestJSON(url, {
11505
- method,
11506
- body: JSON.stringify(savedView),
11507
- headers: {
11508
- "Content-Type": "application/json",
11509
- "Accept-Language": locale2
11510
- }
11511
- });
11512
- if (response.error) {
11513
- throw response.error;
11514
- }
11515
- return response.data;
11516
- },
11517
- onSuccess: (savedView) => {
11518
- if (method === "DELETE" || method === "POST") {
11519
- queryClient2.invalidateQueries({
11520
- queryKey: ["savedViews", domain, tableName]
11521
- });
11522
- return;
11523
- } else {
11524
- const oldData = queryClient2.getQueryData([
11525
- "savedViews",
11526
- domain,
11527
- tableName
11528
- ]);
11529
- const oldView = oldData == null ? void 0 : oldData.find(
11530
- (item) => item.share_token === savedView.share_token
11531
- );
11532
- if ((oldView == null ? void 0 : oldView.name) !== savedView.name) {
11533
- queryClient2.invalidateQueries({
11534
- queryKey: ["savedViews", domain, tableName]
11535
- });
11536
- return;
11537
- }
11538
- }
11539
- queryClient2.setQueryData(
11540
- ["savedViews", domain, tableName],
11541
- (oldData) => {
11542
- if (!oldData)
11543
- return [savedView];
11544
- return oldData.map(
11545
- (item) => item.share_token === savedView.share_token ? savedView : item
11546
- );
11547
- }
11548
- );
11549
- }
11550
- });
11551
- };
11552
-
11553
11443
  // src/utils/constants/viewLevels.ts
11554
11444
  var VIEW_LEVELS = ["company", "project", "personal"];
11555
11445
 
11556
- // src/utils/api/queries.ts
11557
- var PAGE_SIZE = 50 * VIEW_LEVELS.length;
11558
- var useSavedViewsQuery = (props) => {
11559
- const { projectId, companyId, domain, tableName } = props;
11560
- const url = `/rest/v2.0/companies/${companyId}/projects/${projectId}/saved_views?table_name=${tableName}&permissions_domain=${domain}`;
11561
- return useQuery({
11562
- queryKey: ["savedViews", domain, tableName],
11563
- queryFn: async () => {
11564
- const getUrl2 = `${url}&per_page=${PAGE_SIZE}`;
11565
- const response = await requestJSON(getUrl2);
11566
- return response.data;
11567
- }
11568
- });
11569
- };
11570
- var useSavedViewsPermissions = (props) => {
11571
- const { projectId, companyId, domain } = props;
11572
- const url = `/rest/v2.0/companies/${companyId}/projects/${projectId}/saved_views/permissions?permissions_domain=${domain}`;
11573
- return useQuery({
11574
- queryKey: ["savedViewsConfig", domain],
11575
- queryFn: async () => {
11576
- const response = await requestJSON(url);
11577
- return response.data;
11578
- }
11579
- });
11580
- };
11581
- var useCreateSavedView = (props) => useApiRequest(props, "POST", [
11582
- "createSavedView",
11583
- props.domain,
11584
- props.tableName
11585
- ]);
11586
- var useUpdateSavedView = (props) => useApiRequest(props, "PUT", [
11587
- "updateSavedView",
11588
- props.domain,
11589
- props.tableName
11590
- ]);
11591
- var useDeleteSavedView = (props) => useApiRequest(props, "DELETE", [
11592
- "deleteSavedView",
11593
- props.domain,
11594
- props.tableName
11595
- ]);
11596
- var useFetchSavedViewById = (savedViewToken, queryInput, enabled = true) => {
11597
- const { projectId, companyId } = queryInput;
11598
- return useQuery({
11599
- enabled: enabled && Boolean(savedViewToken),
11600
- queryKey: ["savedView", savedViewToken],
11601
- queryFn: async () => {
11602
- const url = `/rest/v2.0/companies/${companyId}/projects/${projectId}/saved_views/${savedViewToken}`;
11603
- const response = await requestJSON(url);
11604
- return response.data;
11605
- }
11606
- });
11607
- };
11608
-
11609
11446
  // src/components/panels/PanelContentUtils.ts
11610
11447
  var import_lodash = __toESM(require_lodash());
11611
11448
 
@@ -11755,12 +11592,13 @@ var normalizeForComparison = (config) => {
11755
11592
  if (!(config == null ? void 0 : config.columnState))
11756
11593
  return config;
11757
11594
  return {
11758
- ...config,
11595
+ ...import_lodash.default.omit(config, ["enableRowGrouping", "enableColumnGrouping"]),
11759
11596
  columnState: config.columnState.map((col) => {
11597
+ const res = import_lodash.default.omit(col, ["aggFunc"]);
11760
11598
  if (col.flex) {
11761
- return import_lodash.default.omit(col, ["width", "flex"]);
11599
+ return import_lodash.default.omit(res, ["width", "flex"]);
11762
11600
  }
11763
- return col;
11601
+ return res;
11764
11602
  })
11765
11603
  };
11766
11604
  };
@@ -11773,10 +11611,9 @@ var isEqual = (viewTableConfig, tableConfig, defaultViewConfig, provider) => {
11773
11611
  );
11774
11612
  const normalizedViewConfig = normalizeForComparison(syncedViewTableConfig);
11775
11613
  const normalizedCurrentConfig = normalizeForComparison(tableConfig);
11776
- return import_lodash.default.isEqual(
11777
- cleanObject(normalizedViewConfig, provider),
11778
- cleanObject(normalizedCurrentConfig, provider)
11779
- );
11614
+ const cleanedViewConfig = cleanObject(normalizedViewConfig, provider);
11615
+ const cleanedCurrentConfig = cleanObject(normalizedCurrentConfig, provider);
11616
+ return import_lodash.default.isEqual(cleanedViewConfig, cleanedCurrentConfig);
11780
11617
  };
11781
11618
  var hasPermissionForViewLevel = (viewLevel, permissions) => {
11782
11619
  switch (viewLevel) {
@@ -11809,7 +11646,7 @@ import {
11809
11646
  Flex as Flex2,
11810
11647
  spacing,
11811
11648
  Typography,
11812
- useI18nContext as useI18nContext4
11649
+ useI18nContext as useI18nContext3
11813
11650
  } from "@procore/core-react";
11814
11651
  import React16 from "react";
11815
11652
  var groupIcon = (group) => {
@@ -11829,7 +11666,7 @@ var Header = styled_components_esm_default(Flex2)`
11829
11666
  }
11830
11667
  `;
11831
11668
  var ViewLevelHeader = ({ expanded, toggleGroup, group }) => {
11832
- const I18n = useI18nContext4();
11669
+ const I18n = useI18nContext3();
11833
11670
  return /* @__PURE__ */ React16.createElement(
11834
11671
  Header,
11835
11672
  {
@@ -11886,9 +11723,9 @@ var Panel2 = styled_components_esm_default(DetailPage.Card)`
11886
11723
  var PanelContent = (props) => {
11887
11724
  const { queryInput, selectedSavedView, tableConfig } = props;
11888
11725
  const { showToast } = useToastAlertContext2();
11889
- const I18n = useI18nContext5();
11890
- const { data: savedViewsFromQuery, error: savedViewsError } = useSavedViewsQuery(props.queryInput);
11891
- const updateMutation = useUpdateSavedView(queryInput);
11726
+ const I18n = useI18nContext4();
11727
+ const { data: savedViewsFromQuery, error: savedViewsError } = props.backend.useSavedViewsQuery(props.queryInput);
11728
+ const updateMutation = props.backend.useUpdateSavedView(queryInput);
11892
11729
  const { mutate: updateSavedView } = updateMutation;
11893
11730
  const isUpdateLoading = "isPending" in updateMutation ? updateMutation.isPending : updateMutation.isLoading ?? false;
11894
11731
  const savedViews = props.savedViews ?? savedViewsFromQuery;
@@ -11899,7 +11736,9 @@ var PanelContent = (props) => {
11899
11736
  errorToastRef.current = savedViewsError;
11900
11737
  }
11901
11738
  }, [savedViewsError, showToast, I18n]);
11902
- const { data: permissions } = useSavedViewsPermissions(props.queryInput);
11739
+ const { data: permissions } = props.backend.useSavedViewsPermissions(
11740
+ props.queryInput
11741
+ );
11903
11742
  const selectedRowRef = useScrollToRef(savedViews);
11904
11743
  const { groups, toggleGroup } = useGroups();
11905
11744
  const isTemporarySelected = (selectedSavedView == null ? void 0 : selectedSavedView.id) === "temporary";
@@ -11933,7 +11772,8 @@ var PanelContent = (props) => {
11933
11772
  {
11934
11773
  item: temporaryView,
11935
11774
  selected: isTemporarySelected,
11936
- onClearTemporary: props.onClearTemporary
11775
+ onClearTemporary: props.onClearTemporary,
11776
+ enableSharingViews: false
11937
11777
  }
11938
11778
  )
11939
11779
  ), presetViews.map((presetView) => {
@@ -11950,7 +11790,8 @@ var PanelContent = (props) => {
11950
11790
  SavedViewCollectionMenuItem,
11951
11791
  {
11952
11792
  item: presetView,
11953
- selected: isSelected
11793
+ selected: isSelected,
11794
+ enableSharingViews: false
11954
11795
  }
11955
11796
  )
11956
11797
  );
@@ -11998,7 +11839,8 @@ var PanelContent = (props) => {
11998
11839
  isUpdateProcessing: isUpdateLoading,
11999
11840
  onEdit: () => props.openModal("update" /* UPDATE */),
12000
11841
  onDelete: props.onDelete,
12001
- permissions
11842
+ permissions,
11843
+ enableSharingViews: false
12002
11844
  }
12003
11845
  )
12004
11846
  );
@@ -12015,7 +11857,7 @@ import {
12015
11857
  Tooltip,
12016
11858
  useI18nContext as useI18nContext11
12017
11859
  } from "@procore/core-react";
12018
- import React22, { useState as useState4, useEffect as useEffect3, useCallback as useCallback3 } from "react";
11860
+ import React22, { useState as useState4, useEffect as useEffect4, useCallback as useCallback3 } from "react";
12019
11861
  import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
12020
11862
  import { useToastAlertContext as useToastAlertContext3, ToastAlertProvider } from "@procore/toast-alert";
12021
11863
 
@@ -12025,7 +11867,7 @@ import {
12025
11867
  ConfirmModal,
12026
11868
  Modal,
12027
11869
  P as P2,
12028
- useI18nContext as useI18nContext6
11870
+ useI18nContext as useI18nContext5
12029
11871
  } from "@procore/core-react";
12030
11872
  import React18 from "react";
12031
11873
  var SavedViewsDeleteConfirmationModalShared = ({
@@ -12033,7 +11875,7 @@ var SavedViewsDeleteConfirmationModalShared = ({
12033
11875
  onDelete,
12034
11876
  open
12035
11877
  }) => {
12036
- const i18n = useI18nContext6();
11878
+ const i18n = useI18nContext5();
12037
11879
  return /* @__PURE__ */ React18.createElement(
12038
11880
  ConfirmModal,
12039
11881
  {
@@ -12064,7 +11906,7 @@ import {
12064
11906
  Modal as Modal2,
12065
11907
  spacing as spacing3,
12066
11908
  Typography as Typography2,
12067
- useI18nContext as useI18nContext7
11909
+ useI18nContext as useI18nContext6
12068
11910
  } from "@procore/core-react";
12069
11911
  import * as React19 from "react";
12070
11912
 
@@ -14394,6 +14236,7 @@ function extractMessage(error, I18n) {
14394
14236
  }
14395
14237
 
14396
14238
  // src/components/modals/form-modal/FormModalBase.tsx
14239
+ var { useEffect: useEffect2, useRef: useRef2 } = React19;
14397
14240
  var ScrollContainer = styled_components_esm_default("div")`
14398
14241
  overflow: auto;
14399
14242
  `;
@@ -14410,22 +14253,38 @@ var FormModalBase = ({
14410
14253
  defaultView,
14411
14254
  selectedSavedView,
14412
14255
  setOpenEditCreateModal,
14413
- onSelect
14256
+ onSelect,
14257
+ backend
14414
14258
  }) => {
14415
- const I18n = useI18nContext7();
14259
+ const I18n = useI18nContext6();
14416
14260
  const NAME_MAX_LENGTH = 150;
14261
+ const originalBodyWidth = useRef2("");
14262
+ useEffect2(() => {
14263
+ if (open) {
14264
+ originalBodyWidth.current = document.body.style.width || "";
14265
+ document.body.style.width = "100%";
14266
+ } else {
14267
+ document.body.style.width = originalBodyWidth.current;
14268
+ }
14269
+ return () => {
14270
+ if (originalBodyWidth.current !== void 0) {
14271
+ document.body.style.width = originalBodyWidth.current;
14272
+ }
14273
+ };
14274
+ }, [open]);
14275
+ const { useCreateSavedView: useCreateSavedView2, useUpdateSavedView: useUpdateSavedView2, useSavedViewsPermissions: useSavedViewsPermissions2 } = backend;
14417
14276
  const {
14418
14277
  mutate: createSavedView,
14419
14278
  isPending: isCreating,
14420
14279
  error: createError,
14421
14280
  reset: resetCreateMutation
14422
- } = useCreateSavedView(queryInput);
14281
+ } = useCreateSavedView2(queryInput);
14423
14282
  const {
14424
14283
  mutate: updateSavedView,
14425
14284
  isPending: isUpdating,
14426
14285
  error: updateError,
14427
14286
  reset: resetUpdateMutation
14428
- } = useUpdateSavedView(queryInput);
14287
+ } = useUpdateSavedView2(queryInput);
14429
14288
  const resetMutations = () => {
14430
14289
  resetCreateMutation();
14431
14290
  resetUpdateMutation();
@@ -14434,7 +14293,7 @@ var FormModalBase = ({
14434
14293
  resetMutations();
14435
14294
  onCancel();
14436
14295
  };
14437
- const { data: permissions } = useSavedViewsPermissions(queryInput);
14296
+ const { data: permissions } = useSavedViewsPermissions2(queryInput);
14438
14297
  const isLoading = isCreating || isUpdating;
14439
14298
  const errors = extractMessage(createError || updateError, I18n);
14440
14299
  const handleOnSubmit = (data) => {
@@ -14545,6 +14404,7 @@ var FormModalBase = ({
14545
14404
  Form.Select,
14546
14405
  {
14547
14406
  name: "view_level",
14407
+ qa: { label: "view-level" },
14548
14408
  options: viewLevelOptions,
14549
14409
  label: I18n.t("savedViews.modal.fields.viewLevel"),
14550
14410
  colWidth: 12,
@@ -14568,7 +14428,7 @@ var FormModalBase = ({
14568
14428
  };
14569
14429
 
14570
14430
  // src/components/modals/form-modal/FormModal.tsx
14571
- import { useI18nContext as useI18nContext8 } from "@procore/core-react";
14431
+ import { useI18nContext as useI18nContext7 } from "@procore/core-react";
14572
14432
  var FormModal = ({
14573
14433
  open,
14574
14434
  mode,
@@ -14579,9 +14439,10 @@ var FormModal = ({
14579
14439
  selectedSavedView,
14580
14440
  setOpenEditCreateModal,
14581
14441
  onSelect,
14582
- defaultView
14442
+ defaultView,
14443
+ backend
14583
14444
  }) => {
14584
- const i18n = useI18nContext8();
14445
+ const i18n = useI18nContext7();
14585
14446
  return /* @__PURE__ */ React20.createElement(
14586
14447
  FormModalBase,
14587
14448
  {
@@ -14597,7 +14458,8 @@ var FormModal = ({
14597
14458
  selectedSavedView,
14598
14459
  setOpenEditCreateModal,
14599
14460
  onSelect,
14600
- defaultView
14461
+ defaultView,
14462
+ backend
14601
14463
  }
14602
14464
  );
14603
14465
  };
@@ -14614,7 +14476,7 @@ import {
14614
14476
  P as P3,
14615
14477
  spacing as spacing4,
14616
14478
  Typography as Typography3,
14617
- useI18nContext as useI18nContext9
14479
+ useI18nContext as useI18nContext8
14618
14480
  } from "@procore/core-react";
14619
14481
  import * as React21 from "react";
14620
14482
  var SharedViewFormModal = ({
@@ -14627,7 +14489,7 @@ var SharedViewFormModal = ({
14627
14489
  isCreating,
14628
14490
  resetCreateError
14629
14491
  }) => {
14630
- const I18n = useI18nContext9();
14492
+ const I18n = useI18nContext8();
14631
14493
  const NAME_MAX_LENGTH = 150;
14632
14494
  const errors = extractMessage(createError, I18n);
14633
14495
  const handleNameChange = () => {
@@ -14757,9 +14619,9 @@ var SharedViewFormModal = ({
14757
14619
  };
14758
14620
 
14759
14621
  // src/utils/hooks/useViewSelection.ts
14760
- import { useState as useState3, useCallback as useCallback2, useEffect as useEffect2, useRef as useRef2, useMemo } from "react";
14622
+ import { useState as useState3, useCallback as useCallback2, useEffect as useEffect3, useRef as useRef3, useMemo } from "react";
14761
14623
  import { useSearchParams } from "react-router-dom";
14762
- import { useI18nContext as useI18nContext10 } from "@procore/core-react";
14624
+ import { useI18nContext as useI18nContext9 } from "@procore/core-react";
14763
14625
 
14764
14626
  // src/utils/viewStorage.ts
14765
14627
  var ViewStorage = {
@@ -14822,11 +14684,11 @@ var restoreUrlParameter = (currentParam, previousParam, setSearchParams) => {
14822
14684
  }
14823
14685
  };
14824
14686
  var useViewSelection = (config, savedViews, presetViews, openSharedViewModal) => {
14825
- const I18n = useI18nContext10();
14687
+ const I18n = useI18nContext9();
14826
14688
  const storageKey = `savedView_${config.domain}_${config.tableName}_${config.companyId}_${config.projectId}_${config.userId}`;
14827
14689
  const temporaryStorageKey = `${storageKey}-temporary`;
14828
14690
  const [searchParams, setSearchParams] = useSearchParams();
14829
- const previousSavedViewParamRef = useRef2(null);
14691
+ const previousSavedViewParamRef = useRef3(null);
14830
14692
  const [selectedSavedView, setSelectedSavedView] = useState3(() => {
14831
14693
  const stored = ViewStorage.load(storageKey, config.defaultView);
14832
14694
  return stored ?? config.defaultView;
@@ -14897,7 +14759,7 @@ var useViewSelection = (config, savedViews, presetViews, openSharedViewModal) =>
14897
14759
  },
14898
14760
  [isViewAlreadySelected, openSharedViewModal, allViews, selectView]
14899
14761
  );
14900
- useEffect2(() => {
14762
+ useEffect3(() => {
14901
14763
  const savedViewId = searchParams.get("saved-view");
14902
14764
  restoreUrlParameter(
14903
14765
  savedViewId,
@@ -14921,6 +14783,177 @@ var useViewSelection = (config, savedViews, presetViews, openSharedViewModal) =>
14921
14783
  };
14922
14784
  };
14923
14785
 
14786
+ // node_modules/@procore/core-http/dist/modern/index.js
14787
+ function getCSRFToken() {
14788
+ const token = document.cookie.match("(^|;)\\s*csrf_token\\s*=\\s*([^;]+)");
14789
+ return token ? decodeURIComponent(token.pop() || "") : "";
14790
+ }
14791
+ function getCSRFHeader() {
14792
+ const csrfToken = getCSRFToken();
14793
+ return csrfToken ? { "X-CSRF-TOKEN": csrfToken } : {};
14794
+ }
14795
+ function removeLeadingSlash(url) {
14796
+ return url.startsWith("/") ? url.substring(1, url.length) : url;
14797
+ }
14798
+ function removeTrailingSlash(url) {
14799
+ return url.endsWith("/") ? url.substring(0, url.length - 1) : url;
14800
+ }
14801
+ function applyBaseUrl(url, baseUrl) {
14802
+ return `${removeTrailingSlash(baseUrl)}/${removeLeadingSlash(url)}`;
14803
+ }
14804
+ function getOptions({ headers, ...options }) {
14805
+ const opts = {
14806
+ credentials: "same-origin",
14807
+ headers: {
14808
+ ...getCSRFHeader(),
14809
+ ...headers
14810
+ },
14811
+ mode: "same-origin",
14812
+ ...options
14813
+ };
14814
+ return opts;
14815
+ }
14816
+ function getUrl(url, baseUrl) {
14817
+ return baseUrl ? applyBaseUrl(url, baseUrl) : url;
14818
+ }
14819
+ function request(url, { baseUrl, ...options } = {}) {
14820
+ return fetch(getUrl(url, baseUrl), getOptions(options));
14821
+ }
14822
+ function requestJSON(url, requestParams = {}) {
14823
+ return request(url, requestParams).then(
14824
+ (response) => response.json()
14825
+ );
14826
+ }
14827
+
14828
+ // src/utils/api/queries.ts
14829
+ import { useQuery } from "@tanstack/react-query";
14830
+
14831
+ // src/utils/api/queriesHandler.ts
14832
+ import { useMutation, useQueryClient } from "@tanstack/react-query";
14833
+ import { useI18nContext as useI18nContext10 } from "@procore/core-react";
14834
+ var useApiRequest = (props, method, mutationKey) => {
14835
+ const { projectId, companyId, domain, tableName } = props;
14836
+ const queryClient2 = useQueryClient();
14837
+ const { locale: locale2 } = useI18nContext10();
14838
+ return useMutation({
14839
+ mutationKey,
14840
+ mutationFn: async (savedView) => {
14841
+ let url = "";
14842
+ if (method === "DELETE" || method === "PUT") {
14843
+ url = `/rest/v2.0/companies/${companyId}/projects/${projectId}/saved_views/${savedView.share_token}?permissions_domain=${domain}`;
14844
+ } else {
14845
+ url = `/rest/v2.0/companies/${companyId}/projects/${projectId}/saved_views?table_name=${tableName}&permissions_domain=${domain}`;
14846
+ }
14847
+ const response = await requestJSON(url, {
14848
+ method,
14849
+ body: JSON.stringify(savedView),
14850
+ headers: {
14851
+ "Content-Type": "application/json",
14852
+ "Accept-Language": locale2
14853
+ }
14854
+ });
14855
+ if (response.error) {
14856
+ throw response.error;
14857
+ }
14858
+ return response.data;
14859
+ },
14860
+ onSuccess: (savedView) => {
14861
+ if (method === "DELETE" || method === "POST") {
14862
+ queryClient2.invalidateQueries({
14863
+ queryKey: ["savedViews", domain, tableName]
14864
+ });
14865
+ return;
14866
+ } else {
14867
+ const oldData = queryClient2.getQueryData([
14868
+ "savedViews",
14869
+ domain,
14870
+ tableName
14871
+ ]);
14872
+ const oldView = oldData == null ? void 0 : oldData.find(
14873
+ (item) => item.share_token === savedView.share_token
14874
+ );
14875
+ if ((oldView == null ? void 0 : oldView.name) !== savedView.name) {
14876
+ queryClient2.invalidateQueries({
14877
+ queryKey: ["savedViews", domain, tableName]
14878
+ });
14879
+ return;
14880
+ }
14881
+ }
14882
+ queryClient2.setQueryData(
14883
+ ["savedViews", domain, tableName],
14884
+ (oldData) => {
14885
+ if (!oldData)
14886
+ return [savedView];
14887
+ return oldData.map(
14888
+ (item) => item.share_token === savedView.share_token ? savedView : item
14889
+ );
14890
+ }
14891
+ );
14892
+ }
14893
+ });
14894
+ };
14895
+
14896
+ // src/utils/api/queries.ts
14897
+ var PAGE_SIZE = 50 * VIEW_LEVELS.length;
14898
+ var useSavedViewsQuery = (props) => {
14899
+ const { projectId, companyId, domain, tableName } = props;
14900
+ const url = `/rest/v2.0/companies/${companyId}/projects/${projectId}/saved_views?table_name=${tableName}&permissions_domain=${domain}`;
14901
+ return useQuery({
14902
+ queryKey: ["savedViews", domain, tableName],
14903
+ queryFn: async () => {
14904
+ const getUrl2 = `${url}&per_page=${PAGE_SIZE}`;
14905
+ const response = await requestJSON(getUrl2);
14906
+ return response.data;
14907
+ }
14908
+ });
14909
+ };
14910
+ var useSavedViewsPermissions = (props) => {
14911
+ const { projectId, companyId, domain } = props;
14912
+ const url = `/rest/v2.0/companies/${companyId}/projects/${projectId}/saved_views/permissions?permissions_domain=${domain}`;
14913
+ return useQuery({
14914
+ queryKey: ["savedViewsConfig", domain],
14915
+ queryFn: async () => {
14916
+ const response = await requestJSON(url);
14917
+ return response.data;
14918
+ }
14919
+ });
14920
+ };
14921
+ var useCreateSavedView = (props) => useApiRequest(props, "POST", [
14922
+ "createSavedView",
14923
+ props.domain,
14924
+ props.tableName
14925
+ ]);
14926
+ var useUpdateSavedView = (props) => useApiRequest(props, "PUT", [
14927
+ "updateSavedView",
14928
+ props.domain,
14929
+ props.tableName
14930
+ ]);
14931
+ var useDeleteSavedView = (props) => useApiRequest(props, "DELETE", [
14932
+ "deleteSavedView",
14933
+ props.domain,
14934
+ props.tableName
14935
+ ]);
14936
+ var useFetchSavedViewById = (savedViewToken, queryInput, enabled = true) => {
14937
+ const { projectId, companyId } = queryInput;
14938
+ return useQuery({
14939
+ enabled: enabled && Boolean(savedViewToken),
14940
+ queryKey: ["savedView", savedViewToken],
14941
+ queryFn: async () => {
14942
+ const url = `/rest/v2.0/companies/${companyId}/projects/${projectId}/saved_views/${savedViewToken}`;
14943
+ const response = await requestJSON(url);
14944
+ return response.data;
14945
+ }
14946
+ });
14947
+ };
14948
+ var createQueries = (customBackend) => ({
14949
+ useSavedViewsQuery: (customBackend == null ? void 0 : customBackend.useSavedViewsQuery) ?? useSavedViewsQuery,
14950
+ useSavedViewsPermissions: (customBackend == null ? void 0 : customBackend.useSavedViewsPermissions) ?? useSavedViewsPermissions,
14951
+ useCreateSavedView: (customBackend == null ? void 0 : customBackend.useCreateSavedView) ?? useCreateSavedView,
14952
+ useUpdateSavedView: (customBackend == null ? void 0 : customBackend.useUpdateSavedView) ?? useUpdateSavedView,
14953
+ useDeleteSavedView: (customBackend == null ? void 0 : customBackend.useDeleteSavedView) ?? useDeleteSavedView,
14954
+ useFetchSavedViewById: (customBackend == null ? void 0 : customBackend.useFetchSavedViewById) ?? useFetchSavedViewById
14955
+ });
14956
+
14924
14957
  // src/components/saved-views/SavedViews.tsx
14925
14958
  var StyledPanel = styled_components_esm_default.div`
14926
14959
  border: ${({ provider }) => provider === "data-table" ? "1px solid #d6dadc" : "none"};
@@ -14928,14 +14961,15 @@ var StyledPanel = styled_components_esm_default.div`
14928
14961
  var queryClient = new QueryClient();
14929
14962
  var SavedViewsContent = (props) => {
14930
14963
  const { projectId, companyId } = props;
14964
+ const backend = createQueries(props.backend);
14931
14965
  const queryInput = {
14932
14966
  domain: props.domain,
14933
14967
  tableName: props.tableName,
14934
14968
  projectId,
14935
14969
  companyId
14936
14970
  };
14937
- const { data: savedViews } = useSavedViewsQuery(queryInput);
14938
- const { mutate: deleteSavedView } = useDeleteSavedView(queryInput);
14971
+ const { data: savedViews } = backend.useSavedViewsQuery(queryInput);
14972
+ const { mutate: deleteSavedView } = backend.useDeleteSavedView(queryInput);
14939
14973
  const { showToast } = useToastAlertContext3();
14940
14974
  const i18n = useI18nContext11();
14941
14975
  const [activeModal, setActiveModal] = useState4(null);
@@ -14972,7 +15006,7 @@ var SavedViewsContent = (props) => {
14972
15006
  props.presetViews,
14973
15007
  openSharedViewModal
14974
15008
  );
14975
- const { data: fetchedView, isError: fetchError } = useFetchSavedViewById(
15009
+ const { data: fetchedView, isError: fetchError } = backend.useFetchSavedViewById(
14976
15010
  (modalData == null ? void 0 : modalData.viewId) ?? null,
14977
15011
  queryInput,
14978
15012
  Boolean(modalData == null ? void 0 : modalData.viewId)
@@ -14982,8 +15016,8 @@ var SavedViewsContent = (props) => {
14982
15016
  isPending: isCreating,
14983
15017
  error: createError,
14984
15018
  reset: resetCreateError
14985
- } = useCreateSavedView(queryInput);
14986
- useEffect3(() => {
15019
+ } = backend.useCreateSavedView(queryInput);
15020
+ useEffect4(() => {
14987
15021
  if (fetchError) {
14988
15022
  showToast.error(i18n.t("savedViews.errors.notFound"));
14989
15023
  selectView(selectedView ?? props.defaultView);
@@ -15069,7 +15103,8 @@ var SavedViewsContent = (props) => {
15069
15103
  savedViews: allViews,
15070
15104
  provider: props.provider,
15071
15105
  userId: props.userId,
15072
- onClearTemporary: clearTemporaryView
15106
+ onClearTemporary: clearTemporaryView,
15107
+ backend
15073
15108
  }
15074
15109
  ))
15075
15110
  ), (isModalOpen("create" /* CREATE */) || isModalOpen("update" /* UPDATE */)) && /* @__PURE__ */ React22.createElement(
@@ -15084,7 +15119,8 @@ var SavedViewsContent = (props) => {
15084
15119
  selectedSavedView: selectedView,
15085
15120
  onSelect: selectView,
15086
15121
  setOpenEditCreateModal: closeModal,
15087
- defaultView: props.defaultView
15122
+ defaultView: props.defaultView,
15123
+ backend
15088
15124
  }
15089
15125
  ), selectedView && isModalOpen("delete" /* DELETE */) && /* @__PURE__ */ React22.createElement(
15090
15126
  SavedViewsDeleteConfirmationModalShared,
@@ -15129,26 +15165,37 @@ var DEFAULT_COLUMN_STATE = {
15129
15165
  rowGroupIndex: null,
15130
15166
  flex: null
15131
15167
  };
15168
+ var isColGroupDef = (colDef) => {
15169
+ return "children" in colDef && Array.isArray(colDef.children);
15170
+ };
15132
15171
  var getColumnStateFromDefs = (columnDefs) => {
15133
- return columnDefs.map((colDef) => {
15134
- const field = colDef.field ?? colDef.colId;
15135
- if (!field)
15136
- return null;
15137
- return {
15138
- colId: field,
15139
- hide: colDef.hide ?? false,
15140
- pinned: colDef.pinned ?? null,
15141
- width: colDef.width ?? colDef.minWidth ?? DEFAULT_COLUMN_STATE.width,
15142
- sort: null,
15143
- sortIndex: null,
15144
- pivot: false,
15145
- pivotIndex: null,
15146
- aggFunc: null,
15147
- rowGroup: false,
15148
- rowGroupIndex: null,
15149
- flex: colDef.flex ?? null
15150
- };
15151
- }).filter((col) => col !== null);
15172
+ return columnDefs.flatMap((colDef) => {
15173
+ if (isColGroupDef(colDef)) {
15174
+ return getColumnStateFromDefs(colDef.children);
15175
+ }
15176
+ return getColumnStateFromSingleDef(colDef);
15177
+ }).filter(
15178
+ (col) => col !== null
15179
+ );
15180
+ };
15181
+ var getColumnStateFromSingleDef = (colDef) => {
15182
+ const field = colDef.field ?? colDef.colId;
15183
+ if (!field)
15184
+ return null;
15185
+ return {
15186
+ colId: field,
15187
+ hide: colDef.hide ?? false,
15188
+ pinned: colDef.pinned ?? null,
15189
+ width: colDef.width ?? colDef.minWidth ?? DEFAULT_COLUMN_STATE.width,
15190
+ sort: null,
15191
+ sortIndex: null,
15192
+ pivot: false,
15193
+ pivotIndex: null,
15194
+ aggFunc: null,
15195
+ rowGroup: false,
15196
+ rowGroupIndex: null,
15197
+ flex: colDef.flex ?? null
15198
+ };
15152
15199
  };
15153
15200
  var extractDefaultView = (gridApi, receivedConfig) => {
15154
15201
  var _a, _b;
@@ -15176,7 +15223,7 @@ var useNormalizedDefaultViews = (defaultViews, gridApi) => {
15176
15223
  };
15177
15224
 
15178
15225
  // src/components/adapters/smart-grid/useSmartGridConfig.ts
15179
- import { useState as useState5, useEffect as useEffect4 } from "react";
15226
+ import { useState as useState5, useEffect as useEffect5, useRef as useRef4 } from "react";
15180
15227
  var GRID_STATE_EVENTS = [
15181
15228
  "sortChanged",
15182
15229
  "filterOpened",
@@ -15195,10 +15242,14 @@ var useSmartGridConfig = (gridApi) => {
15195
15242
  const [config, setConfig] = useState5(
15196
15243
  () => getSmartGridConfig(gridApi)
15197
15244
  );
15198
- useEffect4(() => {
15245
+ const eventListenersDisabledRef = useRef4(false);
15246
+ useEffect5(() => {
15199
15247
  if (!gridApi)
15200
15248
  return;
15201
15249
  const updateConfig = () => {
15250
+ if (eventListenersDisabledRef.current) {
15251
+ return;
15252
+ }
15202
15253
  setConfig(getSmartGridConfig(gridApi));
15203
15254
  };
15204
15255
  GRID_STATE_EVENTS.forEach((event) => {
@@ -15210,7 +15261,13 @@ var useSmartGridConfig = (gridApi) => {
15210
15261
  });
15211
15262
  };
15212
15263
  }, [gridApi]);
15213
- return { config, setConfig };
15264
+ const disableEventListeners = () => {
15265
+ eventListenersDisabledRef.current = true;
15266
+ };
15267
+ const enableEventListeners = () => {
15268
+ eventListenersDisabledRef.current = false;
15269
+ };
15270
+ return { config, setConfig, disableEventListeners, enableEventListeners };
15214
15271
  };
15215
15272
 
15216
15273
  // src/components/adapters/smart-grid/SmartGridSavedViews.tsx
@@ -15254,7 +15311,8 @@ var SmartGridSavedViews = (props) => {
15254
15311
  defaultView,
15255
15312
  presetViews,
15256
15313
  tableName: props.tableName,
15257
- tableConfig
15314
+ tableConfig,
15315
+ backend: props.backend
15258
15316
  }
15259
15317
  );
15260
15318
  };