@procore/saved-views 1.0.1-estimatingFork.3 → 1.1.0-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.
@@ -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
  }
@@ -11385,7 +11385,7 @@ var SavedViewCollectionMenuItem = (props) => {
11385
11385
  loading: props.isUpdateProcessing
11386
11386
  },
11387
11387
  i18n.t("savedViews.actions.update")
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(
11388
+ )), 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,12 +11433,191 @@ 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 useI18nContext4 } from "@procore/core-react";
11436
+ import { Flex as Flex3, useI18nContext as useI18nContext5 } 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 getBasePath = (companyId, projectId) => {
11489
+ if (projectId) {
11490
+ return `/rest/v2.0/companies/${companyId}/projects/${projectId}/saved_views`;
11491
+ }
11492
+ return `/rest/v2.0/companies/${companyId}/saved_views`;
11493
+ };
11494
+ var useApiRequest = (props, method, mutationKey) => {
11495
+ const { projectId, companyId, domain, tableName } = props;
11496
+ const queryClient2 = useQueryClient();
11497
+ const { locale: locale2 } = useI18nContext3();
11498
+ const basePath = getBasePath(companyId, projectId);
11499
+ const queryKey = ["savedViews", domain, tableName, companyId, projectId];
11500
+ return useMutation({
11501
+ mutationKey,
11502
+ mutationFn: async (savedView) => {
11503
+ let url = "";
11504
+ if (method === "DELETE" || method === "PUT") {
11505
+ url = `${basePath}/${savedView.share_token}?permissions_domain=${domain}`;
11506
+ } else {
11507
+ url = `${basePath}?table_name=${tableName}&permissions_domain=${domain}`;
11508
+ }
11509
+ const response = await requestJSON(url, {
11510
+ method,
11511
+ body: JSON.stringify(savedView),
11512
+ headers: {
11513
+ "Content-Type": "application/json",
11514
+ "Accept-Language": locale2
11515
+ }
11516
+ });
11517
+ if (response.error) {
11518
+ throw response.error;
11519
+ }
11520
+ return response.data;
11521
+ },
11522
+ onSuccess: (savedView) => {
11523
+ if (method === "DELETE" || method === "POST") {
11524
+ queryClient2.invalidateQueries({
11525
+ queryKey
11526
+ });
11527
+ return;
11528
+ } else {
11529
+ const oldData = queryClient2.getQueryData(queryKey);
11530
+ const oldView = oldData?.find(
11531
+ (item) => item.share_token === savedView.share_token
11532
+ );
11533
+ if (oldView?.name !== savedView.name) {
11534
+ queryClient2.invalidateQueries({
11535
+ queryKey
11536
+ });
11537
+ return;
11538
+ }
11539
+ }
11540
+ queryClient2.setQueryData(queryKey, (oldData) => {
11541
+ if (!oldData)
11542
+ return [savedView];
11543
+ return oldData.map(
11544
+ (item) => item.share_token === savedView.share_token ? savedView : item
11545
+ );
11546
+ });
11547
+ }
11548
+ });
11549
+ };
11550
+
11440
11551
  // src/utils/constants/viewLevels.ts
11441
- var VIEW_LEVELS = ["company", "project", "personal"];
11552
+ var PROJECT_LEVEL_TOOL_VIEW_LEVELS = [
11553
+ "company",
11554
+ "project",
11555
+ "personal"
11556
+ ];
11557
+ var COMPANY_LEVEL_TOOL_VIEW_LEVELS = ["company", "personal"];
11558
+ var getViewLevels = (isProjectLevelTool) => isProjectLevelTool ? PROJECT_LEVEL_TOOL_VIEW_LEVELS : COMPANY_LEVEL_TOOL_VIEW_LEVELS;
11559
+
11560
+ // src/utils/api/queries.ts
11561
+ var PAGE_SIZE = 50 * PROJECT_LEVEL_TOOL_VIEW_LEVELS.length;
11562
+ var getBasePath2 = (companyId, projectId) => {
11563
+ if (projectId) {
11564
+ return `/rest/v2.0/companies/${companyId}/projects/${projectId}/saved_views`;
11565
+ }
11566
+ return `/rest/v2.0/companies/${companyId}/saved_views`;
11567
+ };
11568
+ var useSavedViewsQuery = (props) => {
11569
+ const { projectId, companyId, domain, tableName } = props;
11570
+ const basePath = getBasePath2(companyId, projectId);
11571
+ const url = `${basePath}?table_name=${tableName}&permissions_domain=${domain}`;
11572
+ return useQuery({
11573
+ queryKey: ["savedViews", domain, tableName, companyId, projectId],
11574
+ queryFn: async () => {
11575
+ const getUrl2 = `${url}&per_page=${PAGE_SIZE}`;
11576
+ const response = await requestJSON(getUrl2);
11577
+ return response.data;
11578
+ }
11579
+ });
11580
+ };
11581
+ var useSavedViewsPermissions = (props) => {
11582
+ const { projectId, companyId, domain } = props;
11583
+ const basePath = getBasePath2(companyId, projectId);
11584
+ const url = `${basePath}/permissions?permissions_domain=${domain}`;
11585
+ return useQuery({
11586
+ queryKey: ["savedViewsConfig", domain, companyId, projectId],
11587
+ queryFn: async () => {
11588
+ const response = await requestJSON(url);
11589
+ return response.data;
11590
+ }
11591
+ });
11592
+ };
11593
+ var useCreateSavedView = (props) => useApiRequest(props, "POST", [
11594
+ "createSavedView",
11595
+ props.domain,
11596
+ props.tableName
11597
+ ]);
11598
+ var useUpdateSavedView = (props) => useApiRequest(props, "PUT", [
11599
+ "updateSavedView",
11600
+ props.domain,
11601
+ props.tableName
11602
+ ]);
11603
+ var useDeleteSavedView = (props) => useApiRequest(props, "DELETE", [
11604
+ "deleteSavedView",
11605
+ props.domain,
11606
+ props.tableName
11607
+ ]);
11608
+ var useFetchSavedViewById = (savedViewToken, queryInput, enabled = true) => {
11609
+ const { projectId, companyId, domain } = queryInput;
11610
+ const basePath = getBasePath2(companyId, projectId);
11611
+ return useQuery({
11612
+ enabled: enabled && Boolean(savedViewToken),
11613
+ queryKey: ["savedView", savedViewToken, companyId, projectId],
11614
+ queryFn: async () => {
11615
+ const url = `${basePath}/${savedViewToken}?permissions_domain=${domain}`;
11616
+ const response = await requestJSON(url);
11617
+ return response.data;
11618
+ }
11619
+ });
11620
+ };
11442
11621
 
11443
11622
  // src/components/panels/PanelContentUtils.ts
11444
11623
  var import_lodash = __toESM(require_lodash());
@@ -11513,12 +11692,10 @@ var getColumnIdentifier = (col) => {
11513
11692
  };
11514
11693
  var updateTableConfig = (view, tableApi, provider) => {
11515
11694
  if (provider === "smart-grid") {
11516
- setTimeout(() => {
11517
- setSmartGridConfig(
11518
- tableApi,
11519
- view.table_config
11520
- );
11521
- }, 0);
11695
+ setSmartGridConfig(
11696
+ tableApi,
11697
+ view.table_config
11698
+ );
11522
11699
  } else {
11523
11700
  const dataTableApi = tableApi;
11524
11701
  const tableConfig = view.table_config;
@@ -11590,20 +11767,13 @@ var cleanObject = (table_config, provider) => {
11590
11767
  var normalizeForComparison = (config) => {
11591
11768
  if (!config?.columnState)
11592
11769
  return config;
11593
- const filteredColumnState = config.columnState.filter(
11594
- (col) => {
11595
- const colId = getColumnIdentifier(col);
11596
- return colId !== "drag_handle" && colId !== "ag-Grid-AutoColumn";
11597
- }
11598
- );
11599
11770
  return {
11600
- ...import_lodash.default.omit(config, ["enableRowGrouping", "enableColumnGrouping"]),
11601
- columnState: filteredColumnState.map((col) => {
11602
- const res = import_lodash.default.omit(col, ["aggFunc"]);
11771
+ ...config,
11772
+ columnState: config.columnState.map((col) => {
11603
11773
  if (col.flex) {
11604
- return import_lodash.default.omit(res, ["width", "flex"]);
11774
+ return import_lodash.default.omit(col, ["width", "flex"]);
11605
11775
  }
11606
- return res;
11776
+ return col;
11607
11777
  })
11608
11778
  };
11609
11779
  };
@@ -11616,17 +11786,10 @@ var isEqual = (viewTableConfig, tableConfig, defaultViewConfig, provider) => {
11616
11786
  );
11617
11787
  const normalizedViewConfig = normalizeForComparison(syncedViewTableConfig);
11618
11788
  const normalizedCurrentConfig = normalizeForComparison(tableConfig);
11619
- const cleanedViewConfig = cleanObject(normalizedViewConfig, provider);
11620
- const cleanedCurrentConfig = cleanObject(normalizedCurrentConfig, provider);
11621
- const isEqual2 = import_lodash.default.isEqual(cleanedViewConfig, cleanedCurrentConfig);
11622
- if (!isEqual2) {
11623
- console.log(
11624
- "[SavedViews]: Showing update button - view config, current config",
11625
- cleanedViewConfig,
11626
- cleanedCurrentConfig
11627
- );
11628
- }
11629
- return isEqual2;
11789
+ return import_lodash.default.isEqual(
11790
+ cleanObject(normalizedViewConfig, provider),
11791
+ cleanObject(normalizedCurrentConfig, provider)
11792
+ );
11630
11793
  };
11631
11794
  var hasPermissionForViewLevel = (viewLevel, permissions) => {
11632
11795
  switch (viewLevel) {
@@ -11643,9 +11806,10 @@ var hasPermissionForViewLevel = (viewLevel, permissions) => {
11643
11806
 
11644
11807
  // src/components/panels/useGroups.ts
11645
11808
  import { useState as useState2 } from "react";
11646
- var useGroups = () => {
11809
+ var useGroups = (isProjectLevelTool) => {
11810
+ const viewLevels = getViewLevels(isProjectLevelTool);
11647
11811
  const [groups, setGroups] = useState2(
11648
- Object.fromEntries(VIEW_LEVELS.map((level) => [level, true]))
11812
+ Object.fromEntries(viewLevels.map((level) => [level, true]))
11649
11813
  );
11650
11814
  const toggleGroup = (group) => {
11651
11815
  setGroups((groups2) => ({ ...groups2, [group]: !groups2[group] }));
@@ -11659,7 +11823,7 @@ import {
11659
11823
  Flex as Flex2,
11660
11824
  spacing,
11661
11825
  Typography,
11662
- useI18nContext as useI18nContext3
11826
+ useI18nContext as useI18nContext4
11663
11827
  } from "@procore/core-react";
11664
11828
  import React16 from "react";
11665
11829
  var groupIcon = (group) => {
@@ -11679,7 +11843,7 @@ var Header = styled_components_esm_default(Flex2)`
11679
11843
  }
11680
11844
  `;
11681
11845
  var ViewLevelHeader = ({ expanded, toggleGroup, group }) => {
11682
- const I18n = useI18nContext3();
11846
+ const I18n = useI18nContext4();
11683
11847
  return /* @__PURE__ */ React16.createElement(
11684
11848
  Header,
11685
11849
  {
@@ -11736,9 +11900,9 @@ var Panel2 = styled_components_esm_default(DetailPage.Card)`
11736
11900
  var PanelContent = (props) => {
11737
11901
  const { queryInput, selectedSavedView, tableConfig } = props;
11738
11902
  const { showToast } = useToastAlertContext2();
11739
- const I18n = useI18nContext4();
11740
- const { data: savedViewsFromQuery, error: savedViewsError } = props.backend.useSavedViewsQuery(props.queryInput);
11741
- const updateMutation = props.backend.useUpdateSavedView(queryInput);
11903
+ const I18n = useI18nContext5();
11904
+ const { data: savedViewsFromQuery, error: savedViewsError } = useSavedViewsQuery(props.queryInput);
11905
+ const updateMutation = useUpdateSavedView(queryInput);
11742
11906
  const { mutate: updateSavedView } = updateMutation;
11743
11907
  const isUpdateLoading = "isPending" in updateMutation ? updateMutation.isPending : updateMutation.isLoading ?? false;
11744
11908
  const savedViews = props.savedViews ?? savedViewsFromQuery;
@@ -11749,14 +11913,14 @@ var PanelContent = (props) => {
11749
11913
  errorToastRef.current = savedViewsError;
11750
11914
  }
11751
11915
  }, [savedViewsError, showToast, I18n]);
11752
- const { data: permissions } = props.backend.useSavedViewsPermissions(
11753
- props.queryInput
11754
- );
11916
+ const { data: permissions } = useSavedViewsPermissions(props.queryInput);
11755
11917
  const selectedRowRef = useScrollToRef(savedViews);
11756
- const { groups, toggleGroup } = useGroups();
11757
11918
  const isTemporarySelected = selectedSavedView?.id === "temporary";
11758
11919
  const temporaryView = savedViews?.find((view) => view.id === "temporary");
11759
11920
  const presetViews = props.presetViews || [props.defaultView];
11921
+ const isProjectLevelTool = !!queryInput.projectId;
11922
+ const viewLevels = getViewLevels(isProjectLevelTool);
11923
+ const { groups, toggleGroup } = useGroups(isProjectLevelTool);
11760
11924
  const onUpdate = (data) => {
11761
11925
  const newSavedView = {
11762
11926
  ...data,
@@ -11785,8 +11949,7 @@ var PanelContent = (props) => {
11785
11949
  {
11786
11950
  item: temporaryView,
11787
11951
  selected: isTemporarySelected,
11788
- onClearTemporary: props.onClearTemporary,
11789
- enableSharingViews: false
11952
+ onClearTemporary: props.onClearTemporary
11790
11953
  }
11791
11954
  )
11792
11955
  ), presetViews.map((presetView) => {
@@ -11803,12 +11966,11 @@ var PanelContent = (props) => {
11803
11966
  SavedViewCollectionMenuItem,
11804
11967
  {
11805
11968
  item: presetView,
11806
- selected: isSelected,
11807
- enableSharingViews: false
11969
+ selected: isSelected
11808
11970
  }
11809
11971
  )
11810
11972
  );
11811
- }), VIEW_LEVELS.map((level) => {
11973
+ }), viewLevels.map((level) => {
11812
11974
  const isExpanded = groups[level];
11813
11975
  const views = isExpanded && savedViews ? savedViews.filter(
11814
11976
  (view) => view.view_level === level && view.id !== "temporary"
@@ -11852,8 +12014,7 @@ var PanelContent = (props) => {
11852
12014
  isUpdateProcessing: isUpdateLoading,
11853
12015
  onEdit: () => props.openModal("update" /* UPDATE */),
11854
12016
  onDelete: props.onDelete,
11855
- permissions,
11856
- enableSharingViews: false
12017
+ permissions
11857
12018
  }
11858
12019
  )
11859
12020
  );
@@ -11870,7 +12031,7 @@ import {
11870
12031
  Tooltip,
11871
12032
  useI18nContext as useI18nContext11
11872
12033
  } from "@procore/core-react";
11873
- import React22, { useState as useState4, useEffect as useEffect4, useCallback as useCallback3 } from "react";
12034
+ import React22, { useState as useState4, useEffect as useEffect3, useCallback as useCallback3 } from "react";
11874
12035
  import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
11875
12036
  import { useToastAlertContext as useToastAlertContext3, ToastAlertProvider } from "@procore/toast-alert";
11876
12037
 
@@ -11880,7 +12041,7 @@ import {
11880
12041
  ConfirmModal,
11881
12042
  Modal,
11882
12043
  P as P2,
11883
- useI18nContext as useI18nContext5
12044
+ useI18nContext as useI18nContext6
11884
12045
  } from "@procore/core-react";
11885
12046
  import React18 from "react";
11886
12047
  var SavedViewsDeleteConfirmationModalShared = ({
@@ -11888,7 +12049,7 @@ var SavedViewsDeleteConfirmationModalShared = ({
11888
12049
  onDelete,
11889
12050
  open
11890
12051
  }) => {
11891
- const i18n = useI18nContext5();
12052
+ const i18n = useI18nContext6();
11892
12053
  return /* @__PURE__ */ React18.createElement(
11893
12054
  ConfirmModal,
11894
12055
  {
@@ -11919,7 +12080,7 @@ import {
11919
12080
  Modal as Modal2,
11920
12081
  spacing as spacing3,
11921
12082
  Typography as Typography2,
11922
- useI18nContext as useI18nContext6
12083
+ useI18nContext as useI18nContext7
11923
12084
  } from "@procore/core-react";
11924
12085
  import * as React19 from "react";
11925
12086
 
@@ -14216,10 +14377,11 @@ var TupleSchema = class extends Schema {
14216
14377
  create$1.prototype = TupleSchema.prototype;
14217
14378
 
14218
14379
  // src/components/modals/form-modal/FormModalBaseUtils.ts
14219
- var getViewLevelOptions = (permissions, i18n) => {
14380
+ var getViewLevelOptions = (permissions, i18n, isProjectLevelTool = true) => {
14220
14381
  const options = ["personal"];
14221
- if (permissions?.can_create_project_saved_views)
14382
+ if (isProjectLevelTool && permissions?.can_create_project_saved_views) {
14222
14383
  options.push("project");
14384
+ }
14223
14385
  if (permissions?.can_create_company_saved_views)
14224
14386
  options.push("company");
14225
14387
  return options.map((option) => ({
@@ -14249,7 +14411,6 @@ function extractMessage(error, I18n) {
14249
14411
  }
14250
14412
 
14251
14413
  // src/components/modals/form-modal/FormModalBase.tsx
14252
- var { useEffect: useEffect2, useRef: useRef2 } = React19;
14253
14414
  var ScrollContainer = styled_components_esm_default("div")`
14254
14415
  overflow: auto;
14255
14416
  `;
@@ -14266,38 +14427,22 @@ var FormModalBase = ({
14266
14427
  defaultView,
14267
14428
  selectedSavedView,
14268
14429
  setOpenEditCreateModal,
14269
- onSelect,
14270
- backend
14430
+ onSelect
14271
14431
  }) => {
14272
- const I18n = useI18nContext6();
14432
+ const I18n = useI18nContext7();
14273
14433
  const NAME_MAX_LENGTH = 150;
14274
- const originalBodyWidth = useRef2("");
14275
- useEffect2(() => {
14276
- if (open) {
14277
- originalBodyWidth.current = document.body.style.width || "";
14278
- document.body.style.width = "100%";
14279
- } else {
14280
- document.body.style.width = originalBodyWidth.current;
14281
- }
14282
- return () => {
14283
- if (originalBodyWidth.current !== void 0) {
14284
- document.body.style.width = originalBodyWidth.current;
14285
- }
14286
- };
14287
- }, [open]);
14288
- const { useCreateSavedView: useCreateSavedView2, useUpdateSavedView: useUpdateSavedView2, useSavedViewsPermissions: useSavedViewsPermissions2 } = backend;
14289
14434
  const {
14290
14435
  mutate: createSavedView,
14291
14436
  isPending: isCreating,
14292
14437
  error: createError,
14293
14438
  reset: resetCreateMutation
14294
- } = useCreateSavedView2(queryInput);
14439
+ } = useCreateSavedView(queryInput);
14295
14440
  const {
14296
14441
  mutate: updateSavedView,
14297
14442
  isPending: isUpdating,
14298
14443
  error: updateError,
14299
14444
  reset: resetUpdateMutation
14300
- } = useUpdateSavedView2(queryInput);
14445
+ } = useUpdateSavedView(queryInput);
14301
14446
  const resetMutations = () => {
14302
14447
  resetCreateMutation();
14303
14448
  resetUpdateMutation();
@@ -14306,7 +14451,7 @@ var FormModalBase = ({
14306
14451
  resetMutations();
14307
14452
  onCancel();
14308
14453
  };
14309
- const { data: permissions } = useSavedViewsPermissions2(queryInput);
14454
+ const { data: permissions } = useSavedViewsPermissions(queryInput);
14310
14455
  const isLoading = isCreating || isUpdating;
14311
14456
  const errors = extractMessage(createError || updateError, I18n);
14312
14457
  const handleOnSubmit = (data) => {
@@ -14337,7 +14482,12 @@ var FormModalBase = ({
14337
14482
  });
14338
14483
  }
14339
14484
  };
14340
- const viewLevelOptions = getViewLevelOptions(permissions, I18n);
14485
+ const isProjectLevelTool = !!queryInput.projectId;
14486
+ const viewLevelOptions = getViewLevelOptions(
14487
+ permissions,
14488
+ I18n,
14489
+ isProjectLevelTool
14490
+ );
14341
14491
  return /* @__PURE__ */ React19.createElement(
14342
14492
  Modal2,
14343
14493
  {
@@ -14417,7 +14567,6 @@ var FormModalBase = ({
14417
14567
  Form.Select,
14418
14568
  {
14419
14569
  name: "view_level",
14420
- qa: { label: "view-level" },
14421
14570
  options: viewLevelOptions,
14422
14571
  label: I18n.t("savedViews.modal.fields.viewLevel"),
14423
14572
  colWidth: 12,
@@ -14441,7 +14590,7 @@ var FormModalBase = ({
14441
14590
  };
14442
14591
 
14443
14592
  // src/components/modals/form-modal/FormModal.tsx
14444
- import { useI18nContext as useI18nContext7 } from "@procore/core-react";
14593
+ import { useI18nContext as useI18nContext8 } from "@procore/core-react";
14445
14594
  var FormModal = ({
14446
14595
  open,
14447
14596
  mode,
@@ -14452,10 +14601,9 @@ var FormModal = ({
14452
14601
  selectedSavedView,
14453
14602
  setOpenEditCreateModal,
14454
14603
  onSelect,
14455
- defaultView,
14456
- backend
14604
+ defaultView
14457
14605
  }) => {
14458
- const i18n = useI18nContext7();
14606
+ const i18n = useI18nContext8();
14459
14607
  return /* @__PURE__ */ React20.createElement(
14460
14608
  FormModalBase,
14461
14609
  {
@@ -14471,8 +14619,7 @@ var FormModal = ({
14471
14619
  selectedSavedView,
14472
14620
  setOpenEditCreateModal,
14473
14621
  onSelect,
14474
- defaultView,
14475
- backend
14622
+ defaultView
14476
14623
  }
14477
14624
  );
14478
14625
  };
@@ -14489,7 +14636,7 @@ import {
14489
14636
  P as P3,
14490
14637
  spacing as spacing4,
14491
14638
  Typography as Typography3,
14492
- useI18nContext as useI18nContext8
14639
+ useI18nContext as useI18nContext9
14493
14640
  } from "@procore/core-react";
14494
14641
  import * as React21 from "react";
14495
14642
  var SharedViewFormModal = ({
@@ -14502,7 +14649,7 @@ var SharedViewFormModal = ({
14502
14649
  isCreating,
14503
14650
  resetCreateError
14504
14651
  }) => {
14505
- const I18n = useI18nContext8();
14652
+ const I18n = useI18nContext9();
14506
14653
  const NAME_MAX_LENGTH = 150;
14507
14654
  const errors = extractMessage(createError, I18n);
14508
14655
  const handleNameChange = () => {
@@ -14632,9 +14779,9 @@ var SharedViewFormModal = ({
14632
14779
  };
14633
14780
 
14634
14781
  // src/utils/hooks/useViewSelection.ts
14635
- import { useState as useState3, useCallback as useCallback2, useEffect as useEffect3, useRef as useRef3, useMemo } from "react";
14782
+ import { useState as useState3, useCallback as useCallback2, useEffect as useEffect2, useRef as useRef2, useMemo } from "react";
14636
14783
  import { useSearchParams } from "react-router-dom";
14637
- import { useI18nContext as useI18nContext9 } from "@procore/core-react";
14784
+ import { useI18nContext as useI18nContext10 } from "@procore/core-react";
14638
14785
 
14639
14786
  // src/utils/viewStorage.ts
14640
14787
  var ViewStorage = {
@@ -14697,11 +14844,12 @@ var restoreUrlParameter = (currentParam, previousParam, setSearchParams) => {
14697
14844
  }
14698
14845
  };
14699
14846
  var useViewSelection = (config, savedViews, presetViews, openSharedViewModal) => {
14700
- const I18n = useI18nContext9();
14701
- const storageKey = `savedView_${config.domain}_${config.tableName}_${config.companyId}_${config.projectId}_${config.userId}`;
14847
+ const I18n = useI18nContext10();
14848
+ const projectIdSegment = config.projectId ?? "company";
14849
+ const storageKey = `savedView_${config.domain}_${config.tableName}_${config.companyId}_${projectIdSegment}_${config.userId}`;
14702
14850
  const temporaryStorageKey = `${storageKey}-temporary`;
14703
14851
  const [searchParams, setSearchParams] = useSearchParams();
14704
- const previousSavedViewParamRef = useRef3(null);
14852
+ const previousSavedViewParamRef = useRef2(null);
14705
14853
  const [selectedSavedView, setSelectedSavedView] = useState3(() => {
14706
14854
  const stored = ViewStorage.load(storageKey, config.defaultView);
14707
14855
  return stored ?? config.defaultView;
@@ -14772,7 +14920,7 @@ var useViewSelection = (config, savedViews, presetViews, openSharedViewModal) =>
14772
14920
  },
14773
14921
  [isViewAlreadySelected, openSharedViewModal, allViews, selectView]
14774
14922
  );
14775
- useEffect3(() => {
14923
+ useEffect2(() => {
14776
14924
  const savedViewId = searchParams.get("saved-view");
14777
14925
  restoreUrlParameter(
14778
14926
  savedViewId,
@@ -14796,177 +14944,6 @@ var useViewSelection = (config, savedViews, presetViews, openSharedViewModal) =>
14796
14944
  };
14797
14945
  };
14798
14946
 
14799
- // node_modules/@procore/core-http/dist/modern/index.js
14800
- function getCSRFToken() {
14801
- const token = document.cookie.match("(^|;)\\s*csrf_token\\s*=\\s*([^;]+)");
14802
- return token ? decodeURIComponent(token.pop() || "") : "";
14803
- }
14804
- function getCSRFHeader() {
14805
- const csrfToken = getCSRFToken();
14806
- return csrfToken ? { "X-CSRF-TOKEN": csrfToken } : {};
14807
- }
14808
- function removeLeadingSlash(url) {
14809
- return url.startsWith("/") ? url.substring(1, url.length) : url;
14810
- }
14811
- function removeTrailingSlash(url) {
14812
- return url.endsWith("/") ? url.substring(0, url.length - 1) : url;
14813
- }
14814
- function applyBaseUrl(url, baseUrl) {
14815
- return `${removeTrailingSlash(baseUrl)}/${removeLeadingSlash(url)}`;
14816
- }
14817
- function getOptions({ headers, ...options }) {
14818
- const opts = {
14819
- credentials: "same-origin",
14820
- headers: {
14821
- ...getCSRFHeader(),
14822
- ...headers
14823
- },
14824
- mode: "same-origin",
14825
- ...options
14826
- };
14827
- return opts;
14828
- }
14829
- function getUrl(url, baseUrl) {
14830
- return baseUrl ? applyBaseUrl(url, baseUrl) : url;
14831
- }
14832
- function request(url, { baseUrl, ...options } = {}) {
14833
- return fetch(getUrl(url, baseUrl), getOptions(options));
14834
- }
14835
- function requestJSON(url, requestParams = {}) {
14836
- return request(url, requestParams).then(
14837
- (response) => response.json()
14838
- );
14839
- }
14840
-
14841
- // src/utils/api/queries.ts
14842
- import { useQuery } from "@tanstack/react-query";
14843
-
14844
- // src/utils/api/queriesHandler.ts
14845
- import { useMutation, useQueryClient } from "@tanstack/react-query";
14846
- import { useI18nContext as useI18nContext10 } from "@procore/core-react";
14847
- var useApiRequest = (props, method, mutationKey) => {
14848
- const { projectId, companyId, domain, tableName } = props;
14849
- const queryClient2 = useQueryClient();
14850
- const { locale: locale2 } = useI18nContext10();
14851
- return useMutation({
14852
- mutationKey,
14853
- mutationFn: async (savedView) => {
14854
- let url = "";
14855
- if (method === "DELETE" || method === "PUT") {
14856
- url = `/rest/v2.0/companies/${companyId}/projects/${projectId}/saved_views/${savedView.share_token}?permissions_domain=${domain}`;
14857
- } else {
14858
- url = `/rest/v2.0/companies/${companyId}/projects/${projectId}/saved_views?table_name=${tableName}&permissions_domain=${domain}`;
14859
- }
14860
- const response = await requestJSON(url, {
14861
- method,
14862
- body: JSON.stringify(savedView),
14863
- headers: {
14864
- "Content-Type": "application/json",
14865
- "Accept-Language": locale2
14866
- }
14867
- });
14868
- if (response.error) {
14869
- throw response.error;
14870
- }
14871
- return response.data;
14872
- },
14873
- onSuccess: (savedView) => {
14874
- if (method === "DELETE" || method === "POST") {
14875
- queryClient2.invalidateQueries({
14876
- queryKey: ["savedViews", domain, tableName]
14877
- });
14878
- return;
14879
- } else {
14880
- const oldData = queryClient2.getQueryData([
14881
- "savedViews",
14882
- domain,
14883
- tableName
14884
- ]);
14885
- const oldView = oldData?.find(
14886
- (item) => item.share_token === savedView.share_token
14887
- );
14888
- if (oldView?.name !== savedView.name) {
14889
- queryClient2.invalidateQueries({
14890
- queryKey: ["savedViews", domain, tableName]
14891
- });
14892
- return;
14893
- }
14894
- }
14895
- queryClient2.setQueryData(
14896
- ["savedViews", domain, tableName],
14897
- (oldData) => {
14898
- if (!oldData)
14899
- return [savedView];
14900
- return oldData.map(
14901
- (item) => item.share_token === savedView.share_token ? savedView : item
14902
- );
14903
- }
14904
- );
14905
- }
14906
- });
14907
- };
14908
-
14909
- // src/utils/api/queries.ts
14910
- var PAGE_SIZE = 50 * VIEW_LEVELS.length;
14911
- var useSavedViewsQuery = (props) => {
14912
- const { projectId, companyId, domain, tableName } = props;
14913
- const url = `/rest/v2.0/companies/${companyId}/projects/${projectId}/saved_views?table_name=${tableName}&permissions_domain=${domain}`;
14914
- return useQuery({
14915
- queryKey: ["savedViews", domain, tableName],
14916
- queryFn: async () => {
14917
- const getUrl2 = `${url}&per_page=${PAGE_SIZE}`;
14918
- const response = await requestJSON(getUrl2);
14919
- return response.data;
14920
- }
14921
- });
14922
- };
14923
- var useSavedViewsPermissions = (props) => {
14924
- const { projectId, companyId, domain } = props;
14925
- const url = `/rest/v2.0/companies/${companyId}/projects/${projectId}/saved_views/permissions?permissions_domain=${domain}`;
14926
- return useQuery({
14927
- queryKey: ["savedViewsConfig", domain],
14928
- queryFn: async () => {
14929
- const response = await requestJSON(url);
14930
- return response.data;
14931
- }
14932
- });
14933
- };
14934
- var useCreateSavedView = (props) => useApiRequest(props, "POST", [
14935
- "createSavedView",
14936
- props.domain,
14937
- props.tableName
14938
- ]);
14939
- var useUpdateSavedView = (props) => useApiRequest(props, "PUT", [
14940
- "updateSavedView",
14941
- props.domain,
14942
- props.tableName
14943
- ]);
14944
- var useDeleteSavedView = (props) => useApiRequest(props, "DELETE", [
14945
- "deleteSavedView",
14946
- props.domain,
14947
- props.tableName
14948
- ]);
14949
- var useFetchSavedViewById = (savedViewToken, queryInput, enabled = true) => {
14950
- const { projectId, companyId } = queryInput;
14951
- return useQuery({
14952
- enabled: enabled && Boolean(savedViewToken),
14953
- queryKey: ["savedView", savedViewToken],
14954
- queryFn: async () => {
14955
- const url = `/rest/v2.0/companies/${companyId}/projects/${projectId}/saved_views/${savedViewToken}`;
14956
- const response = await requestJSON(url);
14957
- return response.data;
14958
- }
14959
- });
14960
- };
14961
- var createQueries = (customBackend) => ({
14962
- useSavedViewsQuery: customBackend?.useSavedViewsQuery ?? useSavedViewsQuery,
14963
- useSavedViewsPermissions: customBackend?.useSavedViewsPermissions ?? useSavedViewsPermissions,
14964
- useCreateSavedView: customBackend?.useCreateSavedView ?? useCreateSavedView,
14965
- useUpdateSavedView: customBackend?.useUpdateSavedView ?? useUpdateSavedView,
14966
- useDeleteSavedView: customBackend?.useDeleteSavedView ?? useDeleteSavedView,
14967
- useFetchSavedViewById: customBackend?.useFetchSavedViewById ?? useFetchSavedViewById
14968
- });
14969
-
14970
14947
  // src/components/saved-views/SavedViews.tsx
14971
14948
  var StyledPanel = styled_components_esm_default.div`
14972
14949
  border: ${({ provider }) => provider === "data-table" ? "1px solid #d6dadc" : "none"};
@@ -14974,15 +14951,14 @@ var StyledPanel = styled_components_esm_default.div`
14974
14951
  var queryClient = new QueryClient();
14975
14952
  var SavedViewsContent = (props) => {
14976
14953
  const { projectId, companyId } = props;
14977
- const backend = createQueries(props.backend);
14978
14954
  const queryInput = {
14979
14955
  domain: props.domain,
14980
14956
  tableName: props.tableName,
14981
14957
  projectId,
14982
14958
  companyId
14983
14959
  };
14984
- const { data: savedViews } = backend.useSavedViewsQuery(queryInput);
14985
- const { mutate: deleteSavedView } = backend.useDeleteSavedView(queryInput);
14960
+ const { data: savedViews } = useSavedViewsQuery(queryInput);
14961
+ const { mutate: deleteSavedView } = useDeleteSavedView(queryInput);
14986
14962
  const { showToast } = useToastAlertContext3();
14987
14963
  const i18n = useI18nContext11();
14988
14964
  const [activeModal, setActiveModal] = useState4(null);
@@ -15019,7 +14995,7 @@ var SavedViewsContent = (props) => {
15019
14995
  props.presetViews,
15020
14996
  openSharedViewModal
15021
14997
  );
15022
- const { data: fetchedView, isError: fetchError } = backend.useFetchSavedViewById(
14998
+ const { data: fetchedView, isError: fetchError } = useFetchSavedViewById(
15023
14999
  modalData?.viewId ?? null,
15024
15000
  queryInput,
15025
15001
  Boolean(modalData?.viewId)
@@ -15029,8 +15005,8 @@ var SavedViewsContent = (props) => {
15029
15005
  isPending: isCreating,
15030
15006
  error: createError,
15031
15007
  reset: resetCreateError
15032
- } = backend.useCreateSavedView(queryInput);
15033
- useEffect4(() => {
15008
+ } = useCreateSavedView(queryInput);
15009
+ useEffect3(() => {
15034
15010
  if (fetchError) {
15035
15011
  showToast.error(i18n.t("savedViews.errors.notFound"));
15036
15012
  selectView(selectedView ?? props.defaultView);
@@ -15116,8 +15092,7 @@ var SavedViewsContent = (props) => {
15116
15092
  savedViews: allViews,
15117
15093
  provider: props.provider,
15118
15094
  userId: props.userId,
15119
- onClearTemporary: clearTemporaryView,
15120
- backend
15095
+ onClearTemporary: clearTemporaryView
15121
15096
  }
15122
15097
  ))
15123
15098
  ), (isModalOpen("create" /* CREATE */) || isModalOpen("update" /* UPDATE */)) && /* @__PURE__ */ React22.createElement(
@@ -15132,8 +15107,7 @@ var SavedViewsContent = (props) => {
15132
15107
  selectedSavedView: selectedView,
15133
15108
  onSelect: selectView,
15134
15109
  setOpenEditCreateModal: closeModal,
15135
- defaultView: props.defaultView,
15136
- backend
15110
+ defaultView: props.defaultView
15137
15111
  }
15138
15112
  ), selectedView && isModalOpen("delete" /* DELETE */) && /* @__PURE__ */ React22.createElement(
15139
15113
  SavedViewsDeleteConfirmationModalShared,
@@ -15178,37 +15152,27 @@ var DEFAULT_COLUMN_STATE = {
15178
15152
  rowGroupIndex: null,
15179
15153
  flex: null
15180
15154
  };
15181
- var isColGroupDef = (colDef) => {
15182
- return "children" in colDef && Array.isArray(colDef.children);
15183
- };
15155
+ var flattenColumnDefs = (defs) => defs.flatMap((d) => "children" in d ? flattenColumnDefs(d.children) : [d]);
15184
15156
  var getColumnStateFromDefs = (columnDefs) => {
15185
- return columnDefs.flatMap((colDef) => {
15186
- if (isColGroupDef(colDef)) {
15187
- return getColumnStateFromDefs(colDef.children);
15188
- }
15189
- return getColumnStateFromSingleDef(colDef);
15190
- }).filter(
15191
- (col) => col !== null
15192
- );
15193
- };
15194
- var getColumnStateFromSingleDef = (colDef) => {
15195
- const field = colDef.field ?? colDef.colId;
15196
- if (!field)
15197
- return null;
15198
- return {
15199
- colId: field,
15200
- hide: colDef.hide ?? false,
15201
- pinned: colDef.pinned ?? null,
15202
- width: colDef.width ?? colDef.minWidth ?? DEFAULT_COLUMN_STATE.width,
15203
- sort: null,
15204
- sortIndex: null,
15205
- pivot: false,
15206
- pivotIndex: null,
15207
- aggFunc: null,
15208
- rowGroup: false,
15209
- rowGroupIndex: null,
15210
- flex: colDef.flex ?? null
15211
- };
15157
+ return flattenColumnDefs(columnDefs).map((colDef) => {
15158
+ const field = colDef.field ?? colDef.colId;
15159
+ if (!field)
15160
+ return null;
15161
+ return {
15162
+ colId: field,
15163
+ hide: colDef.hide ?? false,
15164
+ pinned: colDef.pinned ?? null,
15165
+ width: colDef.width ?? colDef.minWidth ?? DEFAULT_COLUMN_STATE.width,
15166
+ sort: null,
15167
+ sortIndex: null,
15168
+ pivot: false,
15169
+ pivotIndex: null,
15170
+ aggFunc: null,
15171
+ rowGroup: false,
15172
+ rowGroupIndex: null,
15173
+ flex: colDef.flex ?? null
15174
+ };
15175
+ }).filter((col) => col !== null);
15212
15176
  };
15213
15177
  var extractDefaultView = (gridApi, receivedConfig) => {
15214
15178
  const columnDefs = gridApi.getColumnDefs() ?? [];
@@ -15235,7 +15199,7 @@ var useNormalizedDefaultViews = (defaultViews, gridApi) => {
15235
15199
  };
15236
15200
 
15237
15201
  // src/components/adapters/smart-grid/useSmartGridConfig.ts
15238
- import { useState as useState5, useEffect as useEffect5, useRef as useRef4 } from "react";
15202
+ import { useState as useState5, useEffect as useEffect4 } from "react";
15239
15203
  var GRID_STATE_EVENTS = [
15240
15204
  "sortChanged",
15241
15205
  "filterOpened",
@@ -15254,14 +15218,10 @@ var useSmartGridConfig = (gridApi) => {
15254
15218
  const [config, setConfig] = useState5(
15255
15219
  () => getSmartGridConfig(gridApi)
15256
15220
  );
15257
- const eventListenersDisabledRef = useRef4(false);
15258
- useEffect5(() => {
15221
+ useEffect4(() => {
15259
15222
  if (!gridApi)
15260
15223
  return;
15261
15224
  const updateConfig = () => {
15262
- if (eventListenersDisabledRef.current) {
15263
- return;
15264
- }
15265
15225
  setConfig(getSmartGridConfig(gridApi));
15266
15226
  };
15267
15227
  GRID_STATE_EVENTS.forEach((event) => {
@@ -15273,24 +15233,13 @@ var useSmartGridConfig = (gridApi) => {
15273
15233
  });
15274
15234
  };
15275
15235
  }, [gridApi]);
15276
- const disableEventListeners = () => {
15277
- eventListenersDisabledRef.current = true;
15278
- };
15279
- const enableEventListeners = () => {
15280
- eventListenersDisabledRef.current = false;
15281
- };
15282
- return { config, setConfig, disableEventListeners, enableEventListeners };
15236
+ return { config, setConfig };
15283
15237
  };
15284
15238
 
15285
15239
  // src/components/adapters/smart-grid/SmartGridSavedViews.tsx
15286
15240
  var SmartGridSavedViews = (props) => {
15287
15241
  const { gridApi, userId, projectId, companyId } = props;
15288
- const {
15289
- config: tableConfig,
15290
- setConfig: setTableConfig,
15291
- disableEventListeners,
15292
- enableEventListeners
15293
- } = useSmartGridConfig(gridApi);
15242
+ const { config: tableConfig, setConfig: setTableConfig } = useSmartGridConfig(gridApi);
15294
15243
  const presetViews = useNormalizedDefaultViews(props.defaultViews, gridApi);
15295
15244
  const defaultView = presetViews.find((view) => view.id === "default") ?? presetViews[0];
15296
15245
  const onSelect = useCallback4(
@@ -15298,29 +15247,20 @@ var SmartGridSavedViews = (props) => {
15298
15247
  if (!gridApi)
15299
15248
  return item;
15300
15249
  const isPresetView = item.view_level === "default";
15301
- const newConfig = item.table_config;
15302
- const transformedConfig = props.transformSettings?.(newConfig) ?? newConfig;
15303
- disableEventListeners();
15304
15250
  if (isPresetView) {
15305
15251
  updateTableConfig(item, gridApi, "smart-grid");
15306
- setTableConfig(transformedConfig);
15307
- setTimeout(() => {
15308
- enableEventListeners();
15309
- }, 0);
15252
+ setTableConfig(item.table_config);
15310
15253
  return item;
15311
15254
  }
15312
15255
  const updatedView = {
15313
15256
  ...item,
15314
15257
  table_config: customAndConfigSync(
15315
- transformedConfig,
15258
+ item.table_config,
15316
15259
  tableConfig
15317
15260
  )
15318
15261
  };
15319
15262
  updateTableConfig(updatedView, gridApi, "smart-grid");
15320
15263
  setTableConfig(updatedView.table_config);
15321
- setTimeout(() => {
15322
- enableEventListeners();
15323
- }, 0);
15324
15264
  return updatedView;
15325
15265
  },
15326
15266
  [gridApi, tableConfig, setTableConfig]
@@ -15337,8 +15277,7 @@ var SmartGridSavedViews = (props) => {
15337
15277
  defaultView,
15338
15278
  presetViews,
15339
15279
  tableName: props.tableName,
15340
- tableConfig,
15341
- backend: props.backend
15280
+ tableConfig
15342
15281
  }
15343
15282
  );
15344
15283
  };