Skip to content

Commit e1b4eb6

Browse files
committed
Fixes and refactoring
1 parent b0271fd commit e1b4eb6

5 files changed

Lines changed: 53 additions & 55 deletions

File tree

e2e-tests/utilities/api.ts

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
*/
99

1010
import type { Browser, BrowserContext, Page } from '@playwright/test';
11+
import dotenv from 'dotenv';
1112
import fs from 'fs';
1213
import nodePath from 'path';
1314
import { adjectives, animals, colors, uniqueNamesGenerator } from 'unique-names-generator';
@@ -45,23 +46,8 @@ import { SchedulingConditions } from '../fixtures/SchedulingConditions.js';
4546
import { SchedulingGoals } from '../fixtures/SchedulingGoals.js';
4647
import { View } from '../fixtures/View.js';
4748

48-
// Load .env file if it exists (Node.js doesn't load it automatically)
49-
const envPath = nodePath.resolve(process.cwd(), '.env');
50-
if (fs.existsSync(envPath)) {
51-
for (const line of fs.readFileSync(envPath, 'utf-8').split('\n')) {
52-
const trimmed = line.trim();
53-
if (trimmed && !trimmed.startsWith('#')) {
54-
const eqIndex = trimmed.indexOf('=');
55-
if (eqIndex > 0) {
56-
const key = trimmed.slice(0, eqIndex);
57-
const value = trimmed.slice(eqIndex + 1).replace(/^['"]|['"]$/g, '');
58-
if (!process.env[key]) {
59-
process.env[key] = value;
60-
}
61-
}
62-
}
63-
}
64-
}
49+
// Load .env file if it exists (won't override existing env vars)
50+
dotenv.config();
6551

6652
// Default URLs from environment variables, with fallbacks for local development
6753
const DEFAULT_HASURA_URL = process.env.PUBLIC_HASURA_CLIENT_URL ?? 'http://localhost:8080/v1/graphql';

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@
123123
"@vitest/ui": "^1.4.0",
124124
"autoprefixer": "^10.4.20",
125125
"cloc": "2.0.0-cloc",
126+
"dotenv": "^17.3.1",
126127
"esbuild": "^0.24.0",
127128
"eslint": "^8.43.0",
128129
"eslint-config-prettier": "^9.1.0",

scripts/deseed.ts

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@
1111

1212
import { AerieApi } from '../e2e-tests/utilities/api.js';
1313

14-
// Pattern to identify seeded items: name contains " (" indicating unique suffix
15-
const isSeedItem = (name: string): boolean => name.includes(' (') && name.includes(')');
14+
// Pattern to identify seeded items: name ends with " (animal-suffix)" from unique-names-generator
15+
const isSeedItem = (name: string): boolean => /\(\w+\)$/.test(name);
1616

1717
// External type name prefixes from seed script (actual names have _suffix appended)
1818
const SEED_EXTERNAL_SOURCE_TYPE_PREFIX = 'BananaSupplySource_';
@@ -160,7 +160,7 @@ async function deseed() {
160160

161161
// Delete in reverse order of creation to respect foreign keys
162162

163-
// 15. Delete plans (they reference models)
163+
// 1. Delete plans (they reference models)
164164
if (seededPlans.length > 0) {
165165
console.log('Deleting plans...');
166166
for (const plan of seededPlans) {
@@ -174,7 +174,7 @@ async function deseed() {
174174
console.log('');
175175
}
176176

177-
// 1. Delete models
177+
// 2. Delete models
178178
if (seededModels.length > 0) {
179179
console.log('Deleting models...');
180180
for (const model of seededModels) {
@@ -188,7 +188,7 @@ async function deseed() {
188188
console.log('');
189189
}
190190

191-
// 2. Delete external sources first (they contain events and reference derivation groups)
191+
// 3. Delete external sources (they contain events and reference derivation groups)
192192
if (seededExternalSources.length > 0) {
193193
console.log('Deleting external sources...');
194194
// Group sources by derivation group for deletion
@@ -211,7 +211,7 @@ async function deseed() {
211211
console.log('');
212212
}
213213

214-
// 3. Delete derivation groups
214+
// 4. Delete derivation groups
215215
if (seededDerivationGroups.length > 0) {
216216
console.log('Deleting derivation groups...');
217217
try {
@@ -226,7 +226,7 @@ async function deseed() {
226226
console.log('');
227227
}
228228

229-
// 4. Delete external event types (after events are deleted with sources)
229+
// 5. Delete external event types (after events are deleted with sources)
230230
if (seededEventTypes.length > 0) {
231231
console.log('Deleting external event types...');
232232
try {
@@ -241,7 +241,7 @@ async function deseed() {
241241
console.log('');
242242
}
243243

244-
// 5. Delete external source types (after derivation groups are deleted)
244+
// 6. Delete external source types (after derivation groups are deleted)
245245
if (seededSourceTypes.length > 0) {
246246
console.log('Deleting external source types...');
247247
try {
@@ -256,7 +256,7 @@ async function deseed() {
256256
console.log('');
257257
}
258258

259-
// 6. Delete action definitions (they reference workspaces)
259+
// 7. Delete action definitions (they reference workspaces)
260260
if (seededActionDefinitions.length > 0) {
261261
console.log('Deleting action definitions...');
262262
for (const action of seededActionDefinitions) {
@@ -270,7 +270,7 @@ async function deseed() {
270270
console.log('');
271271
}
272272

273-
// 7. Delete extensions (no foreign key dependencies)
273+
// 8. Delete extensions (no foreign key dependencies)
274274
if (seededExtensions.length > 0) {
275275
console.log('Deleting extensions...');
276276
for (const ext of seededExtensions) {
@@ -284,7 +284,7 @@ async function deseed() {
284284
console.log('');
285285
}
286286

287-
// 8. Delete workspaces (they reference parcels)
287+
// 9. Delete workspaces (they reference parcels)
288288
if (seededWorkspaces.length > 0) {
289289
console.log('Deleting workspaces...');
290290
for (const workspace of seededWorkspaces) {
@@ -298,7 +298,7 @@ async function deseed() {
298298
console.log('');
299299
}
300300

301-
// 9. Delete expansion sets (they reference expansion rules)
301+
// 10. Delete expansion sets (they reference expansion rules)
302302
if (seededExpansionSets.length > 0) {
303303
console.log('Deleting expansion sets...');
304304
for (const set of seededExpansionSets) {
@@ -312,7 +312,7 @@ async function deseed() {
312312
console.log('');
313313
}
314314

315-
// 10. Delete expansion rules (they reference parcels)
315+
// 11. Delete expansion rules (they reference parcels)
316316
if (seededExpansionRules.length > 0) {
317317
console.log('Deleting expansion rules...');
318318
for (const rule of seededExpansionRules) {
@@ -326,7 +326,7 @@ async function deseed() {
326326
console.log('');
327327
}
328328

329-
// 11. Delete parcels (they reference dictionaries and expansion rules reference them)
329+
// 12. Delete parcels (they reference dictionaries and expansion rules reference them)
330330
if (seededParcels.length > 0) {
331331
console.log('Deleting parcels...');
332332
for (const parcel of seededParcels) {
@@ -340,7 +340,7 @@ async function deseed() {
340340
console.log('');
341341
}
342342

343-
// 12. Delete dictionaries (after parcels since parcels reference them)
343+
// 13. Delete dictionaries (after parcels since parcels reference them)
344344
if (seededCommandDicts.length > 0) {
345345
console.log('Deleting command dictionaries...');
346346
for (const dict of seededCommandDicts) {
@@ -386,7 +386,7 @@ async function deseed() {
386386
console.log('');
387387
}
388388

389-
// 13. Delete sequence adaptations
389+
// 14. Delete sequence adaptations
390390
if (seededAdaptations.length > 0) {
391391
console.log('Deleting sequence adaptations...');
392392
for (const adaptation of seededAdaptations) {
@@ -400,7 +400,7 @@ async function deseed() {
400400
console.log('');
401401
}
402402

403-
// 14. Delete views
403+
// 15. Delete views
404404
if (seededViews.length > 0) {
405405
console.log('Deleting views...');
406406
for (const view of seededViews) {
@@ -414,7 +414,7 @@ async function deseed() {
414414
console.log('');
415415
}
416416

417-
// 15. Delete scheduling conditions
417+
// 16. Delete scheduling conditions
418418
if (seededConditions.length > 0) {
419419
console.log('Deleting scheduling conditions...');
420420
for (const condition of seededConditions) {
@@ -428,7 +428,7 @@ async function deseed() {
428428
console.log('');
429429
}
430430

431-
// 16. Delete scheduling goals
431+
// 17. Delete scheduling goals
432432
if (seededGoals.length > 0) {
433433
console.log('Deleting scheduling goals...');
434434
for (const goal of seededGoals) {
@@ -442,7 +442,7 @@ async function deseed() {
442442
console.log('');
443443
}
444444

445-
// 17. Delete constraints
445+
// 18. Delete constraints
446446
if (seededConstraints.length > 0) {
447447
console.log('Deleting constraints...');
448448
for (const constraint of seededConstraints) {
@@ -456,7 +456,7 @@ async function deseed() {
456456
console.log('');
457457
}
458458

459-
// 18. Delete tags
459+
// 19. Delete tags
460460
if (seededTags.length > 0) {
461461
console.log('Deleting tags...');
462462
for (const tag of seededTags) {

scripts/seed.ts

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,14 @@
2929

3030
import fs from 'fs';
3131
import { animals, uniqueNamesGenerator } from 'unique-names-generator';
32+
import { AerieApi } from '../e2e-tests/utilities/api.js';
3233
import { ConstraintDefinitionType } from '../src/enums/constraint.js';
3334
import { SchedulingDefinitionType } from '../src/enums/scheduling.js';
3435
import type { ActivityDirectiveInsertInput } from '../src/types/activity.js';
3536
import type { SchedulingConditionInsertInput } from '../src/types/scheduling.js';
3637
import { ResourceType } from '../src/types/simulation.js';
3738
import { getIntervalFromDoyRange, getUnixEpochTime } from '../src/utilities/time.js';
3839
import { generateDefaultView } from '../src/utilities/view.js';
39-
import { AerieApi } from '../e2e-tests/utilities/api.js';
4040

4141
// Generate unique suffix for this seed run
4242
const uniqueSuffix = uniqueNamesGenerator({ dictionaries: [animals], separator: '-' });
@@ -189,14 +189,14 @@ const PLANS: PlanConfig[] = [
189189
name: 'Monthly Production',
190190
startTime: '2024-001T00:00:00',
191191
},
192-
// {
193-
// // Quarter-long mission (10K activities)
194-
// activityMix: { BiteBanana: 2500, GrowBanana: 2000, PeelBanana: 2500, PickBanana: 3000 },
195-
// description: 'Full quarterly mission with comprehensive operations',
196-
// endTime: '2024-091T00:00:00',
197-
// name: 'Q1 Mission',
198-
// startTime: '2024-001T00:00:00',
199-
// },
192+
{
193+
// Quarter-long mission (10K activities)
194+
activityMix: { BiteBanana: 2500, GrowBanana: 2000, PeelBanana: 2500, PickBanana: 3000 },
195+
description: 'Full quarterly mission with comprehensive operations',
196+
endTime: '2024-091T00:00:00',
197+
name: 'Q1 Mission',
198+
startTime: '2024-001T00:00:00',
199+
},
200200
];
201201

202202
// Constraint definitions (EDSL format)
@@ -693,6 +693,9 @@ async function seed() {
693693
.replace('mission_name="GENERIC"', `mission_name="${missionName}"`);
694694
const commandDictResult = await api.createDictionary(commandDictXml);
695695
const commandDictId = commandDictResult.command?.id;
696+
if (commandDictId == null) {
697+
throw new Error('Command dictionary creation failed: no command ID returned');
698+
}
696699
console.log(` - Created command dictionary (ID: ${commandDictId}, mission: ${missionName})`);
697700

698701
// Read and upload channel dictionary with customized mission name
@@ -724,7 +727,7 @@ async function seed() {
724727
const parcelName = `Seed Parcel (${uniqueSuffix})`;
725728
const parcel = await api.createParcel({
726729
channel_dictionary_id: channelDictId ?? null,
727-
command_dictionary_id: commandDictId!,
730+
command_dictionary_id: commandDictId,
728731
name: parcelName,
729732
sequence_adaptation_id: null, // Adaptations are linked separately
730733
});
@@ -840,7 +843,7 @@ async function seed() {
840843
// Reusable content
841844
const sequenceContent = `@ID "seed_sequence"\n\nC FSW_CMD_0 "ON" true 0.5\nC FSW_CMD_1 1.0 10 "2024-001T00:00:00" 100 "0000"\n`;
842845
const textContent = `Seed Workspace Notes\n====================\n\nCreated by seed script. Suffix: ${uniqueSuffix}\n`;
843-
const jsonContent = `{ seeded_json: ${uniqueSuffix} }`;
846+
const jsonContent = JSON.stringify({ seeded_json: uniqueSuffix }, null, 2);
844847
const binaryContent = new Uint8Array(256).map(() => Math.floor(Math.random() * 256));
845848
// Minimal valid JPEG (1x1 pixel)
846849
// prettier-ignore
@@ -870,7 +873,7 @@ async function seed() {
870873
{ content: textContent, path: 'seed_notes.txt' },
871874
{ content: binaryContent, path: 'seed_data.bin' },
872875
{ content: jpegContent, path: 'seed_image.jpg' },
873-
{ content: jsonContent, path: 'seed_image.json' },
876+
{ content: jsonContent, path: 'seed_data.json' },
874877
{ path: 'seed_folder' }, // folder
875878
{ content: sequenceContent, path: 'seed_folder/folder_sequence.seq' },
876879
{ content: binaryContent, path: 'seed_folder/folder_data.bin' },
@@ -903,7 +906,7 @@ async function seed() {
903906
let largeWorkspaceItemCount = 0;
904907

905908
for (const project of projects) {
906-
// Create project folder
909+
// Create project folder (must exist before children)
907910
await api.createWorkspaceItem(largeWorkspaceId, `project_${project}`);
908911
largeWorkspaceItemCount++;
909912

@@ -913,30 +916,37 @@ async function seed() {
913916
await api.createWorkspaceItem(largeWorkspaceId, modulePath);
914917
largeWorkspaceItemCount++;
915918

916-
// Create regular files in module
919+
// Create regular files in module in parallel
920+
const filePromises: Promise<void>[] = [];
917921
for (let f = 1; f <= 15; f++) {
918922
const ext = fileTypes[(f - 1) % fileTypes.length];
919923
const filePath = `${modulePath}/file_${f.toString().padStart(3, '0')}${ext}`;
920924
const content = fileMap[ext];
921-
await api.createWorkspaceItem(largeWorkspaceId, filePath, content);
925+
filePromises.push(api.createWorkspaceItem(largeWorkspaceId, filePath, content));
922926
largeWorkspaceItemCount++;
923927
}
928+
await Promise.all(filePromises);
924929

925930
// Add deep nesting for every other module (up to 7 levels deep)
926931
if (m % 2 === 1) {
927932
const depths = ['level_1', 'level_2', 'level_3', 'level_4', 'level_5'];
928933
let currentPath = modulePath;
929934
for (const depth of depths) {
930935
currentPath = `${currentPath}/${depth}`;
936+
// Create nested folder (must exist before children)
931937
await api.createWorkspaceItem(largeWorkspaceId, currentPath);
932938
largeWorkspaceItemCount++;
933-
// Add a few files at each level
939+
// Create files at this level in parallel
940+
const nestedFilePromises: Promise<void>[] = [];
934941
for (let f = 1; f <= 3; f++) {
935942
const ext = fileTypes[(f - 1) % fileTypes.length];
936943
const content = fileMap[ext];
937-
await api.createWorkspaceItem(largeWorkspaceId, `${currentPath}/nested_${f}${ext}`, content);
944+
nestedFilePromises.push(
945+
api.createWorkspaceItem(largeWorkspaceId, `${currentPath}/nested_${f}${ext}`, content),
946+
);
938947
largeWorkspaceItemCount++;
939948
}
949+
await Promise.all(nestedFilePromises);
940950
}
941951
}
942952
}

src/components/timeline/Row.svelte

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -524,6 +524,7 @@
524524
link => link.plan_id === plan?.id && !($derivationGroupVisibilityMap[link.derivation_group_name] ?? true),
525525
)
526526
.map(link => link.derivation_group_name);
527+
527528
// Apply filter for hiding derivation groups
528529
let externalEventsFilteredByDG = externalEvents.filter(ee => {
529530
let derivationGroup =

0 commit comments

Comments
 (0)