@corva/create-app 0.115.0 → 0.117.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.
@@ -0,0 +1,339 @@
1
+ # AGENTS.md
2
+
3
+ Corva.AI platform UI app — a React dashboard widget scaffolded by `create-corva-app`.
4
+ Deployed to the Corva platform via `yarn release`.
5
+
6
+ ## Critical Rules
7
+
8
+ These constraints are enforced by the platform. Violating them breaks the build or runtime.
9
+
10
+ 1. **Root export** — `src/index.js` MUST default-export `{ component: App, settings: AppSettings }`. The component may also be a `ParentApp` wrapper (e.g., `{ component: ParentApp, settings: AppSettings }`) that wraps `App` with Context.Providers and prop initialization. This is the platform loader contract.
11
+ 2. **UI components** — Use only `@corva/ui` components. Import from `@corva/ui/componentsV2`; fall back to `@corva/ui/components` only when a V2 version doesn't exist yet. `@material-ui/core` v4 is available as the underlying library.
12
+ 3. **HTTP clients** — Use `corvaDataAPI` / `corvaAPI` from `@corva/ui/clients` for all network requests.
13
+ 4. **Do not rename or delete** `App.tsx`, `AppSettings.tsx`, or `index.js` — they are platform entry points.
14
+
15
+ ## Project Structure
16
+
17
+ ```
18
+ src/
19
+ App.tsx — Main app component (default export required)
20
+ AppSettings.tsx — Settings panel component (default export required)
21
+ index.js — Root export: { component, settings }
22
+ constants.ts — Default settings values
23
+ types.ts — Custom app settings interface
24
+ custom.d.ts — Module declarations for CSS/SVG imports
25
+ App.css — Component styles (CSS modules)
26
+ __tests__/ — Jest test files
27
+ __mocks__/mockData.ts — Mock data for tests
28
+ assets/ — Static assets (SVGs, images)
29
+ config/jest/ — Jest setup (setupTests, transforms)
30
+ config-overrides.js — Webpack 5 customization
31
+ tsconfig.json — TypeScript configuration
32
+ manifest.json — Corva platform app metadata (generated at scaffold time)
33
+ ```
34
+
35
+ ## Key Patterns
36
+
37
+ ### Component Structure
38
+
39
+ - Use `useAppCommons()` from `@corva/ui/effects` to access platform data: `appKey`, `appSettings`, `well`, `rig`, `fracFleet`, `wells`, `currentUser`, `onSettingChange`, `onSettingsChange`, etc.
40
+ - Define custom app settings shape in `src/types.ts` (`CustomAppSettings`).
41
+ - Platform types (Well, Rig, FracFleet, User, etc.) are typed in `@corva/ui` — do NOT duplicate them.
42
+
43
+ ```typescript
44
+ // App component pattern — use useAppCommons() instead of props
45
+ const App = () => {
46
+ const { appKey, well, rig, appSettings } = useAppCommons();
47
+ const { isExampleCheckboxChecked } = appSettings || {};
48
+ // ...
49
+ };
50
+
51
+ // AppSettings component pattern — same hook
52
+ const AppSettings = () => {
53
+ const { appSettings, onSettingChange } = useAppCommons();
54
+ // ...
55
+ };
56
+ ```
57
+
58
+ ### Styling
59
+
60
+ CSS modules for component styles:
61
+
62
+ ```typescript
63
+ import styles from './App.css';
64
+ // Use: <div className={styles.container}>
65
+ ```
66
+
67
+ For custom component styles, use `makeStyles` from MUI v4:
68
+
69
+ ```typescript
70
+ import { makeStyles } from '@material-ui/core/styles';
71
+
72
+ const useStyles = makeStyles(theme => ({
73
+ root: { display: 'flex', gap: theme.spacing(1) },
74
+ }));
75
+
76
+ // Inside component:
77
+ const styles = useStyles();
78
+ return <div className={styles.root}>...</div>;
79
+ ```
80
+
81
+ **`theme.spacing(n)`** — 8px base unit for layout dimensions:
82
+
83
+ ```typescript
84
+ padding: theme.spacing(2) // 16px
85
+ margin: theme.spacing(1, 0) // 8px 0
86
+ borderRadius: theme.spacing(0.5) // 4px
87
+ ```
88
+
89
+ **Color manipulation** — `fade`, `darken`, `lighten` from `@material-ui/core/styles`:
90
+
91
+ ```typescript
92
+ import { fade, darken, lighten } from '@material-ui/core/styles';
93
+
94
+ background: fade(theme.palette.common.white, 0.08) // white at 8% opacity
95
+ color: darken(theme.palette.primary.main, 0.2) // darken by 20%
96
+ ```
97
+
98
+ **Transitions:**
99
+
100
+ ```typescript
101
+ transition: theme.transitions.create('opacity')
102
+ transition: theme.transitions.create(['opacity', 'background-color'], {
103
+ duration: theme.transitions.duration.standard, // 300ms
104
+ })
105
+ ```
106
+
107
+ **Breakpoints:**
108
+
109
+ ```typescript
110
+ [theme.breakpoints.down('sm')]: { padding: theme.spacing(1) } // max-width: 599px
111
+ [theme.breakpoints.up('md')]: { flexDirection: 'row' } // min-width: 960px
112
+ ```
113
+
114
+ **`theme.zIndex`** — stacking constants: `appBar` (1100), `drawer` (1200), `modal` (1300), `tooltip` (1500).
115
+
116
+ **CSS variables** — available in `.css` files:
117
+
118
+ ```css
119
+ color: var(--palette-primary-text-1); /* primary text */
120
+ background: var(--palette-background-b-5); /* card background */
121
+ border-color: var(--palette-primary-text-9); /* borders */
122
+ ```
123
+
124
+ **SCSS functions** — available in `.module.scss` files:
125
+
126
+ ```scss
127
+ padding: spacing(2); // 16px
128
+ color: colorAlpha($color, 0.5); // rgba transparency
129
+ transition: transition(opacity); // standard cubic-bezier
130
+ ```
131
+
132
+ **Direct theme import:**
133
+
134
+ ```typescript
135
+ import { lightTheme, darkTheme } from '@corva/ui/config';
136
+ ```
137
+
138
+ ### State Management (Zustand)
139
+
140
+ The Corva platform can render multiple instances of the same app simultaneously. If a Zustand store is created at module level (singleton), all instances share the same state. To avoid this, always create store instances inside a React Context provider.
141
+
142
+ **Store factory + context** — create a factory function and a context to hold the store instance:
143
+
144
+ ```typescript
145
+ // store/createAppStore.ts
146
+ import { createContext } from 'react';
147
+ import { create } from 'zustand';
148
+
149
+ import { AppStore } from '~/types';
150
+
151
+ export const createAppStore = (initProps?: Partial<SavedSettings>) => {
152
+ return create<AppStore>()((set, get) => ({
153
+ // Compose sub-stores
154
+ ...createSettingsStore(initProps?.settings)(set, get),
155
+ ...createDataStore()(set, get),
156
+ }));
157
+ };
158
+
159
+ export const StoreContext = createContext<ReturnType<typeof createAppStore> | null>(null);
160
+ ```
161
+
162
+ **Provider** — create the store once per app mount and pass it via context:
163
+
164
+ ```typescript
165
+ // StoreProvider.tsx
166
+ import { FC, PropsWithChildren, useState } from 'react';
167
+
168
+ import { StoreContext, createAppStore } from '~/store/createAppStore';
169
+
170
+ export const StoreProvider: FC<PropsWithChildren<{ savedSettings: SavedSettings }>> = ({
171
+ children,
172
+ savedSettings,
173
+ }) => {
174
+ const [appStore] = useState(() => createAppStore(savedSettings));
175
+
176
+ return <StoreContext.Provider value={appStore}>{children}</StoreContext.Provider>;
177
+ };
178
+ ```
179
+
180
+ **Consumer hooks** — read from context, never from a global store:
181
+
182
+ ```typescript
183
+ // hooks/useAppStore.ts
184
+ import { useContext } from 'react';
185
+ import { useStore } from 'zustand';
186
+ import { useStoreWithEqualityFn } from 'zustand/traditional';
187
+
188
+ import { StoreContext } from '~/store/createAppStore';
189
+ import { AppStore } from '~/types';
190
+
191
+ /** Read a single top-level key from the store. */
192
+ export const useAppStore = <T extends keyof AppStore>(key: T): AppStore[T] => {
193
+ const store = useContext(StoreContext);
194
+ if (!store) throw new Error('useAppStore must be used within StoreProvider');
195
+ return useStore(store, state => state[key]);
196
+ };
197
+
198
+ /** Subscribe to a derived value with optional custom equality. */
199
+ export const useAppStoreSelector = <R>(
200
+ selector: (state: AppStore) => R,
201
+ equalityFn?: (a: R, b: R) => boolean
202
+ ): R => {
203
+ const store = useContext(StoreContext);
204
+ if (!store) throw new Error('useAppStoreSelector must be used within StoreProvider');
205
+ return useStoreWithEqualityFn(store, selector, equalityFn);
206
+ };
207
+ ```
208
+
209
+ **Usage in components:**
210
+
211
+ ```typescript
212
+ const isLegendVisible = useAppStore('isLegendVisible');
213
+ const selectedChannels = useAppStoreSelector(state => state.selectedChannels);
214
+ ```
215
+
216
+ **Wire it up in `ParentApp`** (see full example with `QueryClientProvider` in the Data Fetching section below).
217
+
218
+ General rules:
219
+ - Name stores `use[Name]Store` (e.g., `useWellDataStore`)
220
+ - Use selectors: `const value = useAppStore('value')`
221
+ - Keep business logic in store actions
222
+
223
+ ### Data Fetching (React Query v4)
224
+
225
+ Same as Zustand: the platform runs multiple app instances, so each must have its own `QueryClient`. Never create a `QueryClient` at module level — use a hook with `useState` to create it once per mount.
226
+
227
+ **`useQueryClient` hook** — creates an isolated `QueryClient` per app instance:
228
+
229
+ ```typescript
230
+ // hooks/useQueryClient.ts
231
+ import { useState } from 'react';
232
+ import { QueryCache, QueryClient } from '@tanstack/react-query';
233
+ import { showErrorNotification } from '@corva/ui/utils';
234
+
235
+ export const useQueryClient = () => {
236
+ const [queryClient] = useState(
237
+ new QueryClient({
238
+ queryCache: new QueryCache({
239
+ onError: (error: unknown) => {
240
+ if (typeof error === 'object' && error !== null && 'message' in error) {
241
+ showErrorNotification(`Something went wrong: ${String(error.message)}`);
242
+ }
243
+ },
244
+ }),
245
+ defaultOptions: {
246
+ queries: {
247
+ refetchOnWindowFocus: false,
248
+ refetchOnReconnect: false,
249
+ },
250
+ },
251
+ })
252
+ );
253
+
254
+ return queryClient;
255
+ };
256
+ ```
257
+
258
+ **Wire it up in `ParentApp`** — wrap the app tree with `QueryClientProvider`:
259
+
260
+ ```typescript
261
+ import { QueryClientProvider } from '@tanstack/react-query';
262
+
263
+ const ParentApp = () => {
264
+ const { appSettings, onSettingsChange } = useAppCommons();
265
+ const queryClient = useQueryClient();
266
+
267
+ return (
268
+ <QueryClientProvider client={queryClient}>
269
+ <StoreProvider savedSettings={appSettings?.savedSettings}>
270
+ <App />
271
+ </StoreProvider>
272
+ </QueryClientProvider>
273
+ );
274
+ };
275
+
276
+ export default { component: ParentApp, settings: AppSettings };
277
+ ```
278
+
279
+ General rules:
280
+ - Encapsulate queries in custom hooks (e.g., `useWellData`)
281
+ - Use typed query keys (array format)
282
+ - Always handle `isLoading` and `isError` states
283
+
284
+ ## Naming Conventions
285
+
286
+ - Boolean variables: prefix with `is`, `has`, or `should`
287
+ - Non-empty array checks: `!!array.length` (not `array.length > 0`)
288
+ - Zustand stores: `use[StoreName]Store`
289
+ - TypeScript props: use `interface` (not `type`)
290
+
291
+ ## Testing
292
+
293
+ - **Framework:** Jest + React Testing Library
294
+ - **Wrapper:** Use `AppTestWrapper` from `@corva/ui/testing` to wrap components — it provides `useAppCommons()` context
295
+ - **Pattern:** Pass data via `AppTestWrapper` props, render components with no props
296
+ - **Mocking:** Mock network requests (jest mocks or msw), never call real APIs
297
+ - **Timezone:** UTC is enforced (`process.env.TZ = 'UTC'`)
298
+ - **Mocked globals:** `ResizeObserver`, `MutationObserver` (in `setupTests.js`)
299
+
300
+ ```tsx
301
+ // Test pattern — data flows through AppTestWrapper context
302
+ render(
303
+ <AppTestWrapper appSettings={{ isExampleCheckboxChecked: true }} well={mockWell}>
304
+ <App />
305
+ </AppTestWrapper>
306
+ );
307
+ ```
308
+
309
+ ## Commands
310
+
311
+ ```
312
+ yarn start Dev server at http://app.local.corva.ai:8080/
313
+ yarn build Production bundle
314
+ yarn test Run tests
315
+ yarn lint ESLint check
316
+ yarn zip Create deployment ZIP
317
+ yarn release Release to Corva platform
318
+ ```
319
+
320
+ ## @corva/ui Documentation
321
+
322
+ Local documentation for `@corva/ui` is bundled at `node_modules/@corva/ui/docs/`.
323
+ Before implementing any UI component, data fetch, or API call, read the relevant doc file:
324
+
325
+ - **V2 Components:** `node_modules/@corva/ui/docs/01-components-v2/` — Props, examples, usage
326
+ - **V1 Components:** `node_modules/@corva/ui/docs/02-components-v1/` — Legacy components reference
327
+ - **Hooks:** `node_modules/@corva/ui/docs/03-hooks/` — Parameters, return types, examples
328
+ - **API Clients:** `node_modules/@corva/ui/docs/04-clients/` — corvaAPI, corvaDataAPI endpoints
329
+ - **Theme:** `node_modules/@corva/ui/docs/05-theme/` — Color palette, CSS variables
330
+ - **Utilities:** `node_modules/@corva/ui/docs/06-utilities/` — Helper functions
331
+ - **Constants:** `node_modules/@corva/ui/docs/07-constants/` — Platform constants
332
+
333
+ Start with `node_modules/@corva/ui/docs/README.md` for the full index.
334
+ Do NOT guess `@corva/ui` APIs — read the local docs first.
335
+
336
+ ## MCP Server (Interactive Fallback)
337
+
338
+ The `corva-ui` MCP server is pre-configured (`.mcp.json`, `.cursor/mcp.json`, `.codex/config.toml`).
339
+ Use it for interactive queries when the local docs are insufficient or you need to search across components.
@@ -0,0 +1 @@
1
+ @AGENTS.md
@@ -2,18 +2,14 @@ import { AppContainer, AppHeader } from '@corva/ui/componentsV2';
2
2
  import { useAppCommons } from '@corva/ui/effects';
