-
Notifications
You must be signed in to change notification settings - Fork 9
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
Allow partial export #522
base: dev
Are you sure you want to change the base?
Allow partial export #522
Conversation
79038e9
to
cf17cc3
Compare
This is currently depending on #581 as I need to run a migration in the reducer (or the frontend) but not the backend. |
@Dassderdie Apart from the missing call of the migration this should now be ready for review. |
|
I agree with both points made. However, I'd stick with the current solution for now. The second point depends on #581, and the first point would be a refactoring I'd like to do separately. Maybe we could even disallow migrations for partial imports for now, depending on your plan with #581. |
...tial-import-overwrite/partial-import-overwrite-modal/partial-import-overwrite.component.html
Outdated
Show resolved
Hide resolved
...tial-export-selection/partial-export-selection-modal/partial-export-selection.component.html
Outdated
Show resolved
Hide resolved
...tial-import-overwrite/partial-import-overwrite-modal/partial-import-overwrite.component.html
Outdated
Show resolved
Hide resolved
...src/app/pages/exercises/exercise/shared/trainer-map-editor/trainer-map-editor.component.html
Outdated
Show resolved
Hide resolved
...artial-import-overwrite/partial-import-overwrite-modal/partial-import-overwrite.component.ts
Outdated
Show resolved
Hide resolved
frontend/src/app/pages/exercises/exercise/exercise/exercise.component.html
Outdated
Show resolved
Hide resolved
Co-authored-by: Julian Schmidt <julian.schmidt@student.hpi.de>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I haven't tested it out again. I will do it after these changes are incorporated.
import type { NgbModal } from '@ng-bootstrap/ng-bootstrap'; | ||
import { PartialExportComponent } from './partial-export-modal/partial-export-modal.component'; | ||
|
||
export function openPartialExportSelectionModal(ngbModalService: NgbModal) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
export function openPartialExportSelectionModal(ngbModalService: NgbModal) { | |
export function openPartialExportModal(ngbModalService: NgbModal) { |
templateUrl: './partial-export-modal.component.html', | ||
styleUrls: ['./partial-export-modal.component.scss'], | ||
}) | ||
export class PartialExportComponent { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
export class PartialExportComponent { | |
export class PartialExportModalComponent { |
const importedPlainObject = JSON.parse(importedText) as object; | ||
const importedInstance = plainToInstance( | ||
PartialExport, | ||
importedPlainObject | ||
); | ||
const migratedInstance = migratePartialExport(importedInstance); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this fails the user should get an error message that the import is invalid.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just noticed that this could not fail. However, I don't know whether this is good behavior. When importing an invalid file, the migration function will choose undefined
for all three categories, which is valid, just not useful. I'm not quite sure how to proceed there.
draftState.alarmGroups = Object.fromEntries( | ||
Object.entries(draftState.alarmGroups).map( | ||
([id, alarmGroup]) => { | ||
alarmGroup.alarmGroupVehicles = {}; | ||
return [id, alarmGroup]; | ||
} | ||
) | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
draftState.alarmGroups = Object.fromEntries( | |
Object.entries(draftState.alarmGroups).map( | |
([id, alarmGroup]) => { | |
alarmGroup.alarmGroupVehicles = {}; | |
return [id, alarmGroup]; | |
} | |
) | |
); | |
for (const alarmGroup of draftState.alarmGroups) { | |
alarmGroup.alarmGroupVehicles = {}; | |
} |
const templateType = ['mapImageTemplates', 'vehicleTemplates'] as const; | ||
for (const property of templateType) { | ||
const templates = copy[property]; | ||
if (templates !== undefined) { | ||
for (const template of templates) { | ||
template.id = uuid(); | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const templateType = ['mapImageTemplates', 'vehicleTemplates'] as const; | |
for (const property of templateType) { | |
const templates = copy[property]; | |
if (templates !== undefined) { | |
for (const template of templates) { | |
template.id = uuid(); | |
} | |
} | |
} | |
const templateTypes = ['mapImageTemplates', 'vehicleTemplates'] as const; | |
for (const templateType of templateTypes) { | |
const templates = copy[templateType]; | |
if (templates !== undefined) { | |
for (const template of templates) { | |
template.id = uuid(); | |
} | |
} | |
} |
const importInstance = plainToInstance( | ||
PartialExport, | ||
this.partialExport | ||
); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const importInstance = plainToInstance( | |
PartialExport, | |
this.partialExport | |
); |
You should be able to use partialExport
directly, as this is just data.
const importedPlainObject = JSON.parse(importedText) as object; | ||
const importedInstance = plainToInstance( | ||
PartialExport, | ||
importedPlainObject | ||
); | ||
const migratedInstance = migratePartialExport(importedInstance); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const importedPlainObject = JSON.parse(importedText) as object; | |
const importedInstance = plainToInstance( | |
PartialExport, | |
importedPlainObject | |
); | |
const migratedInstance = migratePartialExport(importedInstance); | |
const importedPlainObject = JSON.parse(importedText) as object; | |
const migratedPartialExport = migratePartialExport(importedPlainObject); | |
if (!isValid(plainToInstance( | |
PartialExport, | |
migratedPartialExport | |
))) { | |
throw Error('PartialExport is invalid'); | |
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At the moment, you are passing an instance to the modal (instead of a plain object) and, therefore, to the action. I would suspect this to crash, if this instance is later modified in a reducer (e.g., a template gets renamed) as immer.js
would find a prototype in the template object.
Remember that all the `.create()-factory-functions were there to not have instances in the state.
FYI: Instead of the factory functions, one could also add a token to those classes in which immer should ignore the prototypes. But having plain objects without prototypes could be more performant (immerjs/immer#941) and maybe less error-prone. #531
This addresses the partial exports as described in #392.