datastake-daf 0.6.825 → 0.6.827

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.
Files changed (24) hide show
  1. package/dist/components/index.js +1188 -1112
  2. package/dist/pages/index.js +111 -79
  3. package/dist/services/index.js +1 -2
  4. package/dist/style/datastake/mapbox-gl.css +330 -0
  5. package/dist/utils/index.js +1 -1
  6. package/package.json +1 -1
  7. package/src/@daf/core/components/Screens/Admin/AdminTables/DocumentsTable/index.jsx +3 -13
  8. package/src/@daf/core/components/Screens/Admin/AdminTables/EventsTable/column.js +1 -1
  9. package/src/@daf/core/components/Screens/Admin/AdminTables/EventsTable/index.jsx +1 -7
  10. package/src/@daf/core/components/Screens/Admin/AdminTables/LocationTable/index.jsx +1 -7
  11. package/src/@daf/core/components/Screens/Admin/AdminTables/SubjectsTable/index.jsx +1 -7
  12. package/src/@daf/core/components/Screens/Admin/AdminTables/hook.js +16 -7
  13. package/src/@daf/pages/Events/Testimonials/config.js +1 -1
  14. package/src/@daf/pages/Locations/ConflictAreas/config.js +1 -1
  15. package/src/@daf/pages/Stakeholders/ArmedGroups/config.js +1 -1
  16. package/src/@daf/pages/Summary/Activities/PlantingCycle/components/CommunityParticipation/JobsTimeline/index.jsx +32 -9
  17. package/src/@daf/pages/Summary/Activities/PlantingCycle/components/CycleIndicators/HealthAndSafety/helper.js +48 -43
  18. package/src/@daf/pages/Summary/Activities/PlantingCycle/components/CycleIndicators/HealthAndSafety/index.jsx +17 -5
  19. package/src/@daf/pages/Summary/Activities/PlantingCycle/components/CycleOutcomes/PlantingActivitiesTimeline.jsx +12 -5
  20. package/src/@daf/pages/Template/components/LinkingTemplate/config.js +5 -0
  21. package/src/@daf/pages/View/hooks/useViewPermissions.js +25 -3
  22. package/src/@daf/pages/View/index.jsx +3 -6
  23. package/src/@daf/services/AdminService.js +1 -2
  24. package/src/constants/locales/sp/translation.js +1 -1
@@ -42258,7 +42258,7 @@ const getFilterOptions$a = (options, t) => {
42258
42258
  const formConfig$8 = {
42259
42259
  namespace: 'armed-groups',
42260
42260
  view: ['scoping', 'new'],
42261
- scope: 'global',
42261
+ scope: 'createArmedGroup',
42262
42262
  formType: 'armed-group'
42263
42263
  };
42264
42264
  const viewConfig$8 = {
@@ -44012,7 +44012,7 @@ const getFilterOptions$6 = (options, t) => {
44012
44012
  const formConfig$4 = {
44013
44013
  namespace: 'testimonials',
44014
44014
  view: 'testimonials',
44015
- scope: 'create',
44015
+ scope: 'createTestimonial',
44016
44016
  formType: 'testimonial'
44017
44017
  };
44018
44018
  const viewConfig$4 = {
@@ -44979,7 +44979,7 @@ const getFilterOptions$3 = (options, t) => {
44979
44979
  const formConfig$1 = {
44980
44980
  namespace: 'conflict-areas',
44981
44981
  view: ['scoping', 'new'],
44982
- scope: 'conflictAreaCreate',
44982
+ scope: 'createConflictArea',
44983
44983
  formType: 'conflict-area'
44984
44984
  };
44985
44985
  const viewConfig$1 = {
@@ -52898,9 +52898,8 @@ class AdminService extends BaseService {
52898
52898
  subject,
52899
52899
  id
52900
52900
  }) {
52901
- const type = subject === 'location' ? 'location' : 'stakeholder';
52902
52901
  return this.apiDelete({
52903
- url: `/management/subject/${type}/${id}`
52902
+ url: `/management/subject/${subject}/${id}`
52904
52903
  });
52905
52904
  }
52906
52905
  async getUserGrowth(activeFilter) {
@@ -55414,14 +55413,19 @@ const PlantingActivitiesTimeline = ({
55414
55413
  const dataToProcess = !activitiesTimelineChart || !Array.isArray(activitiesTimelineChart) || activitiesTimelineChart.length === 0 ? [] : activitiesTimelineChart;
55415
55414
 
55416
55415
  // Process data without cumulative calculation (for activities timeline)
55417
- return processChartDateData({
55416
+ const processedData = processChartDateData({
55418
55417
  mainData: dataToProcess,
55419
55418
  isCumulative: false,
55420
55419
  valueField: 'count'
55421
55420
  });
55422
- }, [activitiesTimelineChart, processChartDateData]);
55423
55421
 
55424
- // Calculate max value for Y-axis (default to 100 if all values are 0 or very small)
55422
+ // Remove trailing periods with 0 jobs (optional: remove all zero if you prefer)
55423
+ let lastNonZeroIndex = processedData.length - 1;
55424
+ while (lastNonZeroIndex >= 0 && (processedData[lastNonZeroIndex].jobs || 0) === 0) {
55425
+ lastNonZeroIndex--;
55426
+ }
55427
+ return processedData.slice(0, lastNonZeroIndex + 1);
55428
+ }, [activitiesTimelineChart, processChartDateData]);
55425
55429
  const maxActivitiesYValue = React.useMemo(() => {
55426
55430
  if (!activitiesTimelineData || activitiesTimelineData.length === 0) {
55427
55431
  return 100;
@@ -55766,6 +55770,29 @@ const CyclePartners = ({
55766
55770
  });
55767
55771
  };
55768
55772
 
55773
+ // Custom tooltip labels per field/value
55774
+ const FIELD_TOOLTIP_LABELS = {
55775
+ aidKitAccessible: {
55776
+ compliant: "Available",
55777
+ notCompliant: "Not available",
55778
+ empty: "No data"
55779
+ },
55780
+ hsTrainingConfirmation: {
55781
+ compliant: "Training delivered",
55782
+ notCompliant: "No training",
55783
+ empty: "No data"
55784
+ },
55785
+ duosFormed: {
55786
+ compliant: "Duos formed",
55787
+ notCompliant: "Not implemented",
55788
+ empty: "No data"
55789
+ },
55790
+ presenceOfChildren: {
55791
+ compliant: "None reported",
55792
+ notCompliant: "Children present",
55793
+ empty: "No data"
55794
+ }
55795
+ };
55769
55796
  const HEALTH_SAFETY_COLORS = {
55770
55797
  compliant: '#016C6E',
55771
55798
  notCompliant: '#F97066',
@@ -55777,12 +55804,6 @@ const getIndicatorType$1 = value => {
55777
55804
  if (value === null || value === undefined) return "empty";
55778
55805
  return "empty";
55779
55806
  };
55780
-
55781
- /**
55782
- * Gets health and safety distribution data from activity data
55783
- * @param {Object} activityData - Activity data object
55784
- * @returns {Object} Distribution object with compliant, notCompliant, and empty counts
55785
- */
55786
55807
  const getHealthAndSafetyDistributionData = activityData => {
55787
55808
  // Define health and safety indicator fields
55788
55809
  const indicators = [{
@@ -55818,53 +55839,26 @@ const getHealthAndSafetyDistributionData = activityData => {
55818
55839
  });
55819
55840
  return distribution;
55820
55841
  };
55821
-
55822
- /**
55823
- * Checks if the health and safety distribution data is empty
55824
- * @param {Object} healthAndSafetyDistributionData - Distribution object
55825
- * @returns {boolean} True if all values are 0 or empty
55826
- */
55827
55842
  const isHealthAndSafetyDistributionEmpty = healthAndSafetyDistributionData => {
55828
55843
  return Object.values(healthAndSafetyDistributionData).every(val => !val || val === 0);
55829
55844
  };
55830
-
55831
- /**
55832
- * Calculates pie chart data from health and safety distribution
55833
- * @param {Object} healthAndSafetyDistributionData - Distribution object
55834
- * @param {Function} t - Translation function
55835
- * @returns {Array} Array of pie chart data points with value, percent, color, label, and key
55836
- */
55837
- const calculateHealthAndSafetyPieData = (healthAndSafetyDistributionData, t) => {
55838
- const total = Object.values(healthAndSafetyDistributionData).reduce((all, val) => all + (val || 0), 0);
55845
+ const calculateHealthAndSafetyPieData = (data, t, selectedField) => {
55846
+ const total = Object.values(data).reduce((a, v) => a + (v || 0), 0);
55839
55847
  const labels = {
55840
55848
  compliant: t("Available"),
55841
55849
  notCompliant: t("Not available"),
55842
55850
  empty: t("Not answered")
55843
55851
  };
55844
- return Object.keys(healthAndSafetyDistributionData).map(key => {
55845
- const color = HEALTH_SAFETY_COLORS[key] || '#D9D9D9';
55846
- return {
55847
- value: healthAndSafetyDistributionData[key] || 0,
55848
- percent: total > 0 ? (healthAndSafetyDistributionData[key] || 0) / total : 0,
55849
- color: color,
55850
- label: labels[key] || key,
55851
- key: key
55852
- };
55853
- });
55852
+ return Object.keys(data).map(key => ({
55853
+ value: data[key] || 0,
55854
+ percent: total > 0 ? (data[key] || 0) / total : 0,
55855
+ color: HEALTH_SAFETY_COLORS[key] || '#D9D9D9',
55856
+ label: labels[key] || key,
55857
+ key,
55858
+ keyOfField: selectedField // <-- ADD THIS
55859
+ }));
55854
55860
  };
55855
-
55856
- /**
55857
- * Generates tooltip content for health and safety pie chart
55858
- * Shows all statuses with their percentages
55859
- * @param {Object} item - The pie chart item being hovered (not used, but kept for compatibility)
55860
- * @param {boolean} isEmpty - Whether the distribution is empty
55861
- * @param {Object} healthAndSafetyDistributionData - Distribution object
55862
- * @param {Function} t - Translation function
55863
- * @param {Function} renderTooltipJsx - Function to render tooltip JSX
55864
- * @param {string} tooltipTitle - Title to display in the tooltip (defaults to "Health and Safety")
55865
- * @returns {JSX.Element|null} Tooltip content or null
55866
- */
55867
- const getHealthAndSafetyTooltipChildren = (item, isEmpty, healthAndSafetyDistributionData, t, renderTooltipJsx, tooltipTitle = "Health and Safety") => {
55861
+ const getHealthAndSafetyTooltipChildren = (item, isEmpty, healthAndSafetyDistributionData, t, renderTooltipJsx, tooltipTitle = "Health and Safety", selectedField) => {
55868
55862
  // If empty or no data, return null to display nothing
55869
55863
  if (isEmpty || !Object.keys(healthAndSafetyDistributionData).length) {
55870
55864
  return null;
@@ -55877,10 +55871,10 @@ const getHealthAndSafetyTooltipChildren = (item, isEmpty, healthAndSafetyDistrib
55877
55871
  if (total === 0) {
55878
55872
  return null;
55879
55873
  }
55880
- const labels = {
55874
+ const labels = FIELD_TOOLTIP_LABELS[item?.keyOfField] || {
55881
55875
  compliant: t("Available"),
55882
55876
  notCompliant: t("Not available"),
55883
- empty: t("Not answered")
55877
+ empty: t("No data")
55884
55878
  };
55885
55879
 
55886
55880
  // Filter items with values > 0
@@ -55963,7 +55957,6 @@ const HealthAndSafety = ({
55963
55957
  getData: customGetData
55964
55958
  });
55965
55959
 
55966
- // Process the fetched pie chart data
55967
55960
  // The API returns data in format: [{count: 1, [field]: "null"}, {count: 1, [field]: "no"}, {count: 1, [field]: "yes"}]
55968
55961
  const healthAndSafetyDistributionData = React.useMemo(() => {
55969
55962
  if (!pieChartData) return {
@@ -56004,7 +55997,7 @@ const HealthAndSafety = ({
56004
55997
  return getHealthAndSafetyDistributionData(pieChartData);
56005
55998
  }, [pieChartData, selectedField]);
56006
55999
  const isEmpty = React.useMemo(() => isHealthAndSafetyDistributionEmpty(healthAndSafetyDistributionData), [healthAndSafetyDistributionData]);
56007
- const pieData = React.useMemo(() => calculateHealthAndSafetyPieData(healthAndSafetyDistributionData, t), [healthAndSafetyDistributionData, t]);
56000
+ const pieData = React.useMemo(() => calculateHealthAndSafetyPieData(healthAndSafetyDistributionData, t, selectedField), [healthAndSafetyDistributionData, t, selectedField]);
56008
56001
 
56009
56002
  // Get the label for the selected field to use as tooltip title
56010
56003
  const selectedFieldLabel = React.useMemo(() => {
@@ -56018,9 +56011,10 @@ const HealthAndSafety = ({
56018
56011
  return /*#__PURE__*/jsxRuntime.jsx(Widget, {
56019
56012
  loading: loading || pieChartLoading,
56020
56013
  title: /*#__PURE__*/jsxRuntime.jsx("div", {
56021
- children: t("Health and Safety")
56014
+ children: t("Operational Health & Safety")
56022
56015
  }),
56023
- className: "with-border-header h-w-btn-header ",
56016
+ className: "with-border-header h-w-btn-header",
56017
+ description: t("Across all activities in this cycle."),
56024
56018
  addedHeader: /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
56025
56019
  children: [/*#__PURE__*/jsxRuntime.jsx("div", {
56026
56020
  className: "flex-1"
@@ -56339,17 +56333,41 @@ const JobsTimeline = ({
56339
56333
  defaultFilter: 'monthly'
56340
56334
  });
56341
56335
  const jobsData = Array.isArray(dayJobsTimeline) ? dayJobsTimeline : dayJobsTimeline?.jobsTimeline || dayJobsTimeline?.jobs || dayJobsTimeline?.timeline || [];
56336
+
56337
+ // const jobsTimelineData = useMemo(() => {
56338
+ // // Always process data, even if empty, to generate default date range for x-axis
56339
+ // const dataToProcess = (!jobsData || !Array.isArray(jobsData) || jobsData.length === 0)
56340
+ // ? []
56341
+ // : jobsData;
56342
+
56343
+ // // Process data without cumulative calculation (for jobs timeline)
56344
+ // // Try to find value in total, count, jobs, or value fields
56345
+ // return processChartDateData({
56346
+ // mainData: dataToProcess,
56347
+ // isCumulative: false,
56348
+ // valueField: 'total', // Will fallback to count/jobs/value if total doesn't exist
56349
+ // });
56350
+ // }, [jobsData, processChartDateData]);
56351
+
56342
56352
  const jobsTimelineData = React.useMemo(() => {
56343
- // Always process data, even if empty, to generate default date range for x-axis
56353
+ // Prepare data first
56344
56354
  const dataToProcess = !jobsData || !Array.isArray(jobsData) || jobsData.length === 0 ? [] : jobsData;
56345
56355
 
56346
- // Process data without cumulative calculation (for jobs timeline)
56347
- // Try to find value in total, count, jobs, or value fields
56348
- return processChartDateData({
56356
+ // Process data without cumulative calculation
56357
+ const processedData = processChartDateData({
56349
56358
  mainData: dataToProcess,
56350
56359
  isCumulative: false,
56351
- valueField: 'total' // Will fallback to count/jobs/value if total doesn't exist
56360
+ valueField: 'total' // fallback handled inside processChartDateData
56352
56361
  });
56362
+
56363
+ // Find last index with jobs > 0
56364
+ let lastNonZeroIndex = processedData.length - 1;
56365
+ while (lastNonZeroIndex >= 0 && (processedData[lastNonZeroIndex].jobs || 0) === 0) {
56366
+ lastNonZeroIndex--;
56367
+ }
56368
+
56369
+ // Slice up to last period with data
56370
+ return processedData.slice(0, lastNonZeroIndex + 1);
56353
56371
  }, [jobsData, processChartDateData]);
56354
56372
  const maxYValue = React.useMemo(() => {
56355
56373
  if (!jobsTimelineData || jobsTimelineData.length === 0) {
@@ -61316,6 +61334,22 @@ const usePrepareForm$1 = ({
61316
61334
  };
61317
61335
  };
61318
61336
 
61337
+ const evaluateRule = (rule, data) => {
61338
+ if (typeof rule === "boolean") return rule;
61339
+ if (typeof rule === "function") return rule();
61340
+ if (typeof rule === "string") {
61341
+ const parts = rule.split(" ");
61342
+
61343
+ // Expecting: "<field> <is|not> <value>"
61344
+ if (parts.length === 3) {
61345
+ const [field, condition, value] = parts;
61346
+ if (condition === "is") return data?.[field] === value;
61347
+ if (condition === "not") return data?.[field] !== value;
61348
+ }
61349
+ }
61350
+ console.warn("Invalid rule:", rule);
61351
+ return false;
61352
+ };
61319
61353
  const useViewPermissions = ({
61320
61354
  data,
61321
61355
  id,
@@ -61333,9 +61367,6 @@ const useViewPermissions = ({
61333
61367
  viewConfig
61334
61368
  }) => {
61335
61369
  const baseNamespaceKeys = Object.keys(namespaceConfig || {});
61336
- console.log({
61337
- namespaceConfig
61338
- });
61339
61370
  const baseSupportedNamespaces = baseNamespaceKeys?.reduce((acc, key) => {
61340
61371
  acc[key] = () => true;
61341
61372
  return acc;
@@ -61357,7 +61388,8 @@ const useViewPermissions = ({
61357
61388
  ...baseCanEditAction,
61358
61389
  ...namespaceOverrides.canEdit
61359
61390
  };
61360
- return canEditAction[namespace] ? canEditAction[namespace]() : false;
61391
+ const rule = canEditAction[namespace] ? canEditAction[namespace]() : false;
61392
+ return evaluateRule(rule, data);
61361
61393
  }, [namespace, data, user]);
61362
61394
  const canDelete = React.useMemo(() => {
61363
61395
  baseNamespaceKeys.reduce((acc, key) => {
@@ -61367,7 +61399,8 @@ const useViewPermissions = ({
61367
61399
  const canDeleteAction = {
61368
61400
  ...namespaceOverrides.canDelete
61369
61401
  };
61370
- return canDeleteAction[namespace] ? canDeleteAction[namespace]() : false;
61402
+ const rule = canDeleteAction[namespace] ? canDeleteAction[namespace]() : false;
61403
+ return evaluateRule(rule, data);
61371
61404
  }, [namespace, data, user, namespaceOverrides]);
61372
61405
  React.useEffect(() => {
61373
61406
  if (data) {
@@ -61621,7 +61654,12 @@ const namespaceMap = {
61621
61654
  "production-sites": "location",
61622
61655
  operators: "stakeholder",
61623
61656
  workers: "stakeholder",
61624
- activities: "event"
61657
+ activities: "event",
61658
+ "conflict-areas": "location",
61659
+ "armed-groups": "stakeholder",
61660
+ scl: "location",
61661
+ testimonials: 'event',
61662
+ 'corrective-actions': 'event'
61625
61663
  };
61626
61664
 
61627
61665
  const getColumns = ({
@@ -62008,15 +62046,9 @@ const View = ({
62008
62046
  options,
62009
62047
  getSubjectsDetails,
62010
62048
  namespaceOverrides
62011
- // ADD CALLBACK TO GET THE CURRENT NAMESPACE CONFIG
62012
62049
  }) => {
62013
62050
  const getNamespaceConfig = namespace => namespaceConfiguration?.[namespace] || {};
62014
62051
  const [openRecordsModal, setOpenRecordsModal] = React.useState(false);
62015
- console.log({
62016
- partners
62017
- });
62018
-
62019
- // HANDLES THE URL PARAMS FOR THE VIEW PAGE
62020
62052
  const {
62021
62053
  namespace,
62022
62054
  id,
@@ -62041,8 +62073,6 @@ const View = ({
62041
62073
  getRedirectLink
62042
62074
  });
62043
62075
  const namespaceConfig = React.useMemo(() => getNamespaceConfig(namespace), [namespace]);
62044
-
62045
- // PREPARES THE FORM FOR THE VIEW PAGE
62046
62076
  const {
62047
62077
  form,
62048
62078
  data,
@@ -62099,7 +62129,9 @@ const View = ({
62099
62129
  });
62100
62130
  const subjects = {
62101
62131
  "management-location": "location",
62102
- "management-stakeholder": "stakeholder"
62132
+ "management-stakeholder": "stakeholder",
62133
+ "management-event": "event",
62134
+ "management-incident": "incident"
62103
62135
  };
62104
62136
  const handleDeleteSubject = React.useCallback(async () => {
62105
62137
  try {
@@ -62108,7 +62140,7 @@ const View = ({
62108
62140
  id: id
62109
62141
  });
62110
62142
  antd.message.success(t("Subject deleted successfully"));
62111
- push(getRedirectLink(`/app/management/subject/${subjects[namespace]}`));
62143
+ // push(getRedirectLink(`/app/management/subject/${subjects[namespace]}`));
62112
62144
  } catch (error) {
62113
62145
  handleError(error);
62114
62146
  antd.message.error(t("Failed to delete subject"));
@@ -1016,9 +1016,8 @@ class AdminService extends BaseService {
1016
1016
  subject,
1017
1017
  id
1018
1018
  }) {
1019
- const type = subject === 'location' ? 'location' : 'stakeholder';
1020
1019
  return this.apiDelete({
1021
- url: `/management/subject/${type}/${id}`
1020
+ url: `/management/subject/${subject}/${id}`
1022
1021
  });
1023
1022
  }
1024
1023
  async getUserGrowth(activeFilter) {
@@ -0,0 +1,330 @@
1
+ /* Isolated Mapbox GL CSS - Scoped to prevent Leaflet conflicts */
2
+
3
+ /* Mapbox GL Core Styles - Scoped with .mapbox-gl-scope */
4
+ .mapbox-gl-scope .mapboxgl-map {
5
+ font: 12px/20px Helvetica Neue, Arial, Helvetica, sans-serif;
6
+ overflow: hidden;
7
+ position: relative;
8
+ -webkit-tap-highlight-color: rgb(0 0 0/0);
9
+ }
10
+
11
+ .mapbox-gl-scope .mapboxgl-canvas {
12
+ left: 0;
13
+ position: absolute;
14
+ top: 0;
15
+ }
16
+
17
+ .mapbox-gl-scope .mapboxgl-map:-webkit-full-screen {
18
+ height: 100%;
19
+ width: 100%;
20
+ }
21
+
22
+ .mapbox-gl-scope .mapboxgl-canary {
23
+ background-color: salmon;
24
+ }
25
+
26
+ .mapbox-gl-scope .mapboxgl-canvas-container.mapboxgl-interactive,
27
+ .mapbox-gl-scope .mapboxgl-ctrl-group button.mapboxgl-ctrl-compass {
28
+ cursor: grab;
29
+ -webkit-user-select: none;
30
+ user-select: none;
31
+ }
32
+
33
+ .mapbox-gl-scope .mapboxgl-canvas-container.mapboxgl-interactive.mapboxgl-track-pointer {
34
+ cursor: pointer;
35
+ }
36
+
37
+ .mapbox-gl-scope .mapboxgl-canvas-container.mapboxgl-interactive:active,
38
+ .mapbox-gl-scope .mapboxgl-ctrl-group button.mapboxgl-ctrl-compass:active {
39
+ cursor: grabbing;
40
+ }
41
+
42
+ .mapbox-gl-scope .mapboxgl-canvas-container.mapboxgl-touch-zoom-rotate,
43
+ .mapbox-gl-scope .mapboxgl-canvas-container.mapboxgl-touch-zoom-rotate .mapboxgl-canvas {
44
+ touch-action: pan-x pan-y;
45
+ }
46
+
47
+ .mapbox-gl-scope .mapboxgl-canvas-container.mapboxgl-touch-drag-pan,
48
+ .mapbox-gl-scope .mapboxgl-canvas-container.mapboxgl-touch-drag-pan .mapboxgl-canvas {
49
+ touch-action: pinch-zoom;
50
+ }
51
+
52
+ .mapbox-gl-scope .mapboxgl-canvas-container.mapboxgl-touch-zoom-rotate.mapboxgl-touch-drag-pan,
53
+ .mapbox-gl-scope .mapboxgl-canvas-container.mapboxgl-touch-zoom-rotate.mapboxgl-touch-drag-pan .mapboxgl-canvas {
54
+ touch-action: none;
55
+ }
56
+
57
+ /* Control positioning */
58
+ .mapbox-gl-scope .mapboxgl-ctrl-bottom,
59
+ .mapbox-gl-scope .mapboxgl-ctrl-bottom-left,
60
+ .mapbox-gl-scope .mapboxgl-ctrl-bottom-right,
61
+ .mapbox-gl-scope .mapboxgl-ctrl-left,
62
+ .mapbox-gl-scope .mapboxgl-ctrl-right,
63
+ .mapbox-gl-scope .mapboxgl-ctrl-top,
64
+ .mapbox-gl-scope .mapboxgl-ctrl-top-left,
65
+ .mapbox-gl-scope .mapboxgl-ctrl-top-right {
66
+ pointer-events: none;
67
+ position: absolute;
68
+ z-index: 2;
69
+ }
70
+
71
+ .mapbox-gl-scope .mapboxgl-ctrl-top-left {
72
+ left: 0;
73
+ top: 0;
74
+ }
75
+
76
+ .mapbox-gl-scope .mapboxgl-ctrl-top {
77
+ left: 50%;
78
+ top: 0;
79
+ transform: translateX(-50%);
80
+ }
81
+
82
+ .mapbox-gl-scope .mapboxgl-ctrl-top-right {
83
+ right: 0;
84
+ top: 0;
85
+ }
86
+
87
+ .mapbox-gl-scope .mapboxgl-ctrl-right {
88
+ right: 0;
89
+ top: 50%;
90
+ transform: translateY(-50%);
91
+ }
92
+
93
+ .mapbox-gl-scope .mapboxgl-ctrl-bottom-right {
94
+ bottom: 0;
95
+ right: 0;
96
+ }
97
+
98
+ .mapbox-gl-scope .mapboxgl-ctrl-bottom {
99
+ bottom: 0;
100
+ left: 50%;
101
+ transform: translateX(-50%);
102
+ }
103
+
104
+ .mapbox-gl-scope .mapboxgl-ctrl-bottom-left {
105
+ bottom: 0;
106
+ left: 0;
107
+ }
108
+
109
+ .mapbox-gl-scope .mapboxgl-ctrl-left {
110
+ left: 0;
111
+ top: 50%;
112
+ transform: translateY(-50%);
113
+ }
114
+
115
+ .mapbox-gl-scope .mapboxgl-ctrl {
116
+ clear: both;
117
+ pointer-events: auto;
118
+ transform: translate(0);
119
+ }
120
+
121
+ .mapbox-gl-scope .mapboxgl-ctrl-top-left .mapboxgl-ctrl {
122
+ float: left;
123
+ margin: 10px 0 0 10px;
124
+ }
125
+
126
+ .mapbox-gl-scope .mapboxgl-ctrl-top .mapboxgl-ctrl {
127
+ float: left;
128
+ margin: 10px 0;
129
+ }
130
+
131
+ .mapbox-gl-scope .mapboxgl-ctrl-top-right .mapboxgl-ctrl {
132
+ float: right;
133
+ margin: 10px 10px 0 0;
134
+ }
135
+
136
+ .mapbox-gl-scope .mapboxgl-ctrl-bottom-right .mapboxgl-ctrl,
137
+ .mapbox-gl-scope .mapboxgl-ctrl-right .mapboxgl-ctrl {
138
+ float: right;
139
+ margin: 0 10px 10px 0;
140
+ }
141
+
142
+ .mapbox-gl-scope .mapboxgl-ctrl-bottom .mapboxgl-ctrl {
143
+ float: left;
144
+ margin: 10px 0;
145
+ }
146
+
147
+ .mapbox-gl-scope .mapboxgl-ctrl-bottom-left .mapboxgl-ctrl,
148
+ .mapbox-gl-scope .mapboxgl-ctrl-left .mapboxgl-ctrl {
149
+ float: left;
150
+ margin: 0 0 10px 10px;
151
+ }
152
+
153
+ /* Control group styling */
154
+ .mapbox-gl-scope .mapboxgl-ctrl-group {
155
+ background: #fff;
156
+ border-radius: 4px;
157
+ }
158
+
159
+ .mapbox-gl-scope .mapboxgl-ctrl-group:not(:empty) {
160
+ box-shadow: 0 0 0 2px #0000001a;
161
+ }
162
+
163
+ .mapbox-gl-scope .mapboxgl-ctrl-group button {
164
+ background-color: initial;
165
+ border: 0;
166
+ box-sizing: border-box;
167
+ cursor: pointer;
168
+ display: block;
169
+ height: 29px;
170
+ outline: none;
171
+ overflow: hidden;
172
+ padding: 0;
173
+ width: 29px;
174
+ }
175
+
176
+ .mapbox-gl-scope .mapboxgl-ctrl-group button+button {
177
+ border-top: 1px solid #ddd;
178
+ }
179
+
180
+ .mapbox-gl-scope .mapboxgl-ctrl button .mapboxgl-ctrl-icon {
181
+ background-position: 50%;
182
+ background-repeat: no-repeat;
183
+ display: block;
184
+ height: 100%;
185
+ width: 100%;
186
+ }
187
+
188
+ .mapbox-gl-scope .mapboxgl-ctrl-attrib-button:focus,
189
+ .mapbox-gl-scope .mapboxgl-ctrl-group button:focus {
190
+ box-shadow: 0 0 2px 2px #0096ff;
191
+ }
192
+
193
+ .mapbox-gl-scope .mapboxgl-ctrl button:disabled {
194
+ cursor: not-allowed;
195
+ }
196
+
197
+ .mapbox-gl-scope .mapboxgl-ctrl button:disabled .mapboxgl-ctrl-icon {
198
+ opacity: .25;
199
+ }
200
+
201
+ .mapbox-gl-scope .mapboxgl-ctrl-group button:first-child {
202
+ border-radius: 4px 4px 0 0;
203
+ }
204
+
205
+ .mapbox-gl-scope .mapboxgl-ctrl-group button:last-child {
206
+ border-radius: 0 0 4px 4px;
207
+ }
208
+
209
+ .mapbox-gl-scope .mapboxgl-ctrl-group button:only-child {
210
+ border-radius: inherit;
211
+ }
212
+
213
+ .mapbox-gl-scope .mapboxgl-ctrl button:not(:disabled):hover {
214
+ background-color: #0000000d;
215
+ }
216
+
217
+ /* Marker styles */
218
+ .mapbox-gl-scope .mapboxgl-marker {
219
+ position: absolute;
220
+ z-index: 1;
221
+ }
222
+
223
+ .mapbox-gl-scope .mapboxgl-marker svg {
224
+ display: block;
225
+ }
226
+
227
+ /* Popup styles */
228
+ .mapbox-gl-scope .mapboxgl-popup {
229
+ position: absolute;
230
+ text-align: center;
231
+ margin-bottom: 20px;
232
+ }
233
+
234
+ .mapbox-gl-scope .mapboxgl-popup-content-wrapper {
235
+ padding: 1px;
236
+ text-align: left;
237
+ border-radius: 12px;
238
+ }
239
+
240
+ .mapbox-gl-scope .mapboxgl-popup-content {
241
+ margin: 13px 24px 13px 20px;
242
+ line-height: 1.3;
243
+ font-size: 13px;
244
+ min-height: 1px;
245
+ }
246
+
247
+ .mapbox-gl-scope .mapboxgl-popup-content p {
248
+ margin: 17px 0;
249
+ }
250
+
251
+ .mapbox-gl-scope .mapboxgl-popup-tip-container {
252
+ width: 40px;
253
+ height: 20px;
254
+ position: absolute;
255
+ left: 50%;
256
+ margin-top: -1px;
257
+ margin-left: -20px;
258
+ overflow: hidden;
259
+ pointer-events: none;
260
+ }
261
+
262
+ .mapbox-gl-scope .mapboxgl-popup-tip {
263
+ width: 17px;
264
+ height: 17px;
265
+ padding: 1px;
266
+ margin: -10px auto 0;
267
+ pointer-events: auto;
268
+ -webkit-transform: rotate(45deg);
269
+ -moz-transform: rotate(45deg);
270
+ -ms-transform: rotate(45deg);
271
+ transform: rotate(45deg);
272
+ }
273
+
274
+ .mapbox-gl-scope .mapboxgl-popup-content-wrapper,
275
+ .mapbox-gl-scope .mapboxgl-popup-tip {
276
+ background: white;
277
+ color: #333;
278
+ box-shadow: 0 3px 14px rgba(0, 0, 0, 0.4);
279
+ }
280
+
281
+ .mapbox-gl-scope .mapboxgl-popup-close-button {
282
+ position: absolute;
283
+ top: 0;
284
+ right: 0;
285
+ border: none;
286
+ text-align: center;
287
+ width: 24px;
288
+ height: 24px;
289
+ font: 16px/24px Tahoma, Verdana, sans-serif;
290
+ color: #757575;
291
+ text-decoration: none;
292
+ background: transparent;
293
+ }
294
+
295
+ .mapbox-gl-scope .mapboxgl-popup-close-button:hover,
296
+ .mapbox-gl-scope .mapboxgl-popup-close-button:focus {
297
+ color: #585858;
298
+ }
299
+
300
+ /* Attribution */
301
+ .mapbox-gl-scope .mapboxgl-ctrl-attribution {
302
+ background: #fff;
303
+ background: rgba(255, 255, 255, 0.8);
304
+ margin: 0;
305
+ }
306
+
307
+ .mapbox-gl-scope .mapboxgl-ctrl-attribution,
308
+ .mapbox-gl-scope .mapboxgl-ctrl-scale-line {
309
+ padding: 0 5px;
310
+ color: #333;
311
+ line-height: 1.4;
312
+ }
313
+
314
+ .mapbox-gl-scope .mapboxgl-ctrl-attribution a {
315
+ text-decoration: none;
316
+ }
317
+
318
+ .mapbox-gl-scope .mapboxgl-ctrl-attribution a:hover,
319
+ .mapbox-gl-scope .mapboxgl-ctrl-attribution a:focus {
320
+ text-decoration: underline;
321
+ }
322
+
323
+ /* Hide attribution by default */
324
+ .mapbox-gl-scope .mapboxgl-ctrl-attribution {
325
+ display: none !important;
326
+ }
327
+
328
+ .mapbox-gl-scope .mapboxgl-ctrl-logo {
329
+ display: none !important;
330
+ }