Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Manage Default View for Model #1554

Merged
merged 7 commits into from
Dec 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions e2e-tests/fixtures/Model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export class Model {
newPlanButton: Locator;
saveButton: Locator;
versionInput: Locator;
viewInput: Locator;

constructor(
public page: Page,
Expand Down Expand Up @@ -109,6 +110,17 @@ export class Model {
await expect(this.associationTable).not.toBeVisible();
}

async updateDefaultView(viewName: string) {
await this.viewInput.selectOption('None');
const matchingOption = await this.viewInput
.getByRole('option')
.getByText(viewName, { exact: false })
.elementHandle();
expect(matchingOption).toBeDefined();
await this.viewInput.selectOption(matchingOption);
expect(await this.viewInput.inputValue()).toEqual(await matchingOption?.getAttribute('value'));
}

async updateDescription(modelDescription: string) {
await this.descriptionInput.click();
await this.descriptionInput.fill(modelDescription);
Expand All @@ -131,6 +143,7 @@ export class Model {
this.libraryRadioButton = page.getByRole('radio', { name: 'Library' });
this.modelRadioButton = page.getByRole('radio', { exact: true, name: 'Model' });
this.nameInput = page.locator('input[name="name"]');
this.viewInput = page.locator('select[name="view"]');
this.newPlanButton = page.getByRole('button', { name: 'New plan with model' });
this.versionInput = page.locator('input[name="version"]');
this.associationTable = page.getByRole('treegrid');
Expand Down
26 changes: 25 additions & 1 deletion e2e-tests/tests/model.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,24 @@ import { adjectives, animals, colors, uniqueNamesGenerator } from 'unique-names-
import { Constraints } from '../fixtures/Constraints.js';
import { Model } from '../fixtures/Model.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';
import { View } from '../fixtures/View.js';

let constraints: Constraints;
let context: BrowserContext;
let models: Models;
let model: Model;
let page: Page;
let plan: Plan;
let plans: Plans;
let schedulingConditions: SchedulingConditions;
let schedulingGoals: SchedulingGoals;
let schedulingGoalName: string;
let view: View;
let viewName: string;

const checkboxSelector = 'Press SPACE to toggle cell';

Expand All @@ -22,9 +29,12 @@ test.beforeAll(async ({ baseURL, browser }) => {
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);
view = new View(page);
model = new Model(page, models, constraints, schedulingGoals, schedulingConditions);
schedulingGoalName = uniqueNamesGenerator({ dictionaries: [adjectives, colors, animals] });
await constraints.gotoNew();
Expand All @@ -35,11 +45,21 @@ test.beforeAll(async ({ baseURL, browser }) => {
await schedulingGoals.createSchedulingGoal(baseURL, schedulingGoalName);
await models.goto();
await models.createModel(baseURL);
await plans.goto();
await plans.createPlan();
await plan.goto();
viewName = await view.createViewName();
await view.createView(viewName);
await model.goto();
});

test.afterAll(async () => {
await model.deleteModel();
await plan.goto();
await view.deleteView(viewName);
await plans.goto();
await plans.deletePlan();
await models.goto();
await models.deleteModel();
await constraints.goto();
await constraints.deleteConstraint();
await schedulingConditions.goto();
Expand All @@ -63,6 +83,10 @@ test.describe.serial('Model', () => {
await model.updateVersion('2.0.0');
});

test('Should be able to update the default view for a model', async () => {
await model.updateDefaultView(viewName);
});

test('Should be able to add a constraint to the model and specify a version', async () => {
await model.switchToConstraints();
await model.switchToLibraryView();
Expand Down
25 changes: 20 additions & 5 deletions src/components/model/ModelForm.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import { createEventDispatcher } from 'svelte';
import type { User, UserId } from '../../types/app';
import type { ModelLog, ModelSlim } from '../../types/model';
import type { ViewSlim } from '../../types/view';
import effects from '../../utilities/effects';
import { getModelStatusRollup } from '../../utilities/model';
import { permissionHandler } from '../../utilities/permissionHandler';
Expand All @@ -19,18 +20,21 @@
export let initialModelName: string = '';
export let initialModelOwner: UserId | undefined;
export let initialModelVersion: string | undefined;
export let initialModelDefaultViewId: number | null | undefined;
export let activityTypeLogs: ModelLog[] | undefined;
export let modelParameterLogs: ModelLog[] | undefined;
export let resourceTypeLogs: ModelLog[] | undefined;
export let modelId: number | undefined;
export let createdAt: string | undefined;
export let user: User | null;
export let users: UserId[] = [];
export let views: ViewSlim[] = [];

const dispatch = createEventDispatcher<{
createPlan: number;
deleteModel: void;
hasModelChanged: {
default_view_id: number | null;
description: string;
name: string;
owner: UserId;
Expand Down Expand Up @@ -60,6 +64,7 @@
$: name = initialModelName;
$: owner = initialModelOwner ?? null;
$: version = initialModelVersion ?? '';
$: viewId = initialModelDefaultViewId ?? null;
$: modelLogs = {
refresh_activity_type_logs: activityTypeLogs ?? [],
refresh_model_parameter_logs: modelParameterLogs ?? [],
Expand All @@ -83,6 +88,7 @@
}

$: dispatch('hasModelChanged', {
default_view_id: viewId,
description,
name,
owner,
Expand Down Expand Up @@ -131,7 +137,7 @@
<div class="model-form-container">
<div class="inputs">
<Input layout="inline">
<label for="name">Model name</label>
<label for="name">Model Name</label>
<input
class="st-input w-100"
name="name"
Expand All @@ -144,11 +150,11 @@
/>
</Input>
<Input layout="inline">
<label for="id">Model id</label>
<label for="id">Model ID</label>
<input class="st-input w-100" disabled name="id" value={modelId ?? ''} />
</Input>
<Input layout="inline">
<label for="description">Model description</label>
<label for="description">Model Description</label>
<textarea
class="st-input w-100"
name="description"
Expand All @@ -160,7 +166,7 @@
/>
</Input>
<Input layout="inline">
<label for="version">Model version</label>
<label for="version">Model Version</label>
<input
class="st-input w-100"
name="version"
Expand Down Expand Up @@ -192,6 +198,15 @@
on:delete={onClearOwner}
/>
</Input>
<Input layout="inline">
<label for="view">Default View</label>
<select name="view" class="st-select w-100" bind:value={viewId}>
<option value={null}>None</option>
{#each views as viewOption}
<option value={viewOption.id}>{viewOption.name} (ID: {viewOption.id})</option>
{/each}
</select>
</Input>
{#if createdAt}
<Input layout="inline">
<label use:tooltip={{ content: 'Date Created', placement: 'top' }} for="createdAt">Date Created</label>
Expand All @@ -201,7 +216,7 @@
{#if modelId}
<Input layout="inline">
<div class="model-jar-label">
<label class="model-metadata-item-label" for="status">Jar file status</label>
<label class="model-metadata-item-label" for="status">Jar File Status</label>
{#if modelHasExtractionError}
<button
class="icon-button"
Expand Down
17 changes: 12 additions & 5 deletions src/components/model/Models.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,9 @@
];
}
$: selectedModel = $models.find(({ id }) => id === selectedModelId) ?? null;
$: selectedModelDefaultViewName = selectedModel?.view
? `${selectedModel.view.name} (ID: ${selectedModel.view.id})`
: 'None';
$: if (selectedModel) {
const { activityLogStatus, parameterLogStatus, resourceLogStatus } = getModelStatusRollup(selectedModel);

Expand Down Expand Up @@ -271,7 +274,7 @@
<div class="model-metadata">
<fieldset>
<Input layout="inline">
<label class="model-metadata-item-label" for="name">Model name</label>
<label class="model-metadata-item-label" for="name">Model Name</label>
<input
disabled
class="st-input w-100"
Expand All @@ -281,21 +284,25 @@
/>
</Input>
<Input layout="inline">
<label class="model-metadata-item-label" for="id">Model id</label>
<label class="model-metadata-item-label" for="id">Model ID</label>
<input disabled class="st-input w-100" name="id" value={selectedModel.id} />
</Input>
<Input layout="inline">
<label class="model-metadata-item-label" for="description">Description</label>
<label class="model-metadata-item-label" for="description">Model Description</label>
<textarea disabled class="st-input w-100" name="description" value={selectedModel.description} />
</Input>
<Input layout="inline">
<label class="model-metadata-item-label" for="version">Model version</label>
<label class="model-metadata-item-label" for="version">Model Version</label>
<input disabled class="st-input w-100" name="version" value={selectedModel.version} />
</Input>
<Input layout="inline">
<label class="model-metadata-item-label" for="owner">Owner</label>
<input disabled class="st-input w-100" name="owner" value={selectedModel.owner} />
</Input>
<Input layout="inline">
<label class="model-metadata-item-label" for="defaultView">Default View</label>
<input disabled class="st-input w-100" name="defaultView" value={selectedModelDefaultViewName} />
</Input>
<Input layout="inline">
<label class="model-metadata-item-label" for="created">Date Created</label>
<input
Expand All @@ -307,7 +314,7 @@
</Input>
<Input layout="inline">
<div class="model-jar-label">
<label class="model-metadata-item-label" for="status">Jar file status</label>
<label class="model-metadata-item-label" for="status">Jar File Status</label>
{#if modelHasExtractionError}
<button
class="icon-button"
Expand Down
1 change: 1 addition & 0 deletions src/components/plan/PlanMergeReview.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ const mockInitialPlan: Plan = {
model: {
constraint_specification: [],
created_at: '2023-02-16T00:00:00',
default_view_id: 0,
id: 1,
jar_id: 1,
mission: '',
Expand Down
7 changes: 7 additions & 0 deletions src/routes/models/[id]/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@
import { initialModel, model, resetModelStores } from '../../../stores/model';
import { schedulingConditions, schedulingGoals } from '../../../stores/scheduling';
import { users } from '../../../stores/user';
import { views } from '../../../stores/views';
import type { User, UserId } from '../../../types/app';
import type { ConstraintModelSpec, ConstraintModelSpecInsertInput } from '../../../types/constraint';
import type {
Expand Down Expand Up @@ -118,12 +119,14 @@
let hasModelChanged: boolean = false;
let metadataList: Pick<BaseMetadata, 'id' | 'name' | 'public' | 'versions'>[] = [];
let modelMetadata: {
default_view_id: number | null;
description?: string;
name: string;
owner: UserId;
version: string;
} | null = null;
let initialModelMetadata: {
default_view_id: number | null;
description?: string;
name: string;
owner: UserId;
Expand All @@ -146,6 +149,7 @@
}
$: if ($model) {
initialModelMetadata = {
default_view_id: $model.default_view_id,
description: $model.description,
name: $model.name,
owner: $model.owner,
Expand Down Expand Up @@ -299,6 +303,7 @@

function onModelMetadataChange(
event: CustomEvent<{
default_view_id: number | null;
description: string;
name: string;
owner: UserId;
Expand Down Expand Up @@ -668,13 +673,15 @@
initialModelName={$model?.name}
initialModelOwner={$model?.owner}
initialModelVersion={$model?.version}
initialModelDefaultViewId={$model?.default_view_id}
activityTypeLogs={$model?.refresh_activity_type_logs}
modelParameterLogs={$model?.refresh_model_parameter_logs}
resourceTypeLogs={$model?.refresh_resource_type_logs}
modelId={$model?.id}
createdAt={$model?.created_at}
user={data.user}
users={$users ?? []}
views={$views ?? []}
on:createPlan={onCreatePlanWithModel}
on:deleteModel={onDeleteModel}
on:hasModelChanged={onModelMetadataChange}
Expand Down
7 changes: 4 additions & 3 deletions src/types/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@ import type { UserId } from './app';
import type { ConstraintModelSpec } from './constraint';
import type { ParametersMap } from './parameter';
import type { SchedulingConditionModelSpecification, SchedulingGoalModelSpecification } from './scheduling';
import type { View } from './view';
import type { View, ViewSlim } from './view';

export type Model = ModelSchema;

export type ModelInsertInput = Pick<Model, 'description' | 'jar_id' | 'mission' | 'name' | 'version'>;
export type ModelSetInput = Pick<Model, 'description' | 'mission' | 'name' | 'owner' | 'version'>;
export type ModelSetInput = Pick<Model, 'default_view_id' | 'description' | 'mission' | 'name' | 'owner' | 'version'>;

export type ModelStatus = 'extracting' | 'complete' | 'error' | 'none';
export type ModelStatusRollup = {
Expand Down Expand Up @@ -36,6 +36,7 @@ export type ModelLog = {
export type ModelSchema = {
constraint_specification: ConstraintModelSpec[];
created_at: string;
default_view_id: number | null;
description?: string;
id: number;
jar_id: number;
Expand Down Expand Up @@ -66,4 +67,4 @@ export type ModelSlim = Pick<
| 'refresh_model_parameter_logs'
| 'refresh_resource_type_logs'
| 'version'
>;
> & { view: ViewSlim | null };
Loading
Loading