3
3
 
4
4
  import { DEFAULT_SETTINGS } from './constants';
5
- import { AppProps, CustomAppSettings } from './types';
6
5
  import logo from './assets/logo.svg';
7
6
 
8
7
  import styles from './App.css';
9
8
 
10
- function App({
11
- isExampleCheckboxChecked = DEFAULT_SETTINGS.isExampleCheckboxChecked,
12
- fracFleet,
13
- well,
14
- wells,
15
- }: AppProps & CustomAppSettings): JSX.Element {
16
- const { appKey } = useAppCommons();
9
+ const App = () => {
10
+ const { appKey, fracFleet, well, wells, appSettings } = useAppCommons();
11
+ const { isExampleCheckboxChecked = DEFAULT_SETTINGS.isExampleCheckboxChecked } =
12
+ appSettings || {};
17
13
  // NOTE: On general type dashboard app receives wells array
18
14
  // on asset type dashboard app receives well object
19
15
  const wellsList = wells || [well];
@@ -49,7 +45,7 @@ function App({
49
45
  </div>
50
46
  </AppContainer>
51
47
  );
52
- }
48
+ };
53
49
 
54
50
  // Important: Do not change root component default export (App.js). Use it as container
55
51
  // for your App. It's required to make build and zip scripts work as expected;
@@ -2,17 +2,15 @@ import { AppContainer, AppHeader } from '@corva/ui/componentsV2';
2
2
  import { useAppCommons } from '@corva/ui/effects';
3
3
 
4
4
  import { DEFAULT_SETTINGS } from './constants';
5
- import { AppProps, CustomAppSettings } from './types';
6
5
  import logo from './assets/logo.svg';
7
6
 
8
7
  import styles from './App.css';
9
8
 
10
- function App({
11
- isExampleCheckboxChecked = DEFAULT_SETTINGS.isExampleCheckboxChecked,
12
- rig,
13
- well,
14
- }: AppProps & CustomAppSettings): JSX.Element {
15
- const { appKey } = useAppCommons();
9
+ const App = () => {
10
+ const { appKey, rig, well, appSettings } = useAppCommons();
11
+ const { isExampleCheckboxChecked = DEFAULT_SETTINGS.isExampleCheckboxChecked } =
12
+ appSettings || {};
13
+
16
14
  return (
17
15
  <AppContainer header={<AppHeader />} testId={appKey}>
18
16
  <div className={styles.container}>
@@ -44,7 +42,7 @@ function App({
44
42
  </div>
45
43
  </AppContainer>
46
44
  );
47
- }
45
+ };
48
46
 
49
47
  // Important: Do not change root component default export (App.js). Use it as container
50
48
  // for your App. It's required to make build and zip scripts work as expected;
@@ -1,11 +1,11 @@
1
1
  import { Checkbox, FormControlLabel } from '@material-ui/core';
2
+ import { useAppCommons } from '@corva/ui/effects';
2
3
 
3
4
  import { DEFAULT_SETTINGS } from './constants';
4
- import { AppSettingsProps, CustomAppSettings } from './types';
5
5
 
6
- const AppSettings = (props: AppSettingsProps & CustomAppSettings): JSX.Element => {
7
- const { settings: apiSettings, onSettingChange } = props;
8
- const settings = { ...DEFAULT_SETTINGS, ...apiSettings };
6
+ const AppSettings = () => {
7
+ const { appSettings, onSettingChange } = useAppCommons();
8
+ const settings = { ...DEFAULT_SETTINGS, ...appSettings };
9
9
 
10
10
  return (
11
11
  <div>
@@ -1,194 +1,22 @@
1
- import { AppInstance, AppInstanceData, User, AppHeaderData } from '../types';
2
-
3
- export const mockApp: AppInstance = {
4
- app: { app_key: 'test', platform: 'test' },
5
- id: 1,
6
- package: {
7
- manifest: {
8
- format: 1,
9
- license: { type: 'test', url: 'test' },
10
- developer: { name: 'test', identifier: 'test', authors: [] },
11
- application: {
12
- type: 'test',
13
- key: 'test',
14
- visibility: 'test',
15
- name: 'test',
16
- description: 'test',
17
- summary: 'test',
18
- category: 'test',
19
- website: 'test',
20
- segments: ['test'],
21
- ui: {
22
- initial_size: { w: 100, h: 100 },
23
- multi_rig: false,
24
- full_screen_report: false,
25
- use_app_header_v3: false,
26
- },
27
- },
28
- settings: {
29
- entrypoint: { file: 'test', function: 'test' },
30
- environment: {},
31
- runtime: 'test',
32
- app: { log_type: 'test' },
33
- enable_isolation: false,
34
- },
35
- datasets: {},
36
- },
37
- build: 'test',
38
- version: 'test',
39
- },
40
- segment: ['test'],
41
- settings: {},
1
+ export const mockAppSettings = {
2
+ isExampleCheckboxChecked: true,
42
3
  };
43
4
 
44
- export const mockUser: User = {
45
- id: 1,
46
- company_id: 1,
47
- first_name: 'Test',
48
- last_name: 'User',
49
- email: 'test@test.com',
50
- mobile: '1234567890',
51
- created_at: '2023-01-01',
52
- terms_acceptance_at: '2023-01-01',
53
- profile_photo: null,
54
- recently_viewed_asset_ids: [],
55
- unit_system: null,
56
- custom_unit_system: null,
57
- role: 'test',
58
- title: null,
59
- group: null,
60
- favorite_asset_id: null,
61
- current_segment: 'test',
62
- theme: 'test',
63
- messaging_id: 'test',
64
- restricted_assets: [],
65
- restricted_programs: [],
66
- settings: {
67
- favorites: [],
68
- home_page: { selected_assets_tab: 'test' },
69
- onboarded: false,
70
- beta_2_158: {},
71
- uiSettings: {},
72
- singleAsset: {
73
- padId: 1,
74
- rigId: 1,
75
- wellId: null,
76
- rigAssetId: 1,
77
- fracFleetId: 1,
78
- wellAssetId: null,
79
- drilloutUnitId: 1,
80
- completionWellAssetId: 1,
81
- },
82
- feed_filters: {
83
- company_id: null,
84
- start_date: '2023-01-01',
85
- content_types: [],
86
- selected_rigs_ids: [],
87
- selected_user_ids: [],
88
- users_radio_value: 'test',
89
- assets_radio_value: 'test',
90
- date_range_radio_value: 'test',
91
- },
92
- sms_blacklisted: false,
93
- favorit_asset_ids: [],
94
- restricted_assets: [],
95
- alerts_list_filters: {
96
- end_date: '2023-01-01',
97
- segments: [],
98
- alert_name: 'test',
99
- start_date: '2023-01-01',
100
- validation: 'test',
101
- alert_levels: [],
102
- subscription: 'test',
103
- classification: 'test',
104
- assets_radio_value: 'test',
105
- date_range_radio_value: 'test',
106
- },
107
- restricted_programs: [],
108
- is_dnd_feature_shown: false,
109
- last_new_alerts_check: '2023-01-01',
110
- notifications_filters: {
111
- end_date: '2023-01-01',
112
- start_date: '2023-01-01',
113
- content_types: [],
114
- date_range_radio_value: 'test',
115
- },
116
- directional_app_settings: {
117
- curve_to_lat_threshold: 0,
118
- vert_to_curve_threshold: 0,
119
- },
120
- last_new_feed_items_check: '2023-01-01',
121
- participates_in_beta_apps: false,
122
- 'cross-plot__gradient-manager': [],
123
- last_new_dashboard_shares_check: '2023-01-01',
124
- formation_evaluation_lithology_types: {},
125
- formation_evaluation_custom_gradients: [],
126
- },
127
- last_sign_in_at: '2023-01-01',
128
- locked_access: false,
129
- unit_ids: [],
130
- intercom_admin_id: null,
131
- resource: [],
132
- consent_to_process_data: false,
133
- identity_verification_enabled: null,
134
- intercom_user_hash: 'test',
135
- impersonating: false,
136
- profile_groups: [],
137
- preference: {
138
- id: 1,
139
- push_notifications_enabled: false,
140
- emails_enabled: false,
141
- sms_enabled: false,
142
- alert_levels: [],
143
- play_alerts_sound: false,
144
- show_intercom_icon: false,
145
- segment: [],
146
- disable_create_dashboard: false,
147
- disable_costs: false,
148
- disable_documents: false,
149
- realtime_operation_mode: false,
150
- disable_file_upload: false,
151
- stay_on_app_store: false,
152
- new_navigation_beta: false,
153
- new_mobile_app_enabled: false,
154
- },
155
- company: {
156
- id: 1,
157
- name: 'Test Company',
158
- time_zone: 'UTC',
159
- language: 'en',
160
- provider: 'test',
161
- unit_system: {},
162
- custom_unit_system: {},
163
- custom_units: {},
164
- dev_center_enabled: false,
165
- with_subscription: false,
166
- competitor_analysis_enabled: false,
167
- ai_model_scope: 'test',
168
- },
169
- groups: [],
5
+ export const mockWell = {
6
+ name: 'Test Well',
7
+ asset_id: 12345,
8
+ last_active_at: '2023-01-01',
9
+ id: '1',
170
10
  };
171
11
 
172
- export const mockAppData: AppInstanceData = {
173
- id: 1,
174
- rig: null,
175
- well: null,
176
- fracFleet: null,
177
- program: {
178
- id: null,
179
- name: null,
180
- },
181
- wells: null,
182
- isLoading: false,
183
- appHash: 'test',
12
+ export const mockRig = {
13
+ name: 'Test Rig',
14
+ id: '1',
15
+ asset_id: 9999,
184
16
  };
185
17
 
186
- export const mockAppHeaderProps: AppHeaderData = {
187
- app: mockApp,
188
- appLastAnnotation: null,
189
- appSettings: {},
190
- coordinates: { w: 0, h: 0, x: 0, y: 0, pixelHeight: 0, pixelWidth: 0 },
191
- currentUser: mockUser,
192
- isMaximized: false,
193
- layoutEnvironment: { type: 'test', pdfReportMode: false },
18
+ export const mockFracFleet = {
19
+ name: 'Test Frac Fleet',
20
+ id: '1',
21
+ current_pad_id: 101,
194
22
  };