@procore/saved-views 1.0.1-alpha.2 → 1.1.0-alpha.0

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.
@@ -3982,7 +3982,7 @@ var require_lodash = __commonJS({
3982
3982
  if (typeof func != "function") {
3983
3983
  throw new TypeError2(FUNC_ERROR_TEXT);
3984
3984
  }
3985
- return setTimeout2(function() {
3985
+ return setTimeout(function() {
3986
3986
  func.apply(undefined2, args);
3987
3987
  }, wait);
3988
3988
  }
@@ -5813,7 +5813,7 @@ var require_lodash = __commonJS({
5813
5813
  return object2[key];
5814
5814
  }
5815
5815
  var setData = shortOut(baseSetData);
5816
- var setTimeout2 = ctxSetTimeout || function(func, wait) {
5816
+ var setTimeout = ctxSetTimeout || function(func, wait) {
5817
5817
  return root.setTimeout(func, wait);
5818
5818
  };
5819
5819
  var setToString = shortOut(baseSetToString);
@@ -6605,7 +6605,7 @@ var require_lodash = __commonJS({
6605
6605
  }
6606
6606
  function leadingEdge(time) {
6607
6607
  lastInvokeTime = time;
6608
- timerId = setTimeout2(timerExpired, wait);
6608
+ timerId = setTimeout(timerExpired, wait);
6609
6609
  return leading ? invokeFunc(time) : result2;
6610
6610
  }
6611
6611
  function remainingWait(time) {
@@ -6621,7 +6621,7 @@ var require_lodash = __commonJS({
6621
6621
  if (shouldInvoke(time)) {
6622
6622
  return trailingEdge(time);
6623
6623
  }
6624
- timerId = setTimeout2(timerExpired, remainingWait(time));
6624
+ timerId = setTimeout(timerExpired, remainingWait(time));
6625
6625
  }
6626
6626
  function trailingEdge(time) {
6627
6627
  timerId = undefined2;
@@ -6652,12 +6652,12 @@ var require_lodash = __commonJS({
6652
6652
  }
6653
6653
  if (maxing) {
6654
6654
  clearTimeout(timerId);
6655
- timerId = setTimeout2(timerExpired, wait);
6655
+ timerId = setTimeout(timerExpired, wait);
6656
6656
  return invokeFunc(lastCallTime);
6657
6657
  }
6658
6658
  }
6659
6659
  if (timerId === undefined2) {
6660
- timerId = setTimeout2(timerExpired, wait);
6660
+ timerId = setTimeout(timerExpired, wait);
6661
6661
  }
6662
6662
  return result2;
6663
6663
  }
@@ -11387,7 +11387,7 @@ var SavedViewCollectionMenuItem = (props) => {
11387
11387
  loading: props.isUpdateProcessing
11388
11388
  },
11389
11389
  i18n.t("savedViews.actions.update")
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(
11390
+ )), 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,12 +11436,199 @@ 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 useI18nContext4 } from "@procore/core-react";
11439
+ import { Flex as Flex3, useI18nContext as useI18nContext5 } 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 getBasePath = (companyId, projectId) => {
11492
+ if (projectId) {
11493
+ return `/rest/v2.0/companies/${companyId}/projects/${projectId}/saved_views`;
11494
+ }
11495
+ return `/rest/v2.0/companies/${companyId}/saved_views`;
11496
+ };
11497
+ var useApiRequest = (props, method, mutationKey) => {
11498
+ const { projectId, companyId, domain, tableName } = props;
11499
+ const queryClient2 = useQueryClient();
11500
+ const { locale: locale2 } = useI18nContext3();
11501
+ const basePath = getBasePath(companyId, projectId);
11502
+ const queryKeyContext = projectId ?? companyId;
11503
+ return useMutation({
11504
+ mutationKey,
11505
+ mutationFn: async (savedView) => {
11506
+ let url = "";
11507
+ if (method === "DELETE" || method === "PUT") {
11508
+ url = `${basePath}/${savedView.share_token}?permissions_domain=${domain}`;
11509
+ } else {
11510
+ url = `${basePath}?table_name=${tableName}&permissions_domain=${domain}`;
11511
+ }
11512
+ const response = await requestJSON(url, {
11513
+ method,
11514
+ body: JSON.stringify(savedView),
11515
+ headers: {
11516
+ "Content-Type": "application/json",
11517
+ "Accept-Language": locale2
11518
+ }
11519
+ });
11520
+ if (response.error) {
11521
+ throw response.error;
11522
+ }
11523
+ return response.data;
11524
+ },
11525
+ onSuccess: (savedView) => {
11526
+ if (method === "DELETE" || method === "POST") {
11527
+ queryClient2.invalidateQueries({
11528
+ queryKey: ["savedViews", domain, tableName, queryKeyContext]
11529
+ });
11530
+ return;
11531
+ } else {
11532
+ const oldData = queryClient2.getQueryData([
11533
+ "savedViews",
11534
+ domain,
11535
+ tableName,
11536
+ queryKeyContext
11537
+ ]);
11538
+ const oldView = oldData == null ? void 0 : oldData.find(
11539
+ (item) => item.share_token === savedView.share_token
11540
+ );
11541
+ if ((oldView == null ? void 0 : oldView.name) !== savedView.name) {
11542
+ queryClient2.invalidateQueries({
11543
+ queryKey: ["savedViews", domain, tableName, queryKeyContext]
11544
+ });
11545
+ return;
11546
+ }
11547
+ }
11548
+ queryClient2.setQueryData(
11549
+ ["savedViews", domain, tableName, queryKeyContext],
11550
+ (oldData) => {
11551
+ if (!oldData)
11552
+ return [savedView];
11553
+ return oldData.map(
11554
+ (item) => item.share_token === savedView.share_token ? savedView : item
11555
+ );
11556
+ }
11557
+ );
11558
+ }
11559
+ });
11560
+ };
11561
+
11443
11562
  // src/utils/constants/viewLevels.ts
11444
- var VIEW_LEVELS = ["company", "project", "personal"];
11563
+ var PROJECT_LEVEL_TOOL_VIEW_LEVELS = [
11564
+ "company",
11565
+ "project",
11566
+ "personal"
11567
+ ];
11568
+ var COMPANY_LEVEL_TOOL_VIEW_LEVELS = ["company", "personal"];
11569
+ var getViewLevels = (isProjectLevelTool) => isProjectLevelTool ? PROJECT_LEVEL_TOOL_VIEW_LEVELS : COMPANY_LEVEL_TOOL_VIEW_LEVELS;
11570
+
11571
+ // src/utils/api/queries.ts
11572
+ var PAGE_SIZE = 50 * PROJECT_LEVEL_TOOL_VIEW_LEVELS.length;
11573
+ var getBasePath2 = (companyId, projectId) => {
11574
+ if (projectId) {
11575
+ return `/rest/v2.0/companies/${companyId}/projects/${projectId}/saved_views`;
11576
+ }
11577
+ return `/rest/v2.0/companies/${companyId}/saved_views`;
11578
+ };
11579
+ var useSavedViewsQuery = (props) => {
11580
+ const { projectId, companyId, domain, tableName } = props;
11581
+ const basePath = getBasePath2(companyId, projectId);
11582
+ const url = `${basePath}?table_name=${tableName}&permissions_domain=${domain}`;
11583
+ return useQuery({
11584
+ queryKey: ["savedViews", domain, tableName, projectId ?? companyId],
11585
+ queryFn: async () => {
11586
+ const getUrl2 = `${url}&per_page=${PAGE_SIZE}`;
11587
+ const response = await requestJSON(getUrl2);
11588
+ return response.data;
11589
+ }
11590
+ });
11591
+ };
11592
+ var useSavedViewsPermissions = (props) => {
11593
+ const { projectId, companyId, domain } = props;
11594
+ const basePath = getBasePath2(companyId, projectId);
11595
+ const url = `${basePath}/permissions?permissions_domain=${domain}`;
11596
+ return useQuery({
11597
+ queryKey: ["savedViewsConfig", domain, projectId ?? companyId],
11598
+ queryFn: async () => {
11599
+ const response = await requestJSON(url);
11600
+ return response.data;
11601
+ }
11602
+ });
11603
+ };
11604
+ var useCreateSavedView = (props) => useApiRequest(props, "POST", [
11605
+ "createSavedView",
11606
+ props.domain,
11607
+ props.tableName
11608
+ ]);
11609
+ var useUpdateSavedView = (props) => useApiRequest(props, "PUT", [
11610
+ "updateSavedView",
11611
+ props.domain,
11612
+ props.tableName
11613
+ ]);
11614
+ var useDeleteSavedView = (props) => useApiRequest(props, "DELETE", [
11615
+ "deleteSavedView",
11616
+ props.domain,
11617
+ props.tableName
11618
+ ]);
11619
+ var useFetchSavedViewById = (savedViewToken, queryInput, enabled = true) => {
11620
+ const { projectId, companyId, domain } = queryInput;
11621
+ const basePath = getBasePath2(companyId, projectId);
11622
+ return useQuery({
11623
+ enabled: enabled && Boolean(savedViewToken),
11624
+ queryKey: ["savedView", savedViewToken, projectId ?? companyId],
11625
+ queryFn: async () => {
11626
+ const url = `${basePath}/${savedViewToken}?permissions_domain=${domain}`;
11627
+ const response = await requestJSON(url);
11628
+ return response.data;
11629
+ }
11630
+ });
11631
+ };
11445
11632
 
11446
11633
  // src/components/panels/PanelContentUtils.ts
11447
11634
  var import_lodash = __toESM(require_lodash());
@@ -11516,12 +11703,10 @@ var getColumnIdentifier = (col) => {
11516
11703
  };
11517
11704
  var updateTableConfig = (view, tableApi, provider) => {
11518
11705
  if (provider === "smart-grid") {
11519
- setTimeout(() => {
11520
- setSmartGridConfig(
11521
- tableApi,
11522
- view.table_config
11523
- );
11524
- }, 0);
11706
+ setSmartGridConfig(
11707
+ tableApi,
11708
+ view.table_config
11709
+ );
11525
11710
  } else {
11526
11711
  const dataTableApi = tableApi;
11527
11712
  const tableConfig = view.table_config;
@@ -11593,20 +11778,13 @@ var cleanObject = (table_config, provider) => {
11593
11778
  var normalizeForComparison = (config) => {
11594
11779
  if (!(config == null ? void 0 : config.columnState))
11595
11780
  return config;
11596
- const filteredColumnState = config.columnState.filter(
11597
- (col) => {
11598
- const colId = getColumnIdentifier(col);
11599
- return colId !== "drag_handle" && colId !== "ag-Grid-AutoColumn";
11600
- }
11601
- );
11602
11781
  return {
11603
- ...import_lodash.default.omit(config, ["enableRowGrouping", "enableColumnGrouping"]),
11604
- columnState: filteredColumnState.map((col) => {
11605
- const res = import_lodash.default.omit(col, ["aggFunc"]);
11782
+ ...config,
11783
+ columnState: config.columnState.map((col) => {
11606
11784
  if (col.flex) {
11607
- return import_lodash.default.omit(res, ["width", "flex"]);
11785
+ return import_lodash.default.omit(col, ["width", "flex"]);
11608
11786
  }
11609
- return res;
11787
+ return col;
11610
11788
  })
11611
11789
  };
11612
11790
  };
@@ -11619,9 +11797,10 @@ var isEqual = (viewTableConfig, tableConfig, defaultViewConfig, provider) => {
11619
11797
  );
11620
11798
  const normalizedViewConfig = normalizeForComparison(syncedViewTableConfig);
11621
11799
  const normalizedCurrentConfig = normalizeForComparison(tableConfig);
11622
- const cleanedViewConfig = cleanObject(normalizedViewConfig, provider);
11623
- const cleanedCurrentConfig = cleanObject(normalizedCurrentConfig, provider);
11624
- return import_lodash.default.isEqual(cleanedViewConfig, cleanedCurrentConfig);
11800
+ return import_lodash.default.isEqual(
11801
+ cleanObject(normalizedViewConfig, provider),
11802
+ cleanObject(normalizedCurrentConfig, provider)
11803
+ );
11625
11804
  };
11626
11805
  var hasPermissionForViewLevel = (viewLevel, permissions) => {
11627
11806
  switch (viewLevel) {
@@ -11638,9 +11817,10 @@ var hasPermissionForViewLevel = (viewLevel, permissions) => {
11638
11817
 
11639
11818
  // src/components/panels/useGroups.ts
11640
11819
  import { useState as useState2 } from "react";
11641
- var useGroups = () => {
11820
+ var useGroups = (isProjectLevelTool) => {
11821
+ const viewLevels = getViewLevels(isProjectLevelTool);
11642
11822
  const [groups, setGroups] = useState2(
11643
- Object.fromEntries(VIEW_LEVELS.map((level) => [level, true]))
11823
+ Object.fromEntries(viewLevels.map((level) => [level, true]))
11644
11824
  );
11645
11825
  const toggleGroup = (group) => {
11646
11826
  setGroups((groups2) => ({ ...groups2, [group]: !groups2[group] }));
@@ -11654,7 +11834,7 @@ import {
11654
11834
  Flex as Flex2,
11655
11835
  spacing,
11656
11836
  Typography,
11657
- useI18nContext as useI18nContext3
11837
+ useI18nContext as useI18nContext4
11658
11838
  } from "@procore/core-react";
11659
11839
  import React16 from "react";
11660
11840
  var groupIcon = (group) => {
@@ -11674,7 +11854,7 @@ var Header = styled_components_esm_default(Flex2)`
11674
11854
  }
11675
11855
  `;
11676
11856
  var ViewLevelHeader = ({ expanded, toggleGroup, group }) => {
11677
- const I18n = useI18nContext3();
11857
+ const I18n = useI18nContext4();
11678
11858
  return /* @__PURE__ */ React16.createElement(
11679
11859
  Header,
11680
11860
  {
@@ -11731,9 +11911,9 @@ var Panel2 = styled_components_esm_default(DetailPage.Card)`
11731
11911
  var PanelContent = (props) => {
11732
11912
  const { queryInput, selectedSavedView, tableConfig } = props;
11733
11913
  const { showToast } = useToastAlertContext2();
11734
- const I18n = useI18nContext4();
11735
- const { data: savedViewsFromQuery, error: savedViewsError } = props.backend.useSavedViewsQuery(props.queryInput);
11736
- const updateMutation = props.backend.useUpdateSavedView(queryInput);
11914
+ const I18n = useI18nContext5();
11915
+ const { data: savedViewsFromQuery, error: savedViewsError } = useSavedViewsQuery(props.queryInput);
11916
+ const updateMutation = useUpdateSavedView(queryInput);
11737
11917
  const { mutate: updateSavedView } = updateMutation;
11738
11918
  const isUpdateLoading = "isPending" in updateMutation ? updateMutation.isPending : updateMutation.isLoading ?? false;
11739
11919
  const savedViews = props.savedViews ?? savedViewsFromQuery;
@@ -11744,14 +11924,14 @@ var PanelContent = (props) => {
11744
11924
  errorToastRef.current = savedViewsError;
11745
11925
  }
11746
11926
  }, [savedViewsError, showToast, I18n]);
11747
- const { data: permissions } = props.backend.useSavedViewsPermissions(
11748
- props.queryInput
11749
- );
11927
+ const { data: permissions } = useSavedViewsPermissions(props.queryInput);
11750
11928
  const selectedRowRef = useScrollToRef(savedViews);
11751
- const { groups, toggleGroup } = useGroups();
11752
11929
  const isTemporarySelected = (selectedSavedView == null ? void 0 : selectedSavedView.id) === "temporary";
11753
11930
  const temporaryView = savedViews == null ? void 0 : savedViews.find((view) => view.id === "temporary");
11754
11931
  const presetViews = props.presetViews || [props.defaultView];
11932
+ const isProjectLevelTool = !!queryInput.projectId;
11933
+ const viewLevels = getViewLevels(isProjectLevelTool);
11934
+ const { groups, toggleGroup } = useGroups(isProjectLevelTool);
11755
11935
  const onUpdate = (data) => {
11756
11936
  const newSavedView = {
11757
11937
  ...data,
@@ -11780,8 +11960,7 @@ var PanelContent = (props) => {
11780
11960
  {
11781
11961
  item: temporaryView,
11782
11962
  selected: isTemporarySelected,
11783
- onClearTemporary: props.onClearTemporary,
11784
- enableSharingViews: false
11963
+ onClearTemporary: props.onClearTemporary
11785
11964
  }
11786
11965
  )
11787
11966
  ), presetViews.map((presetView) => {
@@ -11798,12 +11977,11 @@ var PanelContent = (props) => {
11798
11977
  SavedViewCollectionMenuItem,
11799
11978
  {
11800
11979
  item: presetView,
11801
- selected: isSelected,
11802
- enableSharingViews: false
11980
+ selected: isSelected
11803
11981
  }
11804
11982
  )
11805
11983
  );
11806
- }), VIEW_LEVELS.map((level) => {
11984
+ }), viewLevels.map((level) => {
11807
11985
  const isExpanded = groups[level];
11808
11986
  const views = isExpanded && savedViews ? savedViews.filter(
11809
11987
  (view) => view.view_level === level && view.id !== "temporary"
@@ -11847,8 +12025,7 @@ var PanelContent = (props) => {
11847
12025
  isUpdateProcessing: isUpdateLoading,
11848
12026
  onEdit: () => props.openModal("update" /* UPDATE */),
11849
12027
  onDelete: props.onDelete,
11850
- permissions,
11851
- enableSharingViews: false
12028
+ permissions
11852
12029
  }
11853
12030
  )
11854
12031
  );
@@ -11865,7 +12042,7 @@ import {
11865
12042
  Tooltip,
11866
12043
  useI18nContext as useI18nContext11
11867
12044
  } from "@procore/core-react";
11868
- import React22, { useState as useState4, useEffect as useEffect4, useCallback as useCallback3 } from "react";
12045
+ import React22, { useState as useState4, useEffect as useEffect3, useCallback as useCallback3 } from "react";
11869
12046
  import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
11870
12047
  import { useToastAlertContext as useToastAlertContext3, ToastAlertProvider } from "@procore/toast-alert";
11871
12048
 
@@ -11875,7 +12052,7 @@ import {
11875
12052
  ConfirmModal,
11876
12053
  Modal,
11877
12054
  P as P2,
11878
- useI18nContext as useI18nContext5
12055
+ useI18nContext as useI18nContext6
11879
12056
  } from "@procore/core-react";
11880
12057
  import React18 from "react";
11881
12058
  var SavedViewsDeleteConfirmationModalShared = ({
@@ -11883,7 +12060,7 @@ var SavedViewsDeleteConfirmationModalShared = ({
11883
12060
  onDelete,
11884
12061
  open
11885
12062
  }) => {
11886
- const i18n = useI18nContext5();
12063
+ const i18n = useI18nContext6();
11887
12064
  return /* @__PURE__ */ React18.createElement(
11888
12065
  ConfirmModal,
11889
12066
  {
@@ -11914,7 +12091,7 @@ import {
11914
12091
  Modal as Modal2,
11915
12092
  spacing as spacing3,
11916
12093
  Typography as Typography2,
11917
- useI18nContext as useI18nContext6
12094
+ useI18nContext as useI18nContext7
11918
12095
  } from "@procore/core-react";
11919
12096
  import * as React19 from "react";
11920
12097
 
@@ -14211,10 +14388,11 @@ var TupleSchema = class extends Schema {
14211
14388
  create$1.prototype = TupleSchema.prototype;
14212
14389
 
14213
14390
  // src/components/modals/form-modal/FormModalBaseUtils.ts
14214
- var getViewLevelOptions = (permissions, i18n) => {
14391
+ var getViewLevelOptions = (permissions, i18n, isProjectLevelTool = true) => {
14215
14392
  const options = ["personal"];
14216
- if (permissions == null ? void 0 : permissions.can_create_project_saved_views)
14393
+ if (isProjectLevelTool && (permissions == null ? void 0 : permissions.can_create_project_saved_views)) {
14217
14394
  options.push("project");
14395
+ }
14218
14396
  if (permissions == null ? void 0 : permissions.can_create_company_saved_views)
14219
14397
  options.push("company");
14220
14398
  return options.map((option) => ({
@@ -14244,7 +14422,6 @@ function extractMessage(error, I18n) {
14244
14422
  }
14245
14423
 
14246
14424
  // src/components/modals/form-modal/FormModalBase.tsx
14247
- var { useEffect: useEffect2, useRef: useRef2 } = React19;
14248
14425
  var ScrollContainer = styled_components_esm_default("div")`
14249
14426
  overflow: auto;
14250
14427
  `;
@@ -14261,38 +14438,22 @@ var FormModalBase = ({
14261
14438
  defaultView,
14262
14439
  selectedSavedView,
14263
14440
  setOpenEditCreateModal,
14264
- onSelect,
14265
- backend
14441
+ onSelect
14266
14442
  }) => {
14267
- const I18n = useI18nContext6();
14443
+ const I18n = useI18nContext7();
14268
14444
  const NAME_MAX_LENGTH = 150;
14269
- const originalBodyWidth = useRef2("");
14270
- useEffect2(() => {
14271
- if (open) {
14272
- originalBodyWidth.current = document.body.style.width || "";
14273
- document.body.style.width = "100%";
14274
- } else {
14275
- document.body.style.width = originalBodyWidth.current;
14276
- }
14277
- return () => {
14278
- if (originalBodyWidth.current !== void 0) {
14279
- document.body.style.width = originalBodyWidth.current;
14280
- }
14281
- };
14282
- }, [open]);
14283
- const { useCreateSavedView: useCreateSavedView2, useUpdateSavedView: useUpdateSavedView2, useSavedViewsPermissions: useSavedViewsPermissions2 } = backend;
14284
14445
  const {
14285
14446
  mutate: createSavedView,
14286
14447
  isPending: isCreating,
14287
14448
  error: createError,
14288
14449
  reset: resetCreateMutation
14289
- } = useCreateSavedView2(queryInput);
14450
+ } = useCreateSavedView(queryInput);
14290
14451
  const {
14291
14452
  mutate: updateSavedView,
14292
14453
  isPending: isUpdating,
14293
14454
  error: updateError,
14294
14455
  reset: resetUpdateMutation
14295
- } = useUpdateSavedView2(queryInput);
14456
+ } = useUpdateSavedView(queryInput);
14296
14457
  const resetMutations = () => {
14297
14458
  resetCreateMutation();
14298
14459
  resetUpdateMutation();
@@ -14301,7 +14462,7 @@ var FormModalBase = ({
14301
14462
  resetMutations();
14302
14463
  onCancel();
14303
14464
  };
14304
- const { data: permissions } = useSavedViewsPermissions2(queryInput);
14465
+ const { data: permissions } = useSavedViewsPermissions(queryInput);
14305
14466
  const isLoading = isCreating || isUpdating;
14306
14467
  const errors = extractMessage(createError || updateError, I18n);
14307
14468
  const handleOnSubmit = (data) => {
@@ -14332,7 +14493,12 @@ var FormModalBase = ({
14332
14493
  });
14333
14494
  }
14334
14495
  };
14335
- const viewLevelOptions = getViewLevelOptions(permissions, I18n);
14496
+ const isProjectLevelTool = !!queryInput.projectId;
14497
+ const viewLevelOptions = getViewLevelOptions(
14498
+ permissions,
14499
+ I18n,
14500
+ isProjectLevelTool
14501
+ );
14336
14502
  return /* @__PURE__ */ React19.createElement(
14337
14503
  Modal2,
14338
14504
  {
@@ -14412,7 +14578,6 @@ var FormModalBase = ({
14412
14578
  Form.Select,
14413
14579
  {
14414
14580
  name: "view_level",
14415
- qa: { label: "view-level" },
14416
14581
  options: viewLevelOptions,
14417
14582
  label: I18n.t("savedViews.modal.fields.viewLevel"),
14418
14583
  colWidth: 12,
@@ -14436,7 +14601,7 @@ var FormModalBase = ({
14436
14601
  };
14437
14602
 
14438
14603
  // src/components/modals/form-modal/FormModal.tsx
14439
- import { useI18nContext as useI18nContext7 } from "@procore/core-react";
14604
+ import { useI18nContext as useI18nContext8 } from "@procore/core-react";
14440
14605
  var FormModal = ({
14441
14606
  open,
14442
14607
  mode,
@@ -14447,10 +14612,9 @@ var FormModal = ({
14447
14612
  selectedSavedView,
14448
14613
  setOpenEditCreateModal,
14449
14614
  onSelect,
14450
- defaultView,
14451
- backend
14615
+ defaultView
14452
14616
  }) => {
14453
- const i18n = useI18nContext7();
14617
+ const i18n = useI18nContext8();
14454
14618
  return /* @__PURE__ */ React20.createElement(
14455
14619
  FormModalBase,
14456
14620
  {
@@ -14466,8 +14630,7 @@ var FormModal = ({
14466
14630
  selectedSavedView,
14467
14631
  setOpenEditCreateModal,
14468
14632
  onSelect,
14469
- defaultView,
14470
- backend
14633
+ defaultView
14471
14634
  }
14472
14635
  );
14473
14636
  };
@@ -14484,7 +14647,7 @@ import {
14484
14647
  P as P3,
14485
14648
  spacing as spacing4,
14486
14649
  Typography as Typography3,
14487
- useI18nContext as useI18nContext8
14650
+ useI18nContext as useI18nContext9
14488
14651
  } from "@procore/core-react";
14489
14652
  import * as React21 from "react";
14490
14653
  var SharedViewFormModal = ({
@@ -14497,7 +14660,7 @@ var SharedViewFormModal = ({
14497
14660
  isCreating,
14498
14661
  resetCreateError
14499
14662
  }) => {
14500
- const I18n = useI18nContext8();
14663
+ const I18n = useI18nContext9();
14501
14664
  const NAME_MAX_LENGTH = 150;
14502
14665
  const errors = extractMessage(createError, I18n);
14503
14666
  const handleNameChange = () => {
@@ -14627,9 +14790,9 @@ var SharedViewFormModal = ({
14627
14790
  };
14628
14791
 
14629
14792
  // src/utils/hooks/useViewSelection.ts
14630
- import { useState as useState3, useCallback as useCallback2, useEffect as useEffect3, useRef as useRef3, useMemo } from "react";
14793
+ import { useState as useState3, useCallback as useCallback2, useEffect as useEffect2, useRef as useRef2, useMemo } from "react";
14631
14794
  import { useSearchParams } from "react-router-dom";
14632
- import { useI18nContext as useI18nContext9 } from "@procore/core-react";
14795
+ import { useI18nContext as useI18nContext10 } from "@procore/core-react";
14633
14796
 
14634
14797
  // src/utils/viewStorage.ts
14635
14798
  var ViewStorage = {
@@ -14692,11 +14855,12 @@ var restoreUrlParameter = (currentParam, previousParam, setSearchParams) => {
14692
14855
  }
14693
14856
  };
14694
14857
  var useViewSelection = (config, savedViews, presetViews, openSharedViewModal) => {
14695
- const I18n = useI18nContext9();
14696
- const storageKey = `savedView_${config.domain}_${config.tableName}_${config.companyId}_${config.projectId}_${config.userId}`;
14858
+ const I18n = useI18nContext10();
14859
+ const projectIdSegment = config.projectId ?? "company";
14860
+ const storageKey = `savedView_${config.domain}_${config.tableName}_${config.companyId}_${projectIdSegment}_${config.userId}`;
14697
14861
  const temporaryStorageKey = `${storageKey}-temporary`;
14698
14862
  const [searchParams, setSearchParams] = useSearchParams();
14699
- const previousSavedViewParamRef = useRef3(null);
14863
+ const previousSavedViewParamRef = useRef2(null);
14700
14864
  const [selectedSavedView, setSelectedSavedView] = useState3(() => {
14701
14865
  const stored = ViewStorage.load(storageKey, config.defaultView);
14702
14866
  return stored ?? config.defaultView;
@@ -14767,7 +14931,7 @@ var useViewSelection = (config, savedViews, presetViews, openSharedViewModal) =>
14767
14931
  },
14768
14932
  [isViewAlreadySelected, openSharedViewModal, allViews, selectView]
14769
14933
  );
14770
- useEffect3(() => {
14934
+ useEffect2(() => {
14771
14935
  const savedViewId = searchParams.get("saved-view");
14772
14936
  restoreUrlParameter(
14773
14937
  savedViewId,
@@ -14791,177 +14955,6 @@ var useViewSelection = (config, savedViews, presetViews, openSharedViewModal) =>
14791
14955
  };
14792
14956
  };
14793
14957
 
14794
- // node_modules/@procore/core-http/dist/modern/index.js
14795
- function getCSRFToken() {
14796
- const token = document.cookie.match("(^|;)\\s*csrf_token\\s*=\\s*([^;]+)");
14797
- return token ? decodeURIComponent(token.pop() || "") : "";
14798
- }
14799
- function getCSRFHeader() {
14800
- const csrfToken = getCSRFToken();
14801
- return csrfToken ? { "X-CSRF-TOKEN": csrfToken } : {};
14802
- }
14803
- function removeLeadingSlash(url) {
14804
- return url.startsWith("/") ? url.substring(1, url.length) : url;
14805
- }
14806
- function removeTrailingSlash(url) {
14807
- return url.endsWith("/") ? url.substring(0, url.length - 1) : url;
14808
- }
14809
- function applyBaseUrl(url, baseUrl) {
14810
- return `${removeTrailingSlash(baseUrl)}/${removeLeadingSlash(url)}`;
14811
- }
14812
- function getOptions({ headers, ...options }) {
14813
- const opts = {
14814
- credentials: "same-origin",
14815
- headers: {
14816
- ...getCSRFHeader(),
14817
- ...headers
14818
- },
14819
- mode: "same-origin",
14820
- ...options
14821
- };
14822
- return opts;
14823
- }
14824
- function getUrl(url, baseUrl) {
14825
- return baseUrl ? applyBaseUrl(url, baseUrl) : url;
14826
- }
14827
- function request(url, { baseUrl, ...options } = {}) {
14828
- return fetch(getUrl(url, baseUrl), getOptions(options));
14829
- }
14830
- function requestJSON(url, requestParams = {}) {
14831
- return request(url, requestParams).then(
14832
- (response) => response.json()
14833
- );
14834
- }
14835
-
14836
- // src/utils/api/queries.ts
14837
- import { useQuery } from "@tanstack/react-query";
14838
-
14839
- // src/utils/api/queriesHandler.ts
14840
- import { useMutation, useQueryClient } from "@tanstack/react-query";
14841
- import { useI18nContext as useI18nContext10 } from "@procore/core-react";
14842
- var useApiRequest = (props, method, mutationKey) => {
14843
- const { projectId, companyId, domain, tableName } = props;
14844
- const queryClient2 = useQueryClient();
14845
- const { locale: locale2 } = useI18nContext10();
14846
- return useMutation({
14847
- mutationKey,
14848
- mutationFn: async (savedView) => {
14849
- let url = "";
14850
- if (method === "DELETE" || method === "PUT") {
14851
- url = `/rest/v2.0/companies/${companyId}/projects/${projectId}/saved_views/${savedView.share_token}?permissions_domain=${domain}`;
14852
- } else {
14853
- url = `/rest/v2.0/companies/${companyId}/projects/${projectId}/saved_views?table_name=${tableName}&permissions_domain=${domain}`;
14854
- }
14855
- const response = await requestJSON(url, {
14856
- method,
14857
- body: JSON.stringify(savedView),
14858
- headers: {
14859
- "Content-Type": "application/json",
14860
- "Accept-Language": locale2
14861
- }
14862
- });
14863
- if (response.error) {
14864
- throw response.error;
14865
- }
14866
- return response.data;
14867
- },
14868
- onSuccess: (savedView) => {
14869
- if (method === "DELETE" || method === "POST") {
14870
- queryClient2.invalidateQueries({
14871
- queryKey: ["savedViews", domain, tableName]
14872
- });
14873
- return;
14874
- } else {
14875
- const oldData = queryClient2.getQueryData([
14876
- "savedViews",
14877
- domain,
14878
- tableName
14879
- ]);
14880
- const oldView = oldData == null ? void 0 : oldData.find(
14881
- (item) => item.share_token === savedView.share_token
14882
- );
14883
- if ((oldView == null ? void 0 : oldView.name) !== savedView.name) {
14884
- queryClient2.invalidateQueries({
14885
- queryKey: ["savedViews", domain, tableName]
14886
- });
14887
- return;
14888
- }
14889
- }
14890
- queryClient2.setQueryData(
14891
- ["savedViews", domain, tableName],
14892
- (oldData) => {
14893
- if (!oldData)
14894
- return [savedView];
14895
- return oldData.map(
14896
- (item) => item.share_token === savedView.share_token ? savedView : item
14897
- );
14898
- }
14899
- );
14900
- }
14901
- });
14902
- };
14903
-
14904
- // src/utils/api/queries.ts
14905
- var PAGE_SIZE = 50 * VIEW_LEVELS.length;
14906
- var useSavedViewsQuery = (props) => {
14907
- const { projectId, companyId, domain, tableName } = props;
14908
- const url = `/rest/v2.0/companies/${companyId}/projects/${projectId}/saved_views?table_name=${tableName}&permissions_domain=${domain}`;
14909
- return useQuery({
14910
- queryKey: ["savedViews", domain, tableName],
14911
- queryFn: async () => {
14912
- const getUrl2 = `${url}&per_page=${PAGE_SIZE}`;
14913
- const response = await requestJSON(getUrl2);
14914
- return response.data;
14915
- }
14916
- });
14917
- };
14918
- var useSavedViewsPermissions = (props) => {
14919
- const { projectId, companyId, domain } = props;
14920
- const url = `/rest/v2.0/companies/${companyId}/projects/${projectId}/saved_views/permissions?permissions_domain=${domain}`;
14921
- return useQuery({
14922
- queryKey: ["savedViewsConfig", domain],
14923
- queryFn: async () => {
14924
- const response = await requestJSON(url);
14925
- return response.data;
14926
- }
14927
- });
14928
- };
14929
- var useCreateSavedView = (props) => useApiRequest(props, "POST", [
14930
- "createSavedView",
14931
- props.domain,
14932
- props.tableName
14933
- ]);
14934
- var useUpdateSavedView = (props) => useApiRequest(props, "PUT", [
14935
- "updateSavedView",
14936
- props.domain,
14937
- props.tableName
14938
- ]);
14939
- var useDeleteSavedView = (props) => useApiRequest(props, "DELETE", [
14940
- "deleteSavedView",
14941
- props.domain,
14942
- props.tableName
14943
- ]);
14944
- var useFetchSavedViewById = (savedViewToken, queryInput, enabled = true) => {
14945
- const { projectId, companyId } = queryInput;
14946
- return useQuery({
14947
- enabled: enabled && Boolean(savedViewToken),
14948
- queryKey: ["savedView", savedViewToken],
14949
- queryFn: async () => {
14950
- const url = `/rest/v2.0/companies/${companyId}/projects/${projectId}/saved_views/${savedViewToken}`;
14951
- const response = await requestJSON(url);
14952
- return response.data;
14953
- }
14954
- });
14955
- };
14956
- var createQueries = (customBackend) => ({
14957
- useSavedViewsQuery: (customBackend == null ? void 0 : customBackend.useSavedViewsQuery) ?? useSavedViewsQuery,
14958
- useSavedViewsPermissions: (customBackend == null ? void 0 : customBackend.useSavedViewsPermissions) ?? useSavedViewsPermissions,
14959
- useCreateSavedView: (customBackend == null ? void 0 : customBackend.useCreateSavedView) ?? useCreateSavedView,
14960
- useUpdateSavedView: (customBackend == null ? void 0 : customBackend.useUpdateSavedView) ?? useUpdateSavedView,
14961
- useDeleteSavedView: (customBackend == null ? void 0 : customBackend.useDeleteSavedView) ?? useDeleteSavedView,
14962
- useFetchSavedViewById: (customBackend == null ? void 0 : customBackend.useFetchSavedViewById) ?? useFetchSavedViewById
14963
- });
14964
-
14965
14958
  // src/components/saved-views/SavedViews.tsx
14966
14959
  var StyledPanel = styled_components_esm_default.div`
14967
14960
  border: ${({ provider }) => provider === "data-table" ? "1px solid #d6dadc" : "none"};
@@ -14969,15 +14962,14 @@ var StyledPanel = styled_components_esm_default.div`
14969
14962
  var queryClient = new QueryClient();
14970
14963
  var SavedViewsContent = (props) => {
14971
14964
  const { projectId, companyId } = props;
14972
- const backend = createQueries(props.backend);
14973
14965
  const queryInput = {
14974
14966
  domain: props.domain,
14975
14967
  tableName: props.tableName,
14976
- projectId,
14968
+ projectId: projectId ?? void 0,
14977
14969
  companyId
14978
14970
  };
14979
- const { data: savedViews } = backend.useSavedViewsQuery(queryInput);
14980
- const { mutate: deleteSavedView } = backend.useDeleteSavedView(queryInput);
14971
+ const { data: savedViews } = useSavedViewsQuery(queryInput);
14972
+ const { mutate: deleteSavedView } = useDeleteSavedView(queryInput);
14981
14973
  const { showToast } = useToastAlertContext3();
14982
14974
  const i18n = useI18nContext11();
14983
14975
  const [activeModal, setActiveModal] = useState4(null);
@@ -15005,7 +14997,7 @@ var SavedViewsContent = (props) => {
15005
14997
  domain: props.domain,
15006
14998
  tableName: props.tableName,
15007
14999
  userId: props.userId,
15008
- projectId,
15000
+ projectId: projectId ?? void 0,
15009
15001
  companyId,
15010
15002
  defaultView: props.defaultView,
15011
15003
  onSelect: props.onSelect
@@ -15014,7 +15006,7 @@ var SavedViewsContent = (props) => {
15014
15006
  props.presetViews,
15015
15007
  openSharedViewModal
15016
15008
  );
15017
- const { data: fetchedView, isError: fetchError } = backend.useFetchSavedViewById(
15009
+ const { data: fetchedView, isError: fetchError } = useFetchSavedViewById(
15018
15010
  (modalData == null ? void 0 : modalData.viewId) ?? null,
15019
15011
  queryInput,
15020
15012
  Boolean(modalData == null ? void 0 : modalData.viewId)
@@ -15024,8 +15016,8 @@ var SavedViewsContent = (props) => {
15024
15016
  isPending: isCreating,
15025
15017
  error: createError,
15026
15018
  reset: resetCreateError
15027
- } = backend.useCreateSavedView(queryInput);
15028
- useEffect4(() => {
15019
+ } = useCreateSavedView(queryInput);
15020
+ useEffect3(() => {
15029
15021
  if (fetchError) {
15030
15022
  showToast.error(i18n.t("savedViews.errors.notFound"));
15031
15023
  selectView(selectedView ?? props.defaultView);
@@ -15111,8 +15103,7 @@ var SavedViewsContent = (props) => {
15111
15103
  savedViews: allViews,
15112
15104
  provider: props.provider,
15113
15105
  userId: props.userId,
15114
- onClearTemporary: clearTemporaryView,
15115
- backend
15106
+ onClearTemporary: clearTemporaryView
15116
15107
  }
15117
15108
  ))
15118
15109
  ), (isModalOpen("create" /* CREATE */) || isModalOpen("update" /* UPDATE */)) && /* @__PURE__ */ React22.createElement(
@@ -15127,8 +15118,7 @@ var SavedViewsContent = (props) => {
15127
15118
  selectedSavedView: selectedView,
15128
15119
  onSelect: selectView,
15129
15120
  setOpenEditCreateModal: closeModal,
15130
- defaultView: props.defaultView,
15131
- backend
15121
+ defaultView: props.defaultView
15132
15122
  }
15133
15123
  ), selectedView && isModalOpen("delete" /* DELETE */) && /* @__PURE__ */ React22.createElement(
15134
15124
  SavedViewsDeleteConfirmationModalShared,
@@ -15173,37 +15163,27 @@ var DEFAULT_COLUMN_STATE = {
15173
15163
  rowGroupIndex: null,
15174
15164
  flex: null
15175
15165
  };
15176
- var isColGroupDef = (colDef) => {
15177
- return "children" in colDef && Array.isArray(colDef.children);
15178
- };
15166
+ var flattenColumnDefs = (defs) => defs.flatMap((d) => "children" in d ? flattenColumnDefs(d.children) : [d]);
15179
15167
  var getColumnStateFromDefs = (columnDefs) => {
15180
- return columnDefs.flatMap((colDef) => {
15181
- if (isColGroupDef(colDef)) {
15182
- return getColumnStateFromDefs(colDef.children);
15183
- }
15184
- return getColumnStateFromSingleDef(colDef);
15185
- }).filter(
15186
- (col) => col !== null
15187
- );
15188
- };
15189
- var getColumnStateFromSingleDef = (colDef) => {
15190
- const field = colDef.field ?? colDef.colId;
15191
- if (!field)
15192
- return null;
15193
- return {
15194
- colId: field,
15195
- hide: colDef.hide ?? false,
15196
- pinned: colDef.pinned ?? null,
15197
- width: colDef.width ?? colDef.minWidth ?? DEFAULT_COLUMN_STATE.width,
15198
- sort: null,
15199
- sortIndex: null,
15200
- pivot: false,
15201
- pivotIndex: null,
15202
- aggFunc: null,
15203
- rowGroup: false,
15204
- rowGroupIndex: null,
15205
- flex: colDef.flex ?? null
15206
- };
15168
+ return flattenColumnDefs(columnDefs).map((colDef) => {
15169
+ const field = colDef.field ?? colDef.colId;
15170
+ if (!field)
15171
+ return null;
15172
+ return {
15173
+ colId: field,
15174
+ hide: colDef.hide ?? false,
15175
+ pinned: colDef.pinned ?? null,
15176
+ width: colDef.width ?? colDef.minWidth ?? DEFAULT_COLUMN_STATE.width,
15177
+ sort: null,
15178
+ sortIndex: null,
15179
+ pivot: false,
15180
+ pivotIndex: null,
15181
+ aggFunc: null,
15182
+ rowGroup: false,
15183
+ rowGroupIndex: null,
15184
+ flex: colDef.flex ?? null
15185
+ };
15186
+ }).filter((col) => col !== null);
15207
15187
  };
15208
15188
  var extractDefaultView = (gridApi, receivedConfig) => {
15209
15189
  var _a, _b;
@@ -15231,7 +15211,7 @@ var useNormalizedDefaultViews = (defaultViews, gridApi) => {
15231
15211
  };
15232
15212
 
15233
15213
  // src/components/adapters/smart-grid/useSmartGridConfig.ts
15234
- import { useState as useState5, useEffect as useEffect5, useRef as useRef4 } from "react";
15214
+ import { useState as useState5, useEffect as useEffect4 } from "react";
15235
15215
  var GRID_STATE_EVENTS = [
15236
15216
  "sortChanged",
15237
15217
  "filterOpened",
@@ -15250,14 +15230,10 @@ var useSmartGridConfig = (gridApi) => {
15250
15230
  const [config, setConfig] = useState5(
15251
15231
  () => getSmartGridConfig(gridApi)
15252
15232
  );
15253
- const eventListenersDisabledRef = useRef4(false);
15254
- useEffect5(() => {
15233
+ useEffect4(() => {
15255
15234
  if (!gridApi)
15256
15235
  return;
15257
15236
  const updateConfig = () => {
15258
- if (eventListenersDisabledRef.current) {
15259
- return;
15260
- }
15261
15237
  setConfig(getSmartGridConfig(gridApi));
15262
15238
  };
15263
15239
  GRID_STATE_EVENTS.forEach((event) => {
@@ -15269,13 +15245,7 @@ var useSmartGridConfig = (gridApi) => {
15269
15245
  });
15270
15246
  };
15271
15247
  }, [gridApi]);
15272
- const disableEventListeners = () => {
15273
- eventListenersDisabledRef.current = true;
15274
- };
15275
- const enableEventListeners = () => {
15276
- eventListenersDisabledRef.current = false;
15277
- };
15278
- return { config, setConfig, disableEventListeners, enableEventListeners };
15248
+ return { config, setConfig };
15279
15249
  };
15280
15250
 
15281
15251
  // src/components/adapters/smart-grid/SmartGridSavedViews.tsx
@@ -15286,21 +15256,18 @@ var SmartGridSavedViews = (props) => {
15286
15256
  const defaultView = presetViews.find((view) => view.id === "default") ?? presetViews[0];
15287
15257
  const onSelect = useCallback4(
15288
15258
  ({ item }) => {
15289
- var _a;
15290
15259
  if (!gridApi)
15291
15260
  return item;
15292
15261
  const isPresetView = item.view_level === "default";
15293
- const newConfig = item.table_config;
15294
- const transformedConfig = ((_a = props.transformSettings) == null ? void 0 : _a.call(props, newConfig)) ?? newConfig;
15295
15262
  if (isPresetView) {
15296
15263
  updateTableConfig(item, gridApi, "smart-grid");
15297
- setTableConfig(transformedConfig);
15264
+ setTableConfig(item.table_config);
15298
15265
  return item;
15299
15266
  }
15300
15267
  const updatedView = {
15301
15268
  ...item,
15302
15269
  table_config: customAndConfigSync(
15303
- transformedConfig,
15270
+ item.table_config,
15304
15271
  tableConfig
15305
15272
  )
15306
15273
  };
@@ -15322,8 +15289,7 @@ var SmartGridSavedViews = (props) => {
15322
15289
  defaultView,
15323
15290
  presetViews,
15324
15291
  tableName: props.tableName,
15325
- tableConfig,
15326
- backend: props.backend
15292
+ tableConfig
15327
15293
  }
15328
15294
  );
15329
15295
  };