Skip to content
4 changes: 2 additions & 2 deletions e2e-tests/fixtures/global.setup.jar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,10 @@ setup.skip(jarDataExists, 'cached JAR data exists');
setup('upload test JAR and save shared test data', async () => {
const api = new AerieApi();
await api.login('test', 'test');
const jarId = await api.uploadFile('e2e-tests/data/banananation-develop.jar');
const definitionFileId = await api.uploadFile('e2e-tests/data/banananation-develop.jar');

const sharedData: SharedTestData = {
jarId,
definitionFileId,
};

// Ensure the directory exists
Expand Down
4 changes: 2 additions & 2 deletions e2e-tests/tests/plan-metadata.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,12 @@ test.beforeAll(async ({ browser }) => {
await apiA.login('userA', 'test');

// Use pre-uploaded JAR from global setup
const { jarId } = getSharedTestData();
const { definitionFileId } = getSharedTestData();

// Create model via API (much faster and more reliable than UI)
const modelName = uniqueNamesGenerator({ dictionaries: [adjectives, colors, animals] });
const model = await apiA.createModel({
jar_id: jarId,
definition_file_id: definitionFileId,
mission: 'test',
name: modelName,
version: '1.0.0',
Expand Down
6 changes: 3 additions & 3 deletions e2e-tests/utilities/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export interface ApiUser {
* Shared test data written during global setup and read by tests.
*/
export interface SharedTestData {
jarId: number;
definitionFileId: number;
}

/**
Expand Down Expand Up @@ -616,12 +616,12 @@ export async function setupTest(browser: Browser, options: SetupOptions = {}): P
await api.login(user, 'test');

// Use pre-uploaded JAR from global setup
const { jarId } = getSharedTestData();
const { definitionFileId } = getSharedTestData();

// Create model via API
const modelName = options.modelName ?? uniqueNamesGenerator({ dictionaries: [adjectives, colors, animals] });
const model = await api.createModel({
jar_id: jarId,
definition_file_id: definitionFileId,
mission: 'test',
name: modelName,
version: '1.0.0',
Expand Down
14 changes: 8 additions & 6 deletions src/components/ActivityList.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@
import CloseIcon from '@nasa-jpl/stellar/icons/close.svg?component';
import UploadIcon from '@nasa-jpl/stellar/icons/upload.svg?component';
import { CirclePlus } from 'lucide-svelte';
import { PlanStatusMessages } from '../enums/planStatusMessages';
import { directiveBuilderIsVisible } from '../stores/directiveBuilder';
import { plan, planModelActivityTypes, subsystemTags } from '../stores/plan';
import { plan, planModelActivityTypes, planReadOnly, subsystemTags } from '../stores/plan';
import type { ActivityType } from '../types/activity';
import type { User } from '../types/app';
import type { TimelineItemType } from '../types/timeline';
Expand Down Expand Up @@ -63,6 +64,7 @@
{getFilterValueFromItem}
filterOptions={$subsystemTags.map(s => ({ color: s.color || '', label: s.name, value: s.id }))}
filterName="Subsystem"
planReadOnly={$planReadOnly}
{hasCreatePermission}
>
<div slot="header" class="upload-container" hidden={!isUploadVisible}>
Expand Down Expand Up @@ -103,17 +105,17 @@
class="st-button secondary"
on:click={onShowUpload}
use:permissionHandler={{
hasPermission: hasCreatePermission,
permissionError: uploadPermissionError,
hasPermission: hasCreatePermission && !$planReadOnly,
permissionError: $planReadOnly ? PlanStatusMessages.READ_ONLY : uploadPermissionError,
}}
use:tooltip={{ content: 'Upload Activities' }}
use:tooltip={{ content: 'Upload Activities', disabled: !hasCreatePermission || $planReadOnly }}
>
<UploadIcon />
</button>
<div
use:permissionHandler={{
hasPermission: hasCreatePermission,
permissionError: createPermissionError,
hasPermission: hasCreatePermission && !$planReadOnly,
permissionError: $planReadOnly ? PlanStatusMessages.READ_ONLY : createPermissionError,
}}
>
<Button
Expand Down
14 changes: 11 additions & 3 deletions src/components/TimelineItemList.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import ChevronDownIcon from '@nasa-jpl/stellar/icons/chevron_down.svg?component';
import { capitalize } from 'lodash-es';
import { CirclePlus, Filter, GripVertical } from 'lucide-svelte';
import { PlanStatusMessages } from '../enums/planStatusMessages';
import { directiveBuilderIsVisible, updateDirectiveBuilder } from '../stores/directiveBuilder';
import { view, viewAddFilterToRow } from '../stores/views';
import type {
Expand Down Expand Up @@ -40,6 +41,7 @@
export let filterName: string = 'Filter';
export let getFilterValueFromItem: (item: TimelineItemType) => string | number;
export let loading: boolean = false;
export let planReadOnly: boolean = false;
export let hasCreatePermission: boolean = true;

let activeItemIndex: number = -1;
Expand Down Expand Up @@ -319,10 +321,16 @@
</div>
{#if typeName === 'activity'}
<div
use:tooltip={{ content: 'Add New Directive', placement: 'top' }}
use:permissionHandler={{
hasPermission: hasCreatePermission,
permissionError: 'You do not have permission to create activities.',
hasPermission: hasCreatePermission && !planReadOnly,
permissionError: planReadOnly
? PlanStatusMessages.READ_ONLY
: 'You do not have permission to create activities.',
}}
use:tooltip={{
content: 'Add New Directive',
disabled: !hasCreatePermission || planReadOnly,
placement: 'top',
}}
class="flex items-center"
>
Expand Down
8 changes: 4 additions & 4 deletions src/components/activity/ActivityDirectiveForm.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import { activityArgumentDefaultsMap } from '../../stores/activities';
import { activityErrorRollupsMap, activityValidationErrors } from '../../stores/console';
import { field } from '../../stores/form';
import { plan, planReadOnly } from '../../stores/plan';
import { plan, planIsLocked } from '../../stores/plan';
import { plugins } from '../../stores/plugins';
import type {
ActivityDirective,
Expand Down Expand Up @@ -92,9 +92,9 @@

$: if (user !== null && $plan !== null) {
hasUpdatePermission =
featurePermissions.activityDirective.canUpdate(user, $plan, activityDirective) && !$planReadOnly;
featurePermissions.activityDirective.canUpdate(user, $plan, activityDirective) && !$planIsLocked;
}
$: updatePermissionError = $planReadOnly
$: updatePermissionError = $planIsLocked
? PlanStatusMessages.READ_ONLY
: 'You do not have permission to update this activity';
$: highlightKeysMap = keyByBoolean(highlightKeys);
Expand Down Expand Up @@ -597,7 +597,7 @@
anchorId={revision ? revision.anchor_id : activityDirective.anchor_id}
disabled={!editable}
{highlightKeysMap}
planReadOnly={$planReadOnly}
planReadOnly={$planIsLocked}
isAnchoredToStart={revision ? revision.anchored_to_start : activityDirective.anchored_to_start}
startOffset={revision ? revision.start_offset : activityDirective.start_offset}
on:updateAnchor={updateAnchor}
Expand Down
4 changes: 2 additions & 2 deletions src/components/activity/ActivityDirectivesTablePanel.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
import { InvalidDate } from '../../constants/time';
import { activityDirectivesMap, selectActivity, selectedActivityDirectiveId } from '../../stores/activities';
import { activityErrorRollupsMap } from '../../stores/console';
import { maxTimeRange, plan, planModelActivityTypes, planReadOnly, viewTimeRange } from '../../stores/plan';
import { maxTimeRange, plan, planIsLocked, planModelActivityTypes, viewTimeRange } from '../../stores/plan';
import { plugins } from '../../stores/plugins';
import { spansMap, spanUtilityMaps } from '../../stores/simulation';
import { view, viewTogglePanel, viewUpdateActivityDirectivesTable } from '../../stores/views';
Expand Down Expand Up @@ -468,7 +468,7 @@
plan={$plan}
spansMap={$spansMap}
spanUtilityMaps={$spanUtilityMaps}
planReadOnly={$planReadOnly}
planReadOnly={$planIsLocked}
{user}
on:columnMoved={onColumnMoved}
on:columnPinned={onColumnPinned}
Expand Down
6 changes: 3 additions & 3 deletions src/components/activity/ActivityFormPanel.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@
import {
activityEditingLocked,
plan,
planIsLocked,
planModelActivityTypes,
planModelId,
planReadOnly,
setActivityEditingLocked,
} from '../../stores/plan';
import { selectedSpan, simulationDatasetId, spanUtilityMaps, spansMap } from '../../stores/simulation';
Expand Down Expand Up @@ -52,12 +52,12 @@
let previewRevision: ActivityDirectiveRevision | undefined;
let selectedParameterName: string | null = null;

$: deletePermissionError = $planReadOnly
$: deletePermissionError = $planIsLocked
? PlanStatusMessages.READ_ONLY
: 'You do not have permission to delete this activity';
$: if (user !== null && $plan !== null && $selectedActivityDirective !== null) {
hasDeletePermission =
featurePermissions.activityDirective.canDelete(user, $plan, $selectedActivityDirective) && !$planReadOnly;
featurePermissions.activityDirective.canDelete(user, $plan, $selectedActivityDirective) && !$planIsLocked;
}

// Auto close the changelog and clear revision preview state whenever the selected activity changes
Expand Down
12 changes: 6 additions & 6 deletions src/components/activity/ActivityPresetInput.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

<script lang="ts">
import { createEventDispatcher } from 'svelte';
import { planReadOnly } from '../../stores/plan';
import { planIsLocked } from '../../stores/plan';
import { gqlSubscribable } from '../../stores/subscribable';
import type { ActivityDirective, ActivityPreset } from '../../types/activity';
import type { User } from '../../types/app';
Expand Down Expand Up @@ -62,15 +62,15 @@
value: activityPreset.id,
}));

hasAssignPermission = featurePermissions.activityPresets.canUnassign(user, plan) && !$planReadOnly;
hasCreatePermission = featurePermissions.activityPresets.canCreate(user, plan) && !$planReadOnly;
hasAssignPermission = featurePermissions.activityPresets.canUnassign(user, plan) && !$planIsLocked;
hasCreatePermission = featurePermissions.activityPresets.canCreate(user, plan) && !$planIsLocked;

const selectedPreset = $activityPresets.find(
activityPreset => activityPreset.id === activityDirective?.applied_preset?.preset_id,
);
if (selectedPreset !== undefined) {
hasDeletePermission = featurePermissions.activityPresets.canDelete(user, plan, selectedPreset) && !$planReadOnly;
hasUpdatePermission = featurePermissions.activityPresets.canUpdate(user, plan, selectedPreset) && !$planReadOnly;
hasDeletePermission = featurePermissions.activityPresets.canDelete(user, plan, selectedPreset) && !$planIsLocked;
hasUpdatePermission = featurePermissions.activityPresets.canUpdate(user, plan, selectedPreset) && !$planIsLocked;
}
}

Expand Down Expand Up @@ -115,7 +115,7 @@
{options}
optionLabel="preset"
placeholder="None"
planReadOnly={$planReadOnly}
planReadOnly={$planIsLocked}
selectedOptionValue={activityDirective?.applied_preset?.preset_id}
showPlaceholderOption={hasAssignPermission}
on:deleteOption={onDeletePreset}
Expand Down
18 changes: 9 additions & 9 deletions src/components/constraints/ConstraintsPanel.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
setConstraintVisibility,
} from '../../stores/constraints';
import { field } from '../../stores/form';
import { plan, planModelId, planReadOnly, viewTimeRange } from '../../stores/plan';
import { plan, planIsLocked, planModelId, viewTimeRange } from '../../stores/plan';
import { plugins } from '../../stores/plugins';
import { simulationStatus } from '../../stores/simulation';
import type { User } from '../../types/app';
Expand Down Expand Up @@ -91,9 +91,9 @@
} else {
endTime = '';
}
hasSpecEditPermission = featurePermissions.constraintsPlanSpec.canUpdate(user, $plan) && !$planReadOnly;
hasSpecEditPermission = featurePermissions.constraintsPlanSpec.canUpdate(user, $plan) && !$planIsLocked;

editPermissionError = $planReadOnly
editPermissionError = $planIsLocked
? PlanStatusMessages.READ_ONLY
: 'You do not have permission to edit constraints for this plan.';
deletePermissionError = hasSpecEditPermission
Expand Down Expand Up @@ -399,9 +399,9 @@
permissionHandler,
{
hasPermission: $plan
? featurePermissions.constraintRuns.canCreate(user, $plan, $plan.model) && !$planReadOnly
? featurePermissions.constraintRuns.canCreate(user, $plan, $plan.model) && !$planIsLocked
: false,
permissionError: $planReadOnly
permissionError: $planIsLocked
? PlanStatusMessages.READ_ONLY
: 'You do not have permission to run constraint checks',
},
Expand All @@ -421,9 +421,9 @@
permissionHandler,
{
hasPermission: $plan
? featurePermissions.constraintRuns.canCreate(user, $plan, $plan.model) && !$planReadOnly
? featurePermissions.constraintRuns.canCreate(user, $plan, $plan.model) && !$planIsLocked
: false,
permissionError: $planReadOnly
permissionError: $planIsLocked
? PlanStatusMessages.READ_ONLY
: 'You do not have permission to run constraint checks',
},
Expand All @@ -450,8 +450,8 @@
name="manage-constraints"
class="st-button secondary"
use:permissionHandler={{
hasPermission: $plan ? featurePermissions.constraints.canCreate(user) && !$planReadOnly : false,
permissionError: $planReadOnly
hasPermission: $plan ? featurePermissions.constraints.canCreate(user) && !$planIsLocked : false,
permissionError: $planIsLocked
? PlanStatusMessages.READ_ONLY
: 'You do not have permission to update constraints',
}}
Expand Down
Loading
Loading