Skip to content

Commit

Permalink
Refactor queries and permission references (#1174)
Browse files Browse the repository at this point in the history
* add query enum for query strings
* use query enum across gql queries and permissions
* added separate static type checker for gql object and queryPermissions to maintain inherited types
  • Loading branch information
duranb authored Mar 26, 2024
1 parent aa7929b commit fe51930
Show file tree
Hide file tree
Showing 6 changed files with 637 additions and 534 deletions.
2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,5 @@
},
"stylelint.validate": ["css", "less", "postcss", "svelte"],
"typescript.preferences.importModuleSpecifier": "relative",
"cSpell.words": ["unconstructable"]
"cSpell.words": ["metadatas", "unconstructable"]
}
14 changes: 10 additions & 4 deletions src/components/plan/PlanForm.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,13 @@
let filteredPlanSnapshots: PlanSnapshotType[] = [];
let isFilteredBySimulation: boolean = false;
let hasCreateSnapshotPermission: boolean = false;
let hasPlanUpdatePermission: boolean = false;
$: permissionError = $planReadOnly ? PlanStatusMessages.READ_ONLY : 'You do not have permission to edit this plan.';
$: if (plan) {
hasCreateSnapshotPermission = featurePermissions.planSnapshot.canCreate(user, plan, plan.model) && !$planReadOnly;
}
$: {
if (plan && user) {
hasPlanUpdatePermission = featurePermissions.plan.canUpdate(user, plan) && !$planReadOnly;
Expand All @@ -56,7 +60,7 @@
} = event;
if (type === 'remove') {
await effects.deletePlanTags([tag.id], user);
} else if (type === 'create' || type === 'select') {
} else if (plan && (type === 'create' || type === 'select')) {
let tagsToAdd: Tag[] = [tag];
if (type === 'create') {
tagsToAdd = (await effects.createTags([{ color: tag.color, name: tag.name }], user)) || [];
Expand All @@ -65,7 +69,7 @@
plan_id: plan?.id || -1,
tag_id,
}));
await effects.createPlanTags(newPlanTags, user, false);
await effects.createPlanTags(newPlanTags, plan, user, false);
}
}
Expand Down Expand Up @@ -187,8 +191,10 @@
<button
class="st-button secondary"
use:permissionHandler={{
hasPermission: !$planReadOnly,
permissionError: PlanStatusMessages.READ_ONLY,
hasPermission: hasCreateSnapshotPermission,
permissionError: $planReadOnly
? PlanStatusMessages.READ_ONLY
: 'You do not have permission to create a plan snapshot',
}}
on:click={onCreatePlanSnapshot}>Take Snapshot</button
>
Expand Down
2 changes: 1 addition & 1 deletion src/routes/plans/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@
plan_id: newPlan.id,
tag_id,
}));
await effects.createPlanTags(newPlanTags, user);
await effects.createPlanTags(newPlanTags, newPlan, user);
newPlan.tags = planTags.map(tag => ({ tag }));
plans = [...plans, newPlan];
}
Expand Down
69 changes: 14 additions & 55 deletions src/utilities/effects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ import type {
import type {
PermissibleQueriesMap,
PermissibleQueryResponse,
PlanWithOwners,
RolePermissionResponse,
RolePermissionsMap,
} from '../types/permissions';
Expand Down Expand Up @@ -300,7 +301,7 @@ const effects = {

async cancelSchedulingRequest(analysisId: number, user: User | null): Promise<void> {
try {
if (!queryPermissions.CANCEL_PENDING_SCHEDULING_REQUEST(user)) {
if (!queryPermissions.CANCEL_SCHEDULING_REQUEST(user)) {
throwPermissionError('cancel a scheduling request dataset');
}
const { confirm } = await showConfirmModal(
Expand All @@ -323,7 +324,7 @@ const effects = {

async cancelSimulation(simulationDatasetId: number, user: User | null): Promise<void> {
try {
if (!queryPermissions.CANCEL_PENDING_SIMULATION(user)) {
if (!queryPermissions.CANCEL_SIMULATION(user)) {
throwPermissionError('cancel a simulation');
}
const { confirm } = await showConfirmModal(
Expand Down Expand Up @@ -1093,9 +1094,14 @@ const effects = {
}
},

async createPlanTags(tags: PlanTagsInsertInput[], user: User | null, notify: boolean = true): Promise<number | null> {
async createPlanTags(
tags: PlanTagsInsertInput[],
plan: PlanWithOwners,
user: User | null,
notify: boolean = true,
): Promise<number | null> {
try {
if (!queryPermissions.CREATE_PLAN_TAGS(user)) {
if (!queryPermissions.CREATE_PLAN_TAGS(user, plan)) {
throwPermissionError('create plan tags');
}

Expand Down Expand Up @@ -1352,7 +1358,7 @@ const effects = {
user: User | null,
): Promise<Pick<SchedulingPlanSpecification, 'id'> | null> {
try {
if (!queryPermissions.CREATE_SCHEDULING_SPEC(user)) {
if (!queryPermissions.CREATE_SCHEDULING_PLAN_SPECIFICATION(user)) {
throwPermissionError('create a scheduling spec');
}

Expand Down Expand Up @@ -2274,29 +2280,6 @@ const effects = {
}
},

// async deleteSchedulingSpecGoal(goal_id: number, specification_id: number, user: User | null): Promise<boolean> {
// try {
// if (!queryPermissions.DELETE_SCHEDULING_GOAL_PLAN_SPECIFICATION(user)) {
// throwPermissionError('delete this scheduling goal');
// }

// const data = await reqHasura<{ goal_id: number; specification_id: number }>(
// gql.DELETE_SCHEDULING_SPEC_GOAL,
// { goal_id, specification_id },
// user,
// );
// if (data.deleteSchedulingSpecGoal != null) {
// return true;
// } else {
// throw Error(`Unable to delete scheduling goal with ID: "${goal_id}"`);
// }
// } catch (e) {
// catchError('Scheduling Goal Delete Failed', e as Error);
// showFailureToast('Scheduling Goal Delete Failed');
// return false;
// }
// },

async deleteSimulationTemplate(
simulationTemplate: SimulationTemplate,
modelName: string,
Expand Down Expand Up @@ -3895,7 +3878,7 @@ const effects = {
try {
if (plan) {
if (
!queryPermissions.UPDATE_SCHEDULING_PLAN_SPECIFICATIONS(user, plan) ||
!queryPermissions.UPDATE_SCHEDULING_SPECIFICATION(user, plan) ||
!queryPermissions.SCHEDULE(user, plan, plan.model)
) {
throwPermissionError(`run ${analysis_only ? 'scheduling analysis' : 'scheduling'}`);
Expand Down Expand Up @@ -4552,11 +4535,11 @@ const effects = {
user: User | null,
): Promise<void> {
try {
if (!queryPermissions.UPDATE_SCHEDULING_PLAN_SPECIFICATIONS(user, plan)) {
if (!queryPermissions.UPDATE_SCHEDULING_SPECIFICATION(user, plan)) {
throwPermissionError('update this scheduling spec');
}

const data = await reqHasura(gql.UPDATE_SCHEDULING_SPEC, { id, spec }, user);
const data = await reqHasura(gql.UPDATE_SCHEDULING_SPECIFICATION, { id, spec }, user);
if (data.updateSchedulingSpec == null) {
throw Error(`Unable to update scheduling spec with ID: "${id}"`);
}
Expand All @@ -4565,30 +4548,6 @@ const effects = {
}
},

// async updateSchedulingSpecGoal(
// goal_id: number,
// specification_id: number,
// spec_goal: Partial<SchedulingGoalPlanSpecification>,
// plan: Plan,
// user: User | null,
// ): Promise<void> {
// try {
// if (!queryPermissions.UPDATE_SCHEDULING_SPEC_GOAL(user, plan)) {
// throwPermissionError('update this scheduling spec goal');
// }

// const data = await reqHasura(gql.UPDATE_SCHEDULING_SPEC_GOAL, { goal_id, spec_goal, specification_id }, user);
// if (data.updateSchedulingSpecGoal != null) {
// showSuccessToast('Scheduling Spec Goal Updated Successfully');
// } else {
// throw Error(`Unable to update scheduling spec goal with ID: "${goal_id}"`);
// }
// } catch (e) {
// catchError('Scheduling Spec Goal Update Failed', e as Error);
// showFailureToast('Scheduling Spec Goal Update Failed');
// }
// },

async updateSimulation(
plan: Plan,
simulationSetInput: Simulation,
Expand Down
Loading

0 comments on commit fe51930

Please sign in to comment.