Skip to content

Commit

Permalink
Feature/channel dictionary hookup (#1244)
Browse files Browse the repository at this point in the history
* Moved sequence adaptation uploading to the command dictionary page, started adding support for uploading parameter and channel dictionaries

* Fixed issues with uploading command dictionaries and sequence adaptations

* Added support for parsing channel and parameter dictionaries

* Fixed the form builder from showing on the sequence select screen, fixed a problem with the seq page not loading

* First pass at adding parcels

* Changed sequence editing to use parcels rather than command dictionaries

* Hooked up sequence adaptation id to parcels

* Added support for a single parameter dictionary

* Added support for multiple parameter dictionaries

* Added a new shared component to support dictionary management

* Updated the DictionaryTable component to include editing

* Finished adding channel dictionaries

* Fixed an issue with the initial channel dictionary not being set for a parcel

* Fixed some errors caused by the rebase

* Fixed the parcel to parameter dictionary mapping to support multiple dictionaries

* Plumbed the channel dictionary into the sequence editor

* wip channel integration (#1245)

* wip channel integration

* Fixed an issue with channel dictionary loading that was causing an infinite loop

---------

Co-authored-by: Cody Hansen <[email protected]>

---------

Co-authored-by: Chet Joswig <[email protected]>
  • Loading branch information
cohansen and joswig authored Apr 26, 2024
1 parent 24d0d8d commit e85e345
Show file tree
Hide file tree
Showing 22 changed files with 790 additions and 484 deletions.
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
},
"dependencies": {
"@fontsource/jetbrains-mono": "^5.0.19",
"@nasa-jpl/aerie-ampcs": "^1.0.4",
"@nasa-jpl/aerie-ampcs": "^1.0.5",
"@nasa-jpl/seq-json-schema": "^1.0.20",
"@nasa-jpl/stellar": "^1.1.18",
"@sveltejs/adapter-node": "5.0.1",
Expand Down
6 changes: 5 additions & 1 deletion src/app.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,11 @@ declare global {
var GLOBALS: GlobalType[];
var ARG_DELEGATOR: ArgDelegator;
function LINT(commandDictionary, view, node);
function TO_SEQ_JSON(seqJson: SeqJson, parameterDictionaries: ParameterDictionary[]);
function TO_SEQ_JSON(
seqJson: SeqJson,
parameterDictionaries: ParameterDictionary[],
channelDictionary: ChannelDictionary | null,
);
}

export {};
186 changes: 186 additions & 0 deletions src/components/parcels/DictionaryTable.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
<svelte:options immutable={true} />

<script lang="ts">
import type { CellEditingStoppedEvent, ICellRendererParams, ValueGetterParams } from 'ag-grid-community';
import { createEventDispatcher } from 'svelte';
import type { User } from '../../types/app';
import type { DataGridColumnDef, RowId } from '../../types/data-grid';
import type { DictionaryType } from '../../types/sequencing';
import { featurePermissions } from '../../utilities/permissions';
import DataGridActions from '../ui/DataGrid/DataGridActions.svelte';
import SingleActionDataGrid from '../ui/DataGrid/SingleActionDataGrid.svelte';
import Panel from '../ui/Panel.svelte';
import SectionTitle from '../ui/SectionTitle.svelte';
export let dictionaries: DictionaryType[];
export let dictionaryId: number | null = null;
export let dictionaryIds: Record<number, boolean> = {};
export let isEditingParcel: boolean = false;
export let isMultiselect: boolean = false;
export let hasEditPermission: boolean = false;
export let type: string;
export let user: User | null;
let dictionaryDataGrid: SingleActionDataGrid<DictionaryType> | undefined = undefined;
const dispatch = createEventDispatcher<{
delete: { id: number };
multiSelect: { ids: Record<number, boolean> };
select: { id: number | null };
}>();
type dCellRendererParams = {
deleteDictionary?: (dictionary: DictionaryType) => void;
};
type DictionaryCellRendererParams = ICellRendererParams<DictionaryType> & dCellRendererParams;
$: isSequenceAdaptation = type === 'Sequence';
$: displayText = isSequenceAdaptation ? `${type} Adaptation` : `${type} Dictionary`;
$: displayTextPlural = isSequenceAdaptation ? `${type} Adaptations` : `${type} Dictionaries`;
$: hasDeletePermission = featurePermissions.commandDictionary.canDelete(user);
$: if (dictionaryIds) {
dictionaryDataGrid?.redrawRows();
}
const editingColumnDefs: DataGridColumnDef[] = [
{
cellDataType: 'boolean',
editable: hasEditPermission,
headerName: '',
suppressAutoSize: true,
suppressSizeToFit: true,
valueGetter: (params: ValueGetterParams<DictionaryType>) => {
const { data } = params;
if (data) {
if (isMultiselect) {
return !!dictionaryIds[data.id];
}
return dictionaryId === data.id;
}
return false;
},
width: 35,
},
];
const dictionaryColumnDefs: DataGridColumnDef[] = [
...(isEditingParcel ? editingColumnDefs : []),
{
field: 'id',
filter: 'number',
headerName: 'ID',
resizable: true,
sortable: true,
suppressAutoSize: true,
suppressSizeToFit: true,
width: 60,
},
{ field: 'mission', filter: 'text', headerName: 'Mission', sortable: true, width: 100 },
{ field: 'version', filter: 'text', headerName: 'Version', sortable: true, suppressAutoSize: true, width: 100 },
{ field: 'created_at', filter: 'text', headerName: 'Created At', resizable: true, sortable: true },
];
const sequenceAdaptationColumDefs: DataGridColumnDef[] = [
...(isEditingParcel ? editingColumnDefs : []),
{
field: 'id',
filter: 'number',
headerName: 'ID',
resizable: true,
sortable: true,
suppressAutoSize: true,
suppressSizeToFit: true,
width: 60,
},
{ field: 'created_at', filter: 'text', headerName: 'Created At', resizable: true, sortable: true },
];
$: columnDefs = [
...(isSequenceAdaptation ? sequenceAdaptationColumDefs : dictionaryColumnDefs),
{
cellClass: 'action-cell-container',
cellRenderer: (params: DictionaryCellRendererParams) => {
const actionsDiv = document.createElement('div');
actionsDiv.className = 'actions-cell';
new DataGridActions({
props: {
deleteCallback: params.deleteDictionary,
deleteTooltip: {
content: `Delete ${displayText}`,
placement: 'bottom',
},
hasDeletePermission,
rowData: params.data,
},
target: actionsDiv,
});
return actionsDiv;
},
cellRendererParams: {
deleteDictionary,
} as dCellRendererParams,
field: 'actions',
headerName: '',
resizable: false,
sortable: false,
suppressAutoSize: true,
suppressSizeToFit: true,
width: 25,
},
];
function deleteDictionary({ id }: Pick<DictionaryType, 'id'>) {
dispatch('delete', { id });
}
function deleteDictionaryContext(event: CustomEvent<RowId[]>) {
deleteDictionary({ id: event.detail[0] as number });
}
function onToggle(event: CustomEvent<CellEditingStoppedEvent<DictionaryType, boolean>>) {
const {
detail: { data, newValue },
} = event;
if (data) {
if (isMultiselect && typeof newValue === 'boolean') {
dictionaryIds = {
...dictionaryIds,
[data.id]: newValue,
};
dispatch('multiSelect', { ids: dictionaryIds });
} else {
dictionaryId = newValue ? data.id : null;
dispatch('select', { id: dictionaryId });
}
}
dictionaryDataGrid?.redrawRows();
}
</script>

<Panel>
<svelte:fragment slot="header">
<SectionTitle>{displayTextPlural}</SectionTitle>
</svelte:fragment>

<svelte:fragment slot="body">
{#if dictionaries.length}
<SingleActionDataGrid
bind:this={dictionaryDataGrid}
{columnDefs}
{hasDeletePermission}
itemDisplayText={displayText}
items={dictionaries}
{user}
on:cellEditingStopped={onToggle}
on:deleteItem={deleteDictionaryContext}
/>
{:else}
No {displayTextPlural} Found
{/if}
</svelte:fragment>
</Panel>
Loading

0 comments on commit e85e345

Please sign in to comment.