Add default Derivation Group associations for Plans at the Model level#1934
Add default Derivation Group associations for Plans at the Model level#1934pranav-super wants to merge 10 commits into
Conversation
| <RadioButton id="constraint"><div class="association-button">Constraints</div></RadioButton> | ||
| <RadioButton id="goal"><div class="association-button">Goals</div></RadioButton> | ||
| <RadioButton id="condition"><div class="association-button">Conditions</div></RadioButton> | ||
| <RadioButton id="derivation_group"><div class="association-button">Derivation Groups</div></RadioButton> |
| export let user: User | null; | ||
| export let selectedDerivationGroups: string[]; | ||
|
|
||
| $: console.log('dgmodelspec -> selectedDerivationGroups', selectedDerivationGroups); |
| import SectionTitle from '../ui/SectionTitle.svelte'; | ||
|
|
||
| export let user: User | null; | ||
| export let selectedDerivationGroups: string[]; |
There was a problem hiding this comment.
I can't seem to select a derivation group by clicking on a row in the DG table
There was a problem hiding this comment.
Ah - i have to click on the expand button.. any reason not to just use left click to trigger the detail view like we do in the other tables in the other tabs?
There was a problem hiding this comment.
No reason in particular. This was modeled after how it works in the plan view (see ManagePlanDerivationGroupsModal.svelte), where there is an expansion button, but that can be updated!
There was a problem hiding this comment.
Makes sense - I'd vote to align it with the other tabs in there just for consistency
| featurePermissions.derivationGroupModelLink.canCreate(user) && | ||
| featurePermissions.derivationGroupModelLink.canDelete(user); | ||
|
|
||
| // $: selectedDerivationGroups = $selectedModelDerivationGroupNames.reduce( |
| return false; | ||
| } | ||
|
|
||
| function isModelOwner(user: User | null, model: AssetWithOwner<ModelWithOwner> | undefined): boolean { |
There was a problem hiding this comment.
any reason for this new permission when it just wraps isUserOwner with the same args?
There was a problem hiding this comment.
It checks for model ownership specifically, and is used a few times! ModelWithOwner has a different set of properties than PlanWithOwner, so giving it a named function seemed appropriate. With that being said...this function is only used twice, whereas the isPlanOwner analogue is used 44 times. If it seems easier to unwrap this and directly use isUserOwner directly instead of this new function, that can be done, but having a named function seemed cleaner, and useful in case model ownership checking should be useful in future features.
There was a problem hiding this comment.
But I guess at the end of the day model ownership is just the same as user ownership? Given that it just wraps a function and doesn't make any modifications I feel like it is fine to keep it as just isUserOwner and modify it if/when user ownership =/ model ownership?
There was a problem hiding this comment.
I suppose that's true. But then is the isPlanOwner function necessary? I added this function as an analogue to that one.
| version: string; | ||
| } | null = null; | ||
|
|
||
| // to get derivation groups here, just need the store, and the table toggle button sends a request to update it. |
| async deleteExternalSource( | ||
| externalSources: ExternalSourceSlim[] | null, | ||
| planDerivationGroupLinks: PlanDerivationGroup[], | ||
| planDerivationGroupLinks: PlanDerivationGroup[], // TODO: add modelDerivationGroup checking? Don't believe it is necessary. |
There was a problem hiding this comment.
This was more of a question to the UI team. When deleting a source, we are stopped if that source is part of a derivation group that is associated with a plan to prevent unexpected effects. I don't think it makes sense to do so when a derivation group is only associated with a model and a source is to be deleted, but I wanted to check if you thought that might be worth adding. I describe this in better detail in the original PR comment/description (the first bullet point)!
There was a problem hiding this comment.
Got it - yeah seems unnecessary to check all of that since if i understand this all correctly, we're just setting defaults for newly created plans and not existing plans for DGs? That's what happens for constraints/goals/conditions at least.
There was a problem hiding this comment.
Yeah, I'd agree. I'll go ahead and remove the TODO!
| } | ||
| if (model) { | ||
| derivationGroupModelLinkErrorStore.set(null); | ||
| if (plan !== null) { |
There was a problem hiding this comment.
Should pass plan in here instead of relying on the store. Not sure if any effects rely on this store (something must..) but this will always evaluate to true since the store exists. If you want to get the value of the store you need to use the svelte store get(store) to get the current value. But the pattern we should follow for effects is to pass in whatever args are needed such as plan.
There was a problem hiding this comment.
On further review, this check should not be there! Removing...
| }, | ||
| CREATE_MODEL_DERIVATION_GROUP: (user: User | null, model: ModelWithOwner): boolean => { | ||
| return ( | ||
| isUserAdmin(user) || (getPermission([Queries.INSERT_PLAN_DERIVATION_GROUP], user) && isModelOwner(user, model)) |
There was a problem hiding this comment.
Should this be queries.INSERT_MODEL_DERIVATION_GROUP?
| }, | ||
| DELETE_MODEL_DERIVATION_GROUP: (user: User | null, model: ModelWithOwner): boolean => { | ||
| return ( | ||
| isUserAdmin(user) || (getPermission([Queries.DELETE_PLAN_DERIVATION_GROUP], user) && isModelOwner(user, model)) |
There was a problem hiding this comment.
Should this be queries.DELETE_MODEL_DERIVATION_GROUP?
| {}, | ||
| ); | ||
| } | ||
|
|
| `, | ||
|
|
||
| DELETE_MODEL_DERIVATION_GROUP: `#graphql | ||
| mutation DeletePlanExternalSource($where: model_derivation_group_bool_exp!) { |
There was a problem hiding this comment.
Should be DeleteModelDerivationGroup?
|
|
||
| CREATE_MODEL_DERIVATION_GROUP: `#graphql | ||
| mutation CreateModelDerivationGroup($source: model_derivation_group_insert_input!) { | ||
| planExternalSourceLink: ${Queries.INSERT_MODEL_DERIVATION_GROUP}( |
There was a problem hiding this comment.
should planExternalSourceLink be modelDerivationGroupLink?
AaronPlave
left a comment
There was a problem hiding this comment.
Could you add an e2e test for this workflow? Left some other comments but nothing too big to fix.
| ): Promise<void> { | ||
| try { | ||
| if ((model && !queryPermissions.DELETE_MODEL_DERIVATION_GROUP(user, model)) || !model) { | ||
| throwPermissionError('delete a derivation group from the plan'); |
There was a problem hiding this comment.
should be "...from the model"
| ): Promise<void> { | ||
| try { | ||
| if ((model && !queryPermissions.CREATE_MODEL_DERIVATION_GROUP(user, model)) || !model) { | ||
| throwPermissionError('add a derivation group to the plan'); |
There was a problem hiding this comment.
should be "...to the model"
| const { planExternalSourceLink: sourceAssociation } = data; | ||
| // If the return was null, do nothing - only act on success or non-null | ||
| if (sourceAssociation !== null) { | ||
| logMessage(`Linked derivation group "${derivationGroupName}" to plan "${model.name}" (ID=${model.id}).`); |
There was a problem hiding this comment.
should be "...to model..."?
| const derivationGroupsToDissociate = initialModelDerivationGroupAssociations.filter( | ||
| derivationGroup => !selectedDerivationGroups.includes(derivationGroup), | ||
| ); | ||
| derivationGroupsToDissociate.forEach(derivationGroup => |
There was a problem hiding this comment.
We should use a for loop here and below when iterating over these promises and we should await the effect promises
| if (model) { | ||
| derivationGroupModelLinkErrorStore.set(null); | ||
| if (plan !== null) { | ||
| const data = await reqHasura<{ |
There was a problem hiding this comment.
Doesn't this return
modelDerivationGroupLink: {
returning: { derivation_group_name: string; model_id: number; }[];
};
| }, | ||
| user, | ||
| ); | ||
| const { planExternalSourceLink: sourceAssociation } = data; |
There was a problem hiding this comment.
Should be modelDerivationGroupLink
| if (plan !== null) { | ||
| const data = await reqHasura<ModelDerivationGroup>( | ||
| gql.CREATE_MODEL_DERIVATION_GROUP, | ||
| { |
There was a problem hiding this comment.
Wouldn't this be:
{
modelDerivationGroupLink: { derivation_group_name: string } | null;
}
|




___REQUIRES_AERIE_PR___="1831"This is the UI update based on the tables introduced in this Plandev PR.
It introduces a derivation group tab along with the other model association tabs on the models page.
This feature is modeled off of the other associations, but since derivation group associations are much simpler than goal/condition/constraint specifications, is a lot lighter-weight and doesn't precisely match functionality.
There are a few minor unresolved TODOs, namely:
We don't believe this is a necessary check for model-derivation-group links (i.e. if a derivation group is linked to a model, and a planner wants to delete a source from said group, they shouldn't be blocked from doing so). We believe this is an unnecessary check because with a model, there are no activities scheduled off of any sources or external events visible to planners at a model level, so there is no anticipated loss when a source is deleted.
ManagePlanDerivationGroupsModal, and a lot of the formatting anddivs were retained as attempts to format otherwise were unsuccessful.