From 733bf3182e00e2b43a9b7a553259e69dd0ad4c93 Mon Sep 17 00:00:00 2001 From: bduran Date: Mon, 23 Sep 2024 13:39:59 -0700 Subject: [PATCH 01/14] fix collapse clickthrough --- src/components/Collapse.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Collapse.svelte b/src/components/Collapse.svelte index b705754a3d..48ac6c4a34 100644 --- a/src/components/Collapse.svelte +++ b/src/components/Collapse.svelte @@ -40,7 +40,7 @@ class:static={!collapsible} class:expanded style:height={`${headerHeight}px`} - on:click={() => { + on:click|stopPropagation={() => { if (collapsible) { expanded = !expanded; dispatch('collapse', !expanded); From c879818cd050304ab9d2ca71b2e28138957ca173 Mon Sep 17 00:00:00 2001 From: bduran Date: Mon, 23 Sep 2024 13:40:58 -0700 Subject: [PATCH 02/14] move scheduling enum file to enums directory --- src/components/scheduling/goals/SchedulingGoalForm.svelte | 2 +- src/{constants => enums}/scheduling.ts | 0 src/types/scheduling.ts | 2 +- src/utilities/effects.ts | 2 +- 4 files changed, 3 insertions(+), 3 deletions(-) rename src/{constants => enums}/scheduling.ts (100%) diff --git a/src/components/scheduling/goals/SchedulingGoalForm.svelte b/src/components/scheduling/goals/SchedulingGoalForm.svelte index ee78e0176d..497550f249 100644 --- a/src/components/scheduling/goals/SchedulingGoalForm.svelte +++ b/src/components/scheduling/goals/SchedulingGoalForm.svelte @@ -4,8 +4,8 @@ import { goto } from '$app/navigation'; import { base } from '$app/paths'; import { createEventDispatcher } from 'svelte'; - import { SchedulingType } from '../../../constants/scheduling'; import { DefinitionType } from '../../../enums/association'; + import { SchedulingType } from '../../../enums/scheduling'; import { SearchParameters } from '../../../enums/searchParameters'; import { schedulingGoals } from '../../../stores/scheduling'; import type { User, UserId } from '../../../types/app'; diff --git a/src/constants/scheduling.ts b/src/enums/scheduling.ts similarity index 100% rename from src/constants/scheduling.ts rename to src/enums/scheduling.ts diff --git a/src/types/scheduling.ts b/src/types/scheduling.ts index d52e8fb072..fbf883cf16 100644 --- a/src/types/scheduling.ts +++ b/src/types/scheduling.ts @@ -1,4 +1,4 @@ -import type { SchedulingType } from '../constants/scheduling'; +import type { SchedulingType } from '../enums/scheduling'; import type { PartialWith } from './app'; import type { SchedulingError } from './errors'; import type { BaseDefinition, BaseMetadata } from './metadata'; diff --git a/src/utilities/effects.ts b/src/utilities/effects.ts index d73c0b3e35..97cd0fa710 100644 --- a/src/utilities/effects.ts +++ b/src/utilities/effects.ts @@ -7,8 +7,8 @@ import { type ParameterDictionary as AmpcsParameterDictionary, } from '@nasa-jpl/aerie-ampcs'; import { get } from 'svelte/store'; -import { SchedulingType } from '../constants/scheduling'; import { DictionaryTypes } from '../enums/dictionaryTypes'; +import { SchedulingType } from '../enums/scheduling'; import { SearchParameters } from '../enums/searchParameters'; import { Status } from '../enums/status'; import { activityDirectivesDB, selectedActivityDirectiveId } from '../stores/activities'; From 745ebdbf66cfbfd41151fea41afd690567a703d8 Mon Sep 17 00:00:00 2001 From: bduran Date: Wed, 25 Sep 2024 09:42:40 -0700 Subject: [PATCH 03/14] Add ability to upload external dataset to plan --- src/components/ResourceList.svelte | 20 ++++ src/components/TimelineItemList.svelte | 104 ++++++++++++++++++ .../activity/TimelineItemsPanel.svelte | 4 +- src/routes/plans/[id]/+page.svelte | 4 +- src/utilities/effects.ts | 25 +++++ src/utilities/gql.ts | 1 + src/utilities/permissions.ts | 15 ++- 7 files changed, 170 insertions(+), 3 deletions(-) diff --git a/src/components/ResourceList.svelte b/src/components/ResourceList.svelte index 1c8cafa4eb..6bbfe2f76b 100644 --- a/src/components/ResourceList.svelte +++ b/src/components/ResourceList.svelte @@ -1,19 +1,36 @@ ({ label: t, value: t }))} filterName="Data Type" + shouldShowUploadOption + {hasUploadPermission} {getFilterValueFromItem} let:prop={item} + on:upload={onUploadFile} > diff --git a/src/components/TimelineItemList.svelte b/src/components/TimelineItemList.svelte index 0086b5433b..e0b2cd31fd 100644 --- a/src/components/TimelineItemList.svelte +++ b/src/components/TimelineItemList.svelte @@ -2,8 +2,10 @@
@@ -187,11 +216,56 @@
+ {#if isUploadVisible} + + {/if}
{typeNamePlural} ({filteredItems.length})
+ {#if shouldShowUploadOption} + + {/if} @@ -33,7 +35,7 @@ - + diff --git a/src/routes/plans/[id]/+page.svelte b/src/routes/plans/[id]/+page.svelte index a37b4b015e..43c87601d6 100644 --- a/src/routes/plans/[id]/+page.svelte +++ b/src/routes/plans/[id]/+page.svelte @@ -414,7 +414,9 @@ $: if ($initialPlan && browser) { // Asynchronously fetch resource types effects.getResourceTypes($initialPlan.model_id, data.user).then(initialResourceTypes => { - $resourceTypes = initialResourceTypes; + externalResourceNames; + + $resourceTypes = [...initialResourceTypes, ...$externalResources.map(({ name, schema }) => ({ name, schema }))]; $resourceTypesLoading = false; }); } diff --git a/src/utilities/effects.ts b/src/utilities/effects.ts index 97cd0fa710..56c69222dd 100644 --- a/src/utilities/effects.ts +++ b/src/utilities/effects.ts @@ -6405,6 +6405,31 @@ const effects = { } }, + async uploadExternalDataset(plan: Plan, files: FileList, user: User | null): Promise { + try { + if (!gatewayPermissions.ADD_EXTERNAL_DATASET(user, plan)) { + throwPermissionError('add external datasets'); + } + + const file: File = files[0]; + + const body = new FormData(); + body.append('plan_id', `${plan.id}`); + body.append('file', file, file.name); + + const uploadedDataset = await reqGateway('/uploadDataset', 'POST', body, user, true); + + if (uploadedDataset != null) { + return uploadedDataset; + } + + return null; + } catch (e) { + catchError(e as Error); + return null; + } + }, + async uploadFile(file: File, user: User | null): Promise { try { const body = new FormData(); diff --git a/src/utilities/gql.ts b/src/utilities/gql.ts index a5905915e1..eebcf0ddf6 100644 --- a/src/utilities/gql.ts +++ b/src/utilities/gql.ts @@ -5,6 +5,7 @@ export enum Queries { ACTIVITY_DIRECTIVE_VALIDATIONS = 'activity_directive_validations', ACTIVITY_PRESETS = 'activity_presets', ACTIVITY_TYPES = 'activity_type', + ADD_EXTERNAL_DATASET = 'addExternalDataset', ANCHOR_VALIDATION_STATUS = 'anchor_validation_status', APPLY_PRESET_TO_ACTIVITY = 'apply_preset_to_activity', BEGIN_MERGE = 'begin_merge', diff --git a/src/utilities/permissions.ts b/src/utilities/permissions.ts index cf62f7b81c..0bfb68456a 100644 --- a/src/utilities/permissions.ts +++ b/src/utilities/permissions.ts @@ -24,7 +24,7 @@ import type { SchedulingGoalMetadata, } from '../types/scheduling'; import type { Parcel, UserSequence, Workspace } from '../types/sequencing'; -import type { Simulation, SimulationTemplate } from '../types/simulation'; +import type { PlanDataset, Simulation, SimulationTemplate } from '../types/simulation'; import type { Tag } from '../types/tags'; import type { View, ViewSlim } from '../types/view'; import gql, { Queries } from './gql'; @@ -1149,6 +1149,12 @@ const queryPermissions: Record b }; const gatewayPermissions = { + ADD_EXTERNAL_DATASET: (user: User | null, plan: PlanWithOwners): boolean => { + const queries = [getFunctionPermission(Queries.ADD_EXTERNAL_DATASET)]; + return ( + isUserAdmin(user) || (getPermission(queries, user) && (isPlanOwner(user, plan) || isPlanCollaborator(user, plan))) + ); + }, IMPORT_PLAN: (user: User | null) => { return ( isUserAdmin(user) || @@ -1302,6 +1308,7 @@ interface FeaturePermissions { expansionSequences: ExpansionSequenceCRUDPermission>; expansionSets: ExpansionSetsCRUDPermission>; externalEventType: CRUDPermission; + externalResources: PlanAssetCRUDPermission; externalSource: CRUDPermission; externalSourceType: CRUDPermission; model: CRUDPermission; @@ -1414,6 +1421,12 @@ const featurePermissions: FeaturePermissions = { canRead: user => queryPermissions.SUB_EXTERNAL_EVENT_TYPES(user), canUpdate: () => false, // no feature to update external event types }, + externalResources: { + canCreate: (user, plan) => gatewayPermissions.ADD_EXTERNAL_DATASET(user, plan), + canDelete: () => false, + canRead: () => true, + canUpdate: () => true, + }, externalSource: { canCreate: user => queryPermissions.CREATE_EXTERNAL_SOURCE(user), canDelete: (user, externalSources) => queryPermissions.DELETE_EXTERNAL_SOURCES(user, externalSources), From 88572c38454f87abe55902662313bda6de7e92fe Mon Sep 17 00:00:00 2001 From: bduran Date: Fri, 27 Sep 2024 10:02:12 -0700 Subject: [PATCH 04/14] add ability to associate simulation dataset to external datasets --- src/components/ResourceList.svelte | 139 +++++++++++++++++++++++-- src/components/TimelineItemList.svelte | 118 +++------------------ src/utilities/effects.ts | 16 ++- 3 files changed, 154 insertions(+), 119 deletions(-) diff --git a/src/components/ResourceList.svelte b/src/components/ResourceList.svelte index 6bbfe2f76b..62b8f87a60 100644 --- a/src/components/ResourceList.svelte +++ b/src/components/ResourceList.svelte @@ -1,20 +1,28 @@ @@ -40,11 +64,110 @@ typeNamePlural="Resources" filterOptions={resourceDataTypes.map(t => ({ label: t, value: t }))} filterName="Data Type" - shouldShowUploadOption - {hasUploadPermission} {getFilterValueFromItem} let:prop={item} - on:upload={onUploadFile} > + +
+ +
+ + diff --git a/src/components/TimelineItemList.svelte b/src/components/TimelineItemList.svelte index e0b2cd31fd..881d64f653 100644 --- a/src/components/TimelineItemList.svelte +++ b/src/components/TimelineItemList.svelte @@ -2,10 +2,9 @@
@@ -216,57 +188,16 @@
- {#if isUploadVisible} - - {/if}
+
{typeNamePlural} ({filteredItems.length})
- {#if shouldShowUploadOption} - - {/if} - +
+ + +
{ + async uploadExternalDataset( + plan: Plan, + files: FileList, + user: User | null, + simulationDatasetId?: number, + ): Promise { try { if (!gatewayPermissions.ADD_EXTERNAL_DATASET(user, plan)) { throwPermissionError('add external datasets'); @@ -6415,12 +6420,13 @@ const effects = { const body = new FormData(); body.append('plan_id', `${plan.id}`); - body.append('file', file, file.name); + body.append('simulation_dataset_id', `${simulationDatasetId}`); + body.append('external_dataset', file, file.name); - const uploadedDataset = await reqGateway('/uploadDataset', 'POST', body, user, true); + const uploadedDatasetId = await reqGateway('/uploadDataset', 'POST', body, user, true); - if (uploadedDataset != null) { - return uploadedDataset; + if (uploadedDatasetId != null) { + return uploadedDatasetId; } return null; From 5f65006f85faeb3b85d0e1c2f5dd80ea45b9a863 Mon Sep 17 00:00:00 2001 From: bduran Date: Mon, 30 Sep 2024 18:22:11 -0700 Subject: [PATCH 05/14] styling --- src/components/ResourceList.svelte | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/ResourceList.svelte b/src/components/ResourceList.svelte index 62b8f87a60..a90d678c25 100644 --- a/src/components/ResourceList.svelte +++ b/src/components/ResourceList.svelte @@ -86,7 +86,7 @@ }} /> Date: Tue, 1 Oct 2024 13:00:48 -0700 Subject: [PATCH 06/14] add e2e tests for dataset uploading --- e2e-tests/data/external-dataset.csv | 6 +++ e2e-tests/data/external-dataset.json | 43 +++++++++++++++++++ e2e-tests/fixtures/Plan.ts | 16 ++++++++ e2e-tests/tests/plan-resources.test.ts | 57 ++++++++++++++++++++++++++ 4 files changed, 122 insertions(+) create mode 100644 e2e-tests/data/external-dataset.csv create mode 100644 e2e-tests/data/external-dataset.json create mode 100644 e2e-tests/tests/plan-resources.test.ts diff --git a/e2e-tests/data/external-dataset.csv b/e2e-tests/data/external-dataset.csv new file mode 100644 index 0000000000..4d968098a9 --- /dev/null +++ b/e2e-tests/data/external-dataset.csv @@ -0,0 +1,6 @@ +time_utc,TotalPower,BatteryStateOfCharge,Temperature +2024-245T00:01:00.0,0.0,143.15,0.0 +2024-245T00:02:00.0,384.999999940483,1.4,-12.0964867663028 +2024-245T00:03:00.0,384.999999399855,137.45,-12.0974993557598 +2024-245T00:04:00.0,385.000010807604,134.85,-12.0985125609155 +2024-245T00:05:00.0,381.80000002749,132.4,-12.0995253838464 diff --git a/e2e-tests/data/external-dataset.json b/e2e-tests/data/external-dataset.json new file mode 100644 index 0000000000..cfdd4e6b61 --- /dev/null +++ b/e2e-tests/data/external-dataset.json @@ -0,0 +1,43 @@ +{ + "datasetStart": "2024-245T14:00:00", + "profileSet": { + "/orientation": { + "schema": { + "items": { + "x": { + "type": "real" + }, + "y": { + "type": "real" + }, + "z": { + "type": "real" + } + }, + "type": "struct" + }, + "segments": [ + { + "duration": 3600000000, + "dynamics": { + "x": 0, + "y": 0, + "z": 1 + } + }, + { + "duration": 3600000000 + }, + { + "duration": 3600000000, + "dynamics": { + "x": 1, + "y": 1, + "z": 0 + } + } + ], + "type": "discrete" + } + } +} diff --git a/e2e-tests/fixtures/Plan.ts b/e2e-tests/fixtures/Plan.ts index 24f919060f..21bffc778f 100644 --- a/e2e-tests/fixtures/Plan.ts +++ b/e2e-tests/fixtures/Plan.ts @@ -94,6 +94,7 @@ export class Plan { } async addActivity(name: string = 'GrowBanana') { + await this.showPanel(PanelNames.TIMELINE_ITEMS); const currentNumOfActivitiesWithName = await this.panelActivityDirectivesTable.getByRole('row', { name }).count(); const activityListItem = this.page.locator(`.list-item :text-is("${name}")`); const activityRow = this.page @@ -253,6 +254,13 @@ export class Plan { await this.panelActivityForm.getByPlaceholder('Enter preset name').blur(); } + async fillExternalDatasetFileInput(importFilePath: string) { + const inputFile = this.page.locator('input[name="file"]'); + await inputFile.focus(); + await inputFile.setInputFiles(importFilePath); + await inputFile.evaluate(e => e.blur()); + } + async fillPlanName(name: string) { await this.planNameInput.fill(name); await this.planNameInput.evaluate(e => e.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter' }))); @@ -554,6 +562,14 @@ export class Plan { this.schedulingSatisfiedActivity = page.locator('.scheduling-goal-analysis-activities-list > .satisfied-activity'); } + async uploadExternalDatasets(importFilePath: string) { + await this.panelActivityTypes.getByRole('button', { exact: true, name: 'Resources' }).click(); + await this.panelActivityTypes.getByRole('button', { exact: true, name: 'Upload Resources' }).click(); + await this.fillExternalDatasetFileInput(importFilePath); + await expect(this.panelActivityTypes.getByRole('button', { exact: true, name: 'Upload' })).toBeEnabled(); + await this.panelActivityTypes.getByRole('button', { exact: true, name: 'Upload' }).click(); + } + async waitForActivityCheckingStatus(status: Status) { await expect(this.page.locator(this.activityCheckingStatusSelector(status))).toBeAttached({ timeout: 10000 }); await expect(this.page.locator(this.activityCheckingStatusSelector(status))).toBeVisible(); diff --git a/e2e-tests/tests/plan-resources.test.ts b/e2e-tests/tests/plan-resources.test.ts new file mode 100644 index 0000000000..326ebff542 --- /dev/null +++ b/e2e-tests/tests/plan-resources.test.ts @@ -0,0 +1,57 @@ +import test, { expect, type BrowserContext, type Page } from '@playwright/test'; +import { Constraints } from '../fixtures/Constraints.js'; +import { Models } from '../fixtures/Models.js'; +import { Plan } from '../fixtures/Plan.js'; +import { Plans } from '../fixtures/Plans.js'; +import { SchedulingConditions } from '../fixtures/SchedulingConditions.js'; +import { SchedulingGoals } from '../fixtures/SchedulingGoals.js'; + +let constraints: Constraints; +let context: BrowserContext; +let models: Models; +let page: Page; +let plan: Plan; +let plans: Plans; +let schedulingConditions: SchedulingConditions; +let schedulingGoals: SchedulingGoals; + +test.beforeAll(async ({ baseURL, browser }) => { + context = await browser.newContext(); + page = await context.newPage(); + + models = new Models(page); + plans = new Plans(page, models); + constraints = new Constraints(page); + schedulingConditions = new SchedulingConditions(page); + schedulingGoals = new SchedulingGoals(page); + plan = new Plan(page, plans, constraints, schedulingGoals, schedulingConditions); + + await models.goto(); + await models.createModel(baseURL); + await plans.goto(); + await plans.createPlan(); + await plan.goto(); +}); + +test.afterAll(async () => { + await plans.goto(); + await plans.deletePlan(); + await models.goto(); + await models.deleteModel(); + await page.close(); + await context.close(); +}); + +test.describe.serial('Plan Resources', () => { + test('Uploading external plan dataset file - JSON', async () => { + await plan.uploadExternalDatasets('e2e-tests/data/external-dataset.json'); + await expect(plan.panelActivityTypes.getByText('/orientation')).toBeVisible(); + }); + + test('Uploading external plan dataset file - CSV', async () => { + await plan.uploadExternalDatasets('e2e-tests/data/external-dataset.csv'); + await expect(plan.panelActivityTypes.getByText('TotalPower')).toBeVisible(); + await expect(plan.panelActivityTypes.getByText('BatteryStateOfCharge')).toBeVisible(); + await expect(plan.panelActivityTypes.getByText('Temperature')).toBeVisible(); + }); +}); From 3e2a469ef5f7ee33cd78dcf6336f174418c42021 Mon Sep 17 00:00:00 2001 From: bduran Date: Mon, 7 Oct 2024 13:13:39 -0700 Subject: [PATCH 07/14] update design --- src/components/ResourceList.svelte | 30 ++++++++++++++------------ src/components/TimelineItemList.svelte | 15 ++++--------- 2 files changed, 20 insertions(+), 25 deletions(-) diff --git a/src/components/ResourceList.svelte b/src/components/ResourceList.svelte index a90d678c25..13aec3d824 100644 --- a/src/components/ResourceList.svelte +++ b/src/components/ResourceList.svelte @@ -2,6 +2,7 @@ { - const uniqueLookup: Set = new Set(); - $resourceTypes = [...initialResourceTypes, ...$externalResources].reduce( - (prevExternalResources: ResourceType[], { name, schema }) => { - if (!uniqueLookup.has(name)) { - uniqueLookup.add(name); - prevExternalResources.push({ name, schema }); - } - return prevExternalResources; - }, - [], - ); + $resourceTypes = initialResourceTypes; $resourceTypesLoading = false; }); } diff --git a/src/stores/simulation.ts b/src/stores/simulation.ts index 01a3a1af53..01e60b29a6 100644 --- a/src/stores/simulation.ts +++ b/src/stores/simulation.ts @@ -100,6 +100,15 @@ export const selectedSimulationEventId: Writable = writable(null) /* Derived. */ +export const allResourceTypes: Readable = derived( + [resourceTypes, externalResources], + ([$resourceTypes, $externalResources]) => { + return $resourceTypes + .map(({ name, schema }) => ({ name, schema })) + .concat($externalResources.map(({ name, schema }) => ({ name, schema }))); + }, +); + export const spansMap: Readable = derived(spans, $spans => keyBy($spans, 'span_id')); export const spanUtilityMaps: Readable = derived(spans, $spans => { diff --git a/src/types/simulation.ts b/src/types/simulation.ts index 3180d65fb6..638aa5481b 100644 --- a/src/types/simulation.ts +++ b/src/types/simulation.ts @@ -7,6 +7,7 @@ import type { Subscription } from './subscribable'; export type PlanDataset = { dataset: { profiles: Profile[] }; + dataset_id: number; offset_from_plan_start: string; }; diff --git a/src/utilities/effects.ts b/src/utilities/effects.ts index a9bc4ec803..4d99804b0f 100644 --- a/src/utilities/effects.ts +++ b/src/utilities/effects.ts @@ -213,7 +213,7 @@ import type { import type { Row, Timeline } from '../types/timeline'; import type { View, ViewDefinition, ViewInsertInput, ViewSlim, ViewUpdateInput } from '../types/view'; import { ActivityDeletionAction } from './activities'; -import { convertToQuery, getSearchParameterNumber, setQueryParam } from './generic'; +import { compare, convertToQuery, getSearchParameterNumber, setQueryParam } from './generic'; import gql, { convertToGQLArray } from './gql'; import { showConfirmModal, @@ -4230,12 +4230,26 @@ const effects = { const { plan_dataset: plan_datasets } = data; if (plan_datasets != null) { let resources: Resource[] = []; + + const profileMap: Set = new Set(); + plan_datasets.sort(({ dataset_id: datasetIdA }, { dataset_id: datasetIdB }) => { + return compare(datasetIdA, datasetIdB, false); + }); + for (const dataset of plan_datasets) { const { dataset: { profiles }, offset_from_plan_start, } = dataset; - const sampledResources: Resource[] = sampleProfiles(profiles, startTimeYmd, offset_from_plan_start); + const uniqueProfiles: Profile[] = profiles.filter(profile => { + if (!profileMap.has(profile.name)) { + profileMap.add(profile.name); + return true; + } + return false; + }); + + const sampledResources: Resource[] = sampleProfiles(uniqueProfiles, startTimeYmd, offset_from_plan_start); resources = [...resources, ...sampledResources]; } return { aborted: false, resources }; diff --git a/src/utilities/gql.ts b/src/utilities/gql.ts index eebcf0ddf6..795321f62f 100644 --- a/src/utilities/gql.ts +++ b/src/utilities/gql.ts @@ -1803,6 +1803,7 @@ const gql = { type } } + dataset_id offset_from_plan_start } } From 86df418d20316ce62d962217a6a36d5a30cfa4e6 Mon Sep 17 00:00:00 2001 From: bduran Date: Tue, 22 Oct 2024 16:23:54 -0700 Subject: [PATCH 13/14] fix styling fix unique list of types --- src/components/ResourceList.svelte | 2 +- src/components/TimelineItemList.svelte | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/ResourceList.svelte b/src/components/ResourceList.svelte index 36912db0a1..c0f984a78a 100644 --- a/src/components/ResourceList.svelte +++ b/src/components/ResourceList.svelte @@ -27,7 +27,7 @@ let uploadFiles: FileList | undefined; let uploadFileInput: HTMLInputElement; - $: resourceDataTypes = $allResourceTypes.map(({ name }) => name); + $: resourceDataTypes = [...new Set($allResourceTypes.map(t => t.schema.type))]; $: if (user !== null && $plan !== null) { hasUploadPermission = featurePermissions.externalResources.canCreate(user, $plan); } diff --git a/src/components/TimelineItemList.svelte b/src/components/TimelineItemList.svelte index 886c9d012d..0e3314d6a3 100644 --- a/src/components/TimelineItemList.svelte +++ b/src/components/TimelineItemList.svelte @@ -400,6 +400,7 @@ .filter-buttons { display: flex; gap: 4px; + position: relative; } .list-items { From ad6778420fe598a6226c55a63c15de3798d47e8f Mon Sep 17 00:00:00 2001 From: bduran Date: Tue, 22 Oct 2024 16:51:27 -0700 Subject: [PATCH 14/14] fix test --- e2e-tests/tests/plan-resources.test.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/e2e-tests/tests/plan-resources.test.ts b/e2e-tests/tests/plan-resources.test.ts index 326ebff542..495df1e071 100644 --- a/e2e-tests/tests/plan-resources.test.ts +++ b/e2e-tests/tests/plan-resources.test.ts @@ -45,7 +45,8 @@ test.afterAll(async () => { test.describe.serial('Plan Resources', () => { test('Uploading external plan dataset file - JSON', async () => { await plan.uploadExternalDatasets('e2e-tests/data/external-dataset.json'); - await expect(plan.panelActivityTypes.getByText('/orientation')).toBeVisible(); + await expect(plan.panelActivityTypes.getByText('/awake')).toBeVisible(); + await expect(plan.panelActivityTypes.getByText('/batteryEnergy')).toBeVisible(); }); test('Uploading external plan dataset file - CSV', async () => {