Skip to content

Commit

Permalink
add file input to constraint form
Browse files Browse the repository at this point in the history
  • Loading branch information
duranb committed Oct 31, 2024
1 parent 3b5ea7f commit c5c77d5
Show file tree
Hide file tree
Showing 7 changed files with 112 additions and 43 deletions.
31 changes: 28 additions & 3 deletions src/components/constraints/ConstraintForm.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
import { goto } from '$app/navigation';
import { base } from '$app/paths';
import { createEventDispatcher } from 'svelte';
import type { DefinitionType } from '../../enums/association';
import { DefinitionType } from '../../enums/association';
import { ConstraintDefinitionType } from '../../enums/constraint';
import { SearchParameters } from '../../enums/searchParameters';
import { constraints } from '../../stores/constraints';
import type { User, UserId } from '../../types/app';
Expand All @@ -17,11 +18,13 @@
export let initialConstraintDefinitionAuthor: UserId | undefined = undefined;
export let initialConstraintDefinitionCode: string | null = '';
export let initialConstraintDefinitionFilename: string | null = null;
export let initialConstraintDescription: string = '';
export let initialConstraintId: number | null = null;
export let initialConstraintName: string = '';
export let initialConstraintPublic: boolean = true;
export let initialConstraintDefinitionTags: Tag[] = [];
export let initialConstraintDefinitionType: ConstraintDefinitionType = ConstraintDefinitionType.EDSL;
export let initialConstraintMetadataTags: Tag[] = [];
export let initialConstraintOwner: UserId = null;
export let initialConstraintRevision: number | null = null;
Expand Down Expand Up @@ -100,13 +103,24 @@
}>,
) {
const {
detail: { definitionCode, definitionTags, description, name, public: isPublic, tags: metadataTags },
detail: {
definitionCode,
definitionFile,
definitionTags,
definitionType,
description,
name,
public: isPublic,
tags: metadataTags,
},
} = event;
const newConstraintId = await effects.createConstraint(
name,
isPublic,
metadataTags.map(({ id }) => ({ tag_id: id })),
definitionType === DefinitionType.CODE ? ConstraintDefinitionType.EDSL : ConstraintDefinitionType.JAR,
definitionCode ?? '',
definitionFile ?? null,
definitionTags.map(({ id }) => ({ tag_id: id })),
user,
description,
Expand All @@ -130,12 +144,14 @@
}>,
) {
const {
detail: { definitionCode, definitionTags },
detail: { definitionCode, definitionFile, definitionTags, definitionType },
} = event;
if (initialConstraintId !== null) {
const definition = await effects.createConstraintDefinition(
initialConstraintId,
definitionType === DefinitionType.CODE ? ConstraintDefinitionType.EDSL : ConstraintDefinitionType.JAR,
definitionCode ?? '',
definitionFile ?? null,
definitionTags.map(({ id }) => ({ tag_id: id })),
user,
);
Expand Down Expand Up @@ -228,12 +244,20 @@
<AssociationForm
allMetadata={$constraints}
defaultDefinitionCode={`export default (): Constraint => {\n\n}\n`}
definitionTypeConfigurations={{
code: { label: 'EDSL' },
file: { accept: '.jar', label: 'JAR File' },
}}
displayName="Constraint"
{hasCreateDefinitionCodePermission}
{hasWriteMetadataPermission}
{hasWriteDefinitionTagsPermission}
initialDefinitionAuthor={initialConstraintDefinitionAuthor}
initialDefinitionType={initialConstraintDefinitionType === ConstraintDefinitionType.EDSL
? DefinitionType.CODE
: DefinitionType.FILE}
initialDefinitionCode={initialConstraintDefinitionCode}
initialDefinitionFileName={initialConstraintDefinitionFilename}
initialDescription={initialConstraintDescription}
initialId={initialConstraintId}
initialName={initialConstraintName}
Expand All @@ -245,6 +269,7 @@
{initialReferenceModelId}
{permissionError}
revisions={constraintRevisions}
showDefinitionTypeSelector={true}
{tags}
tsFiles={constraintsTsFiles}
{mode}
Expand Down
11 changes: 3 additions & 8 deletions src/components/constraints/ConstraintsPanel.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@
async function onDuplicateConstraintInvocation(event: CustomEvent<ConstraintPlanSpecification>) {
const {
detail: { constraint_metadata, constraint_invocation_id, ...constraintPlanSpec },
detail: { constraint_metadata, invocation_id, ...constraintPlanSpec },
} = event;
if ($plan) {
await effects.createConstraintPlanSpecification(constraintPlanSpec, user);
Expand All @@ -165,12 +165,7 @@
detail: { constraint_metadata, specification_id, ...constraintPlanSpec },
} = event;
if ($plan) {
await effects.deleteConstraintInvocations(
$plan,
specification_id,
[constraintPlanSpec.constraint_invocation_id],
user,
);
await effects.deleteConstraintInvocations($plan, specification_id, [constraintPlanSpec.invocation_id], user);
}
}
Expand Down Expand Up @@ -376,7 +371,7 @@
</button>
</div>

{#each filteredConstraints as constraint (constraint.constraint_invocation_id)}
{#each filteredConstraints as constraint (constraint.invocation_id)}
{#if $constraintsMap[constraint.constraint_id]}
<ConstraintListItem
constraint={$constraintsMap[constraint.constraint_id]}
Expand Down
2 changes: 1 addition & 1 deletion src/components/scheduling/goals/SchedulingGoalForm.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -261,8 +261,8 @@
{initialReferenceModelId}
{permissionError}
revisions={goalRevisions}
{tags}
showDefinitionTypeSelector={true}
{tags}
tsFiles={goalsTsFiles}
{mode}
{user}
Expand Down
5 changes: 4 additions & 1 deletion src/components/ui/Association/AssociationForm.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@
);
$: isDefinitionModified =
diffDefinition({ definition: initialDefinitionCode }, { definition: definitionCode }) ||
definitionFiles !== undefined;
(definitionType === DefinitionType.FILE && (definitionFiles?.length ?? 0) > 0);
$: isDefinitionTagsModified = diffTags(initialDefinitionTags || [], definitionTags);
$: hasUpdateDefinitionPermission = hasWriteDefinitionTagsPermission || isDefinitionModified;
$: pageTitle = mode === 'edit' ? 's' : 'New ';
Expand All @@ -168,6 +168,9 @@
owner !== '' &&
definitionCode !== '' &&
name !== '' &&
(mode === 'create' && definitionType === DefinitionType.FILE
? !initialDefinitionFileName && (definitionFiles?.length ?? 0) > 0
: true) &&
(isMetadataModified || (isDefinitionTagsModified && hasUpdateDefinitionPermission) || isDefinitionModified);
$: saveButtonClass = saveButtonEnabled ? 'primary' : 'secondary';
$: if (mode === 'edit' && (isMetadataModified || isDefinitionModified)) {
Expand Down
59 changes: 37 additions & 22 deletions src/routes/constraints/edit/[id]/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import { constraintMetadata, constraintMetadataId } from '../../../../stores/constraints';
import { tags } from '../../../../stores/tags';
import type { ConstraintDefinition, ConstraintMetadataVersionDefinition } from '../../../../types/constraint';
import effects from '../../../../utilities/effects';
import { getSearchParameterNumber, setQueryParam } from '../../../../utilities/generic';
import type { PageData } from './$types';
Expand All @@ -18,12 +19,16 @@
getSearchParameterNumber(SearchParameters.REVISION, $page.url.searchParams) ??
data.initialConstraint.versions[0].revision;
let constraintDefinition: Pick<ConstraintDefinition, 'author' | 'definition' | 'revision' | 'tags'> =
data.initialConstraint.versions.find(
({ revision }) => revision === constraintRevision,
) as ConstraintMetadataVersionDefinition;
let constraintDefinition: Pick<
ConstraintDefinition,
'author' | 'definition' | 'revision' | 'tags' | 'type' | 'uploaded_jar_id'
> = data.initialConstraint.versions.find(
({ revision }) => revision === constraintRevision,
) as ConstraintMetadataVersionDefinition;
let constraintDefinitionCode = constraintDefinition?.definition;
let constraintDefinitionAuthor = constraintDefinition?.author;
let constraintDefinitionFilename: string | null = null;
let constraintDefinitionType = constraintDefinition.type;
let constraintDescription = data.initialConstraint.description;
let constraintId = data.initialConstraint.id;
let constraintName = data.initialConstraint.name;
Expand All @@ -35,24 +40,32 @@
let referenceModelId: number | null = null;
$: $constraintMetadataId = data.initialConstraint.id;
$: if ($constraintMetadata != null && $constraintMetadata.id === $constraintMetadataId) {
constraintDefinition = $constraintMetadata.versions.find(
({ revision }) => revision === constraintRevision,
) as ConstraintMetadataVersionDefinition;
if (constraintDefinition != null) {
constraintDefinitionAuthor = constraintDefinition?.author;
constraintDefinitionCode = constraintDefinition?.definition;
constraintDefinitionTags = constraintDefinition?.tags.map(({ tag }) => tag);
}
$: (async () => {
if ($constraintMetadata != null && $constraintMetadata.id === $constraintMetadataId) {
constraintDefinition = $constraintMetadata.versions.find(
({ revision }) => revision === constraintRevision,
) as ConstraintMetadataVersionDefinition;
if (constraintDefinition != null) {
constraintDefinitionAuthor = constraintDefinition?.author;
constraintDefinitionType = constraintDefinition?.type;
constraintDefinitionCode = constraintDefinition?.definition;
constraintDefinitionTags = constraintDefinition?.tags.map(({ tag }) => tag);
if (constraintDefinition.uploaded_jar_id !== null) {
constraintDefinitionFilename = await effects.getFileName(constraintDefinition.uploaded_jar_id, data.user);
} else {
constraintDefinitionFilename = null;
}
}
constraintDescription = $constraintMetadata.description;
constraintId = $constraintMetadata.id;
constraintName = $constraintMetadata.name;
constraintPublic = $constraintMetadata.public;
constraintMetadataTags = $constraintMetadata.tags.map(({ tag }) => tag);
constraintOwner = $constraintMetadata.owner;
constraintRevisions = $constraintMetadata.versions.map(({ revision }) => revision);
}
constraintDescription = $constraintMetadata.description;
constraintId = $constraintMetadata.id;
constraintName = $constraintMetadata.name;
constraintPublic = $constraintMetadata.public;
constraintMetadataTags = $constraintMetadata.tags.map(({ tag }) => tag);
constraintOwner = $constraintMetadata.owner;
constraintRevisions = $constraintMetadata.versions.map(({ revision }) => revision);
}
})();
function onRevisionSelect(event: CustomEvent<number>) {
const { detail: revision } = event;
Expand All @@ -79,8 +92,10 @@

<ConstraintForm
initialConstraintDefinitionAuthor={constraintDefinitionAuthor}
initialConstraintDefinitionCode={constraintDefinitionCode ?? ''}
initialConstraintDescription={constraintDescription}
initialConstraintDefinitionType={constraintDefinitionType}
initialConstraintDefinitionCode={constraintDefinitionCode ?? ''}
initialConstraintDefinitionFilename={constraintDefinitionFilename}
initialConstraintId={constraintId}
initialConstraintName={constraintName}
initialConstraintPublic={constraintPublic}
Expand Down
12 changes: 8 additions & 4 deletions src/types/constraint.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,12 @@ export type ConstraintDefinition = BaseDefinition & {
constraint_id: number;
parameter_schema?: ValueSchema;
type: ConstraintDefinitionType;
uploaded_jar_id: number | null;
};

export type ConstraintMetadataVersionDefinition = Pick<
ConstraintDefinition,
'author' | 'definition' | 'revision' | 'tags'
'author' | 'definition' | 'revision' | 'tags' | 'type' | 'uploaded_jar_id'
>;

export type ConstraintMetadata = BaseMetadata<ConstraintDefinition>;
Expand All @@ -32,14 +33,14 @@ export type ConstraintModelSpecification = {
export type ConstraintPlanSpecification = {
arguments: any;
constraint_id: number;
constraint_invocation_id?: number;
constraint_metadata:
| (Pick<ConstraintMetadata, 'name' | 'owner' | 'public'> & {
versions: Pick<ConstraintDefinition, 'parameter_schema' | 'revision' | 'type'>[];
})
| null;
constraint_revision: number | null;
enabled: boolean;
invocation_id?: number;
plan_id: number;
specification_id: number;
// constraint_definition: ConstraintDefinition;
Expand All @@ -48,9 +49,12 @@ export type ConstraintPlanSpecification = {

export type ConstraintModelSpecInsertInput = Omit<ConstraintModelSpecification, 'constraint_metadata'>;
export type ConstraintPlanSpecSetInput = Omit<ConstraintPlanSpecification, 'constraint_metadata'>;
export type ConstraintPlanSpecInsertInput = Omit<ConstraintPlanSpecSetInput, 'constraint_invocation_id'>;
export type ConstraintPlanSpecInsertInput = Omit<ConstraintPlanSpecSetInput, 'invocation_id'>;

export type ConstraintDefinitionInsertInput = Pick<ConstraintDefinition, 'constraint_id' | 'definition'> & {
export type ConstraintDefinitionInsertInput = Pick<
ConstraintDefinition,
'constraint_id' | 'definition' | 'type' | 'uploaded_jar_id'
> & {
tags: {
data: ConstraintTagsInsertInput[];
};
Expand Down
35 changes: 31 additions & 4 deletions src/utilities/effects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
type ParameterDictionary as AmpcsParameterDictionary,
} from '@nasa-jpl/aerie-ampcs';
import { get } from 'svelte/store';
import { ConstraintDefinitionType } from '../enums/constraint';
import { DictionaryTypes } from '../enums/dictionaryTypes';
import { SchedulingDefinitionType } from '../enums/scheduling';
import { SearchParameters } from '../enums/searchParameters';
Expand Down Expand Up @@ -604,7 +605,9 @@ const effects = {
name: string,
isPublic: boolean,
metadataTags: ConstraintTagsInsertInput[],
definitionType: ConstraintDefinitionType,
definition: string,
file: File | null,
definitionTags: ConstraintTagsInsertInput[],
user: User | null,
description?: string,
Expand All @@ -614,6 +617,15 @@ const effects = {
throwPermissionError('create a constraint');
}

let jarId: number | null = null;
let codeDefinition: string | null = null;

if (definitionType === ConstraintDefinitionType.EDSL) {
codeDefinition = definition;
} else if (definitionType === ConstraintDefinitionType.JAR && file) {
jarId = await effects.uploadFile(file, user);
}

const constraintInsertInput: ConstraintInsertInput = {
...(description ? { description } : {}),
name,
Expand All @@ -624,10 +636,12 @@ const effects = {
versions: {
data: [
{
definition,
definition: codeDefinition,
tags: {
data: definitionTags,
},
type: definitionType,
uploaded_jar_id: jarId,
},
],
},
Expand Down Expand Up @@ -655,7 +669,9 @@ const effects = {

async createConstraintDefinition(
constraintId: number,
definitionType: ConstraintDefinitionType,
definition: string,
file: File | null,
definitionTags: ConstraintTagsInsertInput[],
user: User | null,
): Promise<Pick<ConstraintDefinition, 'constraint_id' | 'definition' | 'revision'> | null> {
Expand All @@ -664,12 +680,23 @@ const effects = {
throwPermissionError('create a constraint');
}

let jarId: number | null = null;
let codeDefinition: string | null = null;

if (definitionType === ConstraintDefinitionType.EDSL) {
codeDefinition = definition;
} else if (definitionType === ConstraintDefinitionType.JAR && file !== null) {
jarId = await effects.uploadFile(file, user);
}

const constraintDefinitionInsertInput: ConstraintDefinitionInsertInput = {
constraint_id: constraintId,
definition,
definition: codeDefinition,
tags: {
data: definitionTags,
},
type: definitionType,
uploaded_jar_id: jarId,
};
const data = await reqHasura<ConstraintDefinition>(
gql.CREATE_CONSTRAINT_DEFINITION,
Expand Down Expand Up @@ -5665,17 +5692,17 @@ const effects = {
const {
enabled,
constraint_id: constraintId,
constraint_invocation_id,
invocation_id,
constraint_revision: revision,
} = constraintPlanSpecification;

const { updateConstraintPlanSpecification } = await reqHasura(
gql.UPDATE_CONSTRAINT_PLAN_SPECIFICATION,
{
arguments: constraintPlanSpecification.arguments,
constraint_invocation_id,
enabled,
id: constraintId,
invocation_id,
planId: plan.id,
revision,
},
Expand Down

0 comments on commit c5c77d5

Please sign in to comment.