Skip to content

Commit

Permalink
Do not include view definition in view subscription and full view on …
Browse files Browse the repository at this point in the history
…demand. Fix bug with deletion of views.
  • Loading branch information
AaronPlave committed Dec 6, 2023
1 parent 2d51aea commit 2aa76b3
Show file tree
Hide file tree
Showing 8 changed files with 33 additions and 28 deletions.
2 changes: 1 addition & 1 deletion src/components/context-menu/ContextMenu.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@
}
function onKeyDown(event: KeyboardEvent) {
if (event.key === 'Escape') {
if (shown && event.key === 'Escape') {
hide(true);
event.stopPropagation();
}
Expand Down
10 changes: 5 additions & 5 deletions src/components/modals/SavedViewsModal.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import { SearchParameters } from '../../enums/searchParameters';
import { initializeView, view, views } from '../../stores/views';
import type { User } from '../../types/app';
import type { View } from '../../types/view';
import type { ViewSlim } from '../../types/view';
import effects from '../../utilities/effects';
import { setQueryParam } from '../../utilities/generic';
import Tab from '../ui/Tabs/Tab.svelte';
Expand All @@ -22,12 +22,12 @@
const dispatch = createEventDispatcher();
let userViews: View[] = [];
let userViews: ViewSlim[] = [];
$: userViews = $views.filter((view: View) => view.owner === user?.id);
$: userViews = $views.filter((view: ViewSlim) => view.owner === user?.id);
async function deleteView({ detail: viewId }: CustomEvent<number>) {
const matchingView = userViews.find(v => v.id === viewId);
const matchingView = $views.find(v => v.id === viewId);
if (matchingView) {
const success = await effects.deleteView(matchingView, user);
Expand All @@ -40,7 +40,7 @@
}
async function deleteViews({ detail: viewIds }: CustomEvent<number[]>) {
const matchingViews = userViews.filter(v => viewIds.some(viewId => viewId === v.id));
const matchingViews = $views.filter(v => viewIds.some(viewId => viewId === v.id));
const success = await effects.deleteViews(matchingViews, user);
if (success) {
Expand Down
20 changes: 10 additions & 10 deletions src/components/view/ViewsTable.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,21 @@
import { createEventDispatcher } from 'svelte';
import type { User } from '../../types/app';
import type { DataGridColumnDef } from '../../types/data-grid';
import type { View } from '../../types/view';
import type { View, ViewSlim } from '../../types/view';
import { featurePermissions } from '../../utilities/permissions';
import { downloadView as downloadViewUtil } from '../../utilities/view';
import BulkActionDataGrid from '../ui/DataGrid/BulkActionDataGrid.svelte';
import DataGridActions from '../ui/DataGrid/DataGridActions.svelte';
export let views: View[] = [];
export let views: ViewSlim[] = [];
export let user: User | null;
type CellRendererParams = {
deleteView: (view: View) => void;
downloadView: (view: View) => void;
openView: (view: View) => void;
deleteView: (view: ViewSlim) => void;
downloadView: (view: ViewSlim) => void;
openView: (view: ViewSlim) => void;
};
type ViewCellRendererParams = ICellRendererParams<View> & CellRendererParams;
type ViewCellRendererParams = ICellRendererParams<ViewSlim> & CellRendererParams;
const dispatch = createEventDispatcher();
const baseColumnDefs: DataGridColumnDef[] = [
Expand Down Expand Up @@ -104,20 +104,20 @@
},
];
function deleteView({ id: viewId }: View) {
function deleteView({ id: viewId }: ViewSlim) {
dispatch('deleteView', viewId);
}
function deleteViews({ detail: views }: CustomEvent<View[]>) {
function deleteViews({ detail: views }: CustomEvent<ViewSlim[]>) {
const viewIds = views.map(({ id }) => id);
dispatch('deleteViews', viewIds);
}
function hasDeletePermission(user: User | null, view: View) {
function hasDeletePermission(user: User | null, view: ViewSlim) {
return featurePermissions.view.canDelete(user, view);
}
function openView({ id: viewId }: Partial<View>) {
function openView({ id: viewId }: Partial<ViewSlim>) {
dispatch('openView', viewId);
}
</script>
Expand Down
4 changes: 2 additions & 2 deletions src/stores/views.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { isEqual } from 'lodash-es';
import { derived, get, writable, type Writable } from 'svelte/store';
import type { View, ViewGrid, ViewTable, ViewToggleEvent } from '../types/view';
import type { View, ViewGrid, ViewSlim, ViewTable, ViewToggleEvent } from '../types/view';
import { getTarget } from '../utilities/generic';
import gql from '../utilities/gql';
import { TimelineInteractionMode, TimelineLockStatus } from '../utilities/timeline';
Expand All @@ -9,7 +9,7 @@ import { gqlSubscribable } from './subscribable';

/* Subscriptions. */

export const views = gqlSubscribable<View[]>(gql.SUB_VIEWS, {}, [], null);
export const views = gqlSubscribable<ViewSlim[]>(gql.SUB_VIEWS, {}, [], null);

/* Writeable. */

Expand Down
2 changes: 2 additions & 0 deletions src/types/view.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,3 +92,5 @@ export type View = {
owner: UserId;
updated_at: string;
};

export type ViewSlim = Omit<View, 'definition'>;
14 changes: 9 additions & 5 deletions src/utilities/effects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ import type {
TagsSetInput,
} from '../types/tags';
import type { Row, Timeline } from '../types/timeline';
import type { View, ViewDefinition, ViewInsertInput, ViewUpdateInput } from '../types/view';
import type { View, ViewDefinition, ViewInsertInput, ViewSlim, ViewUpdateInput } from '../types/view';
import { ActivityDeletionAction } from './activities';
import { convertToQuery, getSearchParameterNumber, setQueryParam, sleep } from './generic';
import gql, { convertToGQLArray } from './gql';
Expand Down Expand Up @@ -2165,7 +2165,7 @@ const effects = {
}
},

async deleteView(view: View, user: User | null): Promise<boolean> {
async deleteView(view: ViewSlim, user: User | null): Promise<boolean> {
try {
if (!queryPermissions.DELETE_VIEW(user, view)) {
throwPermissionError('delete this view');
Expand All @@ -2180,25 +2180,27 @@ const effects = {
if (confirm) {
const data = await reqHasura<{ id: number }>(gql.DELETE_VIEW, { id: view.id }, user);
if (data.deletedView != null) {
showSuccessToast('View Deleted Successfully');
return true;
} else {
throw Error(`Unable to delete view "${view.name}"`);
}
}
} catch (e) {
showFailureToast('View Delete Failed');
catchError(e as Error);
}

return false;
},

async deleteViews(views: View[], user: User | null): Promise<boolean> {
async deleteViews(views: ViewSlim[], user: User | null): Promise<boolean> {
try {
const hasPermission = views.reduce((previousValue, view) => {
return previousValue || queryPermissions.DELETE_VIEWS(user, view);
}, true);
}, false);
if (!hasPermission) {
throwPermissionError('delete these views');
throwPermissionError('delete one or all of these views');
}

const { confirm } = await showConfirmModal(
Expand All @@ -2219,12 +2221,14 @@ const effects = {
if (leftoverViewIds.length > 0) {
throw new Error(`Some views were not successfully deleted: ${leftoverViewIds.join(', ')}`);
}
showSuccessToast('Views Deleted Successfully');
return true;
} else {
throw Error('Unable to delete views');
}
}
} catch (e) {
showFailureToast('View Deletes Failed');
catchError(e as Error);
}

Expand Down
1 change: 0 additions & 1 deletion src/utilities/gql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2085,7 +2085,6 @@ const gql = {
subscription SubViews {
views: view {
created_at
definition
id
name
owner
Expand Down
8 changes: 4 additions & 4 deletions src/utilities/permissions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import type { SchedulingCondition, SchedulingGoal } from '../types/scheduling';
import type { UserSequence } from '../types/sequencing';
import type { Simulation, SimulationTemplate } from '../types/simulation';
import type { Tag } from '../types/tags';
import type { View } from '../types/view';
import type { View, ViewSlim } from '../types/view';
import { showFailureToast } from './toast';

export const ADMIN_ROLE = 'aerie_admin';
Expand Down Expand Up @@ -506,10 +506,10 @@ const queryPermissions = {
DELETE_USER_SEQUENCE: (user: User | null, sequence: AssetWithOwner<UserSequence>): boolean => {
return isUserAdmin(user) || (getPermission(['delete_user_sequence_by_pk'], user) && isUserOwner(user, sequence));
},
DELETE_VIEW: (user: User | null, view: View): boolean => {
DELETE_VIEW: (user: User | null, view: ViewSlim): boolean => {
return isUserAdmin(user) || (getPermission(['delete_view_by_pk'], user) && isUserOwner(user, view));
},
DELETE_VIEWS: (user: User | null, view: View): boolean => {
DELETE_VIEWS: (user: User | null, view: ViewSlim): boolean => {
return isUserAdmin(user) || (getPermission(['delete_view'], user) && isUserOwner(user, view));
},
DUPLICATE_PLAN: (user: User | null, plan: PlanWithOwners, model: ModelWithOwner): boolean => {
Expand Down Expand Up @@ -870,7 +870,7 @@ interface FeaturePermissions {
simulation: RunnableCRUDPermission<AssetWithOwner<Simulation>>;
simulationTemplates: PlanSimulationTemplateCRUDPermission;
tags: CRUDPermission<Tag>;
view: CRUDPermission<View>;
view: CRUDPermission<ViewSlim>;
}

const featurePermissions: FeaturePermissions = {
Expand Down

0 comments on commit 2aa76b3

Please sign in to comment.