Skip to content

Commit

Permalink
CSCKAN-323 feat: Update origins changes
Browse files Browse the repository at this point in the history
  • Loading branch information
afonsobspinto committed Oct 16, 2024
1 parent 7186834 commit caf19d8
Show file tree
Hide file tree
Showing 7 changed files with 71 additions and 65 deletions.
3 changes: 1 addition & 2 deletions backend/composer/api/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
from django.contrib.auth.models import User
from django.db.models import Q
from django_fsm import FSMField
from drf_spectacular.types import OpenApiTypes
from drf_writable_nested.mixins import UniqueFieldsMixin
from drf_writable_nested.serializers import WritableNestedModelSerializer
from rest_framework import serializers
Expand All @@ -21,7 +20,7 @@
Sentence,
Specie,
Tag,
Via, Destination, AnatomicalEntityIntersection, Region, Layer, AnatomicalEntityMeta, GraphRenderingState,
Via, Destination, AnatomicalEntityIntersection, AnatomicalEntityMeta, GraphRenderingState,
)
from ..services.connections_service import get_complete_from_entities_for_destination, \
get_complete_from_entities_for_via
Expand Down
2 changes: 1 addition & 1 deletion backend/composer/api/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,7 @@ def update(self, request, *args, **kwargs):
if response.status_code == status.HTTP_200_OK:
instance = self.get_object()
self.handle_graph_rendering_state(instance, graph_rendering_state_data, request.user)
if origin_ids:
if origin_ids is not None:
instance.set_origins(origin_ids)

return response
Expand Down
60 changes: 10 additions & 50 deletions frontend/src/components/Forms/StatementForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,11 @@ import {
import {CustomFooter} from "../Widgets/HoveredOptionContent";
import {StatementStateChip} from "../Widgets/StateChip";
import {projections} from "../../services/ProjectionService";
import {userProfile} from "../../services/UserService";
import {checkOwnership} from "../../helpers/ownershipAlert";


const StatementForm = (props: any) => {
const {uiFields, statement, isDisabled, action: refreshStatement} = props;
const {uiFields, statement, setStatement, isDisabled, action: refreshStatement} = props;
const {schema, uiSchema} = jsonSchemas.getConnectivityStatementSchema();
const copiedSchema = JSON.parse(JSON.stringify(schema));
const copiedUISchema = JSON.parse(JSON.stringify(uiSchema));
Expand Down Expand Up @@ -182,7 +182,7 @@ const StatementForm = (props: any) => {
);
},
onUpdate: async (selectedOptions: any) => {
await updateOrigins(selectedOptions, statement.id);
await updateOrigins(selectedOptions, statement.id, setStatement);
},
errors: "",
mapValueToOption: () =>
Expand Down Expand Up @@ -696,53 +696,13 @@ const StatementForm = (props: any) => {
};

const handleErrorAction = (error: any, newStatementData: ConnectivityStatement) => {
const statementIdNumber = newStatementData.id ?? -1; // Ensure statement ID is a valid number

// Fetch the latest statement to check for ownership
statementService.getObject(statementIdNumber.toString()).then((fetchedStatement: ConnectivityStatement) => {
// Check if the fetched statement has an owner and it's not the current user
if (fetchedStatement.owner && fetchedStatement.owner?.id !== userProfile.getUser().id) {
// Show a confirmation alert to the user
const userConfirmed = window.confirm(
`This statement is currently assigned to ${fetchedStatement.owner.first_name}. You are in read-only mode, and any changes you attempt will not be saved.
Would you like to assign this statement to yourself and gain edit access? Select 'OK' to assign ownership, or 'Cancel' to continue viewing in read-only mode.`
);

if (userConfirmed) {
// User confirmed to assign ownership
const userId = userProfile.getUser().id;

// Reassign ownership
statementService
.assignOwner(statementIdNumber, {
...fetchedStatement,
owner_id: userId, // Assign ownership to the current user
})
.then((_: ConnectivityStatement) => {
// Save and refresh the updated statement
return statementService.save({
...newStatementData,
owner_id: userId,
}).then(() => {
refreshStatement(); // Refresh after saving
});
})
.catch((error) => {
console.error("Failed to reassign ownership", error);
refreshStatement(); // Still refresh the statement even if there's an error
});
} else {
// User canceled, just refresh the statement
refreshStatement();
}
} else {
// No need to assign ownership, just refresh the statement
refreshStatement();
}
}).catch((fetchError) => {
console.error("Failed to fetch the statement data", fetchError);
refreshStatement(); // Refresh the statement in case of fetch failure
});
checkOwnership(
statement.id,
(fetchedData, userId) => statementService.save({...newStatementData, owner_id: userId})
.then(() => refreshStatement()),
() => refreshStatement(),
(owner) => `This statement is currently assigned to ${owner.first_name}. You are in read-only mode. Would you like to assign this statement to yourself and gain edit access?`
);
};


Expand Down
8 changes: 4 additions & 4 deletions frontend/src/components/ProofingTab/PathsBuilder.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ const PathsBuilder = (props: any) => {
{...props}
statement={statement}
format="noLabel"
refreshStatement={refreshStatement}
action={refreshStatement}
extraData={{ sentence_id: statement.sentence.id }}
uiFields={["origins"]}
enableAutoSave={false}
Expand All @@ -70,7 +70,7 @@ const PathsBuilder = (props: any) => {
{...props}
statement={statement}
format="noLabel"
refreshStatement={refreshStatement}
action={refreshStatement}
extraData={{ sentence_id: statement.sentence.id }}
uiFields={["vias"]}
enableAutoSave={false}
Expand All @@ -94,7 +94,7 @@ const PathsBuilder = (props: any) => {
{...props}
statement={statement}
format="noLabel"
refreshStatement={refreshStatement}
action={refreshStatement}
extraData={{ sentence_id: statement.sentence.id }}
uiFields={["destinations"]}
enableAutoSave={false}
Expand All @@ -119,7 +119,7 @@ const PathsBuilder = (props: any) => {
{...props}
statement={statement}
format="small"
refreshStatement={refreshStatement}
action={refreshStatement}
extraData={{ sentence_id: statement.sentence.id }}
uiFields={["forward_connection"]}
enableAutoSave={true}
Expand Down
8 changes: 3 additions & 5 deletions frontend/src/components/Widgets/CustomEntitiesDropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,6 @@ export default function CustomEntitiesDropdown({
label,
chipsNumber = 2,
postProcessOptions = false,
refreshStatement,
getPreLevelSelectedValues,
areConnectionsExplicit,
minWidth = '',
Expand Down Expand Up @@ -329,7 +328,7 @@ export default function CustomEntitiesDropdown({

const handleChipRemove = (chip: Option) => {
const updatedChips = selectedOptions.filter((c: Option) => c !== chip);
handleSelectedOptionsChange(updatedChips).then(() => refreshStatement());
handleSelectedOptionsChange(updatedChips);
};

const handleInputChange = (event: any) => {
Expand Down Expand Up @@ -385,8 +384,7 @@ export default function CustomEntitiesDropdown({
setAnchorEl(null);
setInputValue("");
setAllOptions([]);
if (refreshStatement && hasValueChanged) {
refreshStatement();
if (hasValueChanged) {
setHasValueChanged(false);
}
if (postProcessOptions && selectedOptions.length === 0) {
Expand All @@ -399,7 +397,7 @@ export default function CustomEntitiesDropdown({
return () => {
document.removeEventListener("mousedown", closePopperOnClickOutside);
};
}, [hasValueChanged, postProcessOptions, getPreLevelSelectedValues, refreshStatement, selectedOptions.length, id]);
}, [hasValueChanged, postProcessOptions, getPreLevelSelectedValues, selectedOptions.length, id]);

return isDisabled ? (
disabledReason ? (
Expand Down
42 changes: 42 additions & 0 deletions frontend/src/helpers/ownershipAlert.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import statementService from "../services/StatementService";
import {userProfile} from "../services/UserService";

export const checkOwnership = (
id: number,
onSave: (fetchedData: any, userId: number) => Promise<any>,
onCancel: (fetchedData: any, userId: number) => void,
alertMessage: (owner: any) => string
) => {
const userId = userProfile.getUser().id;
// Fetch the latest data to check for ownership
statementService.getObject(id.toString())
.then((fetchedData: any) => {
// Check if the fetched data has an owner and if the current user is not the owner
if (fetchedData.owner && fetchedData.owner.id !== userProfile.getUser().id) {
const userConfirmed = window.confirm(alertMessage(fetchedData.owner));

if (userConfirmed) {

// Reassign ownership and save the data
statementService.assignOwner(fetchedData.id, {
...fetchedData,
owner_id: userId, // Assign ownership to the current user
})
.then(() => {
// Call the merged save action
return onSave(fetchedData, userId)
})
.catch((error) => {
console.error("Failed to reassign ownership", error);
onCancel(fetchedData, userId);
});
} else {
onCancel(fetchedData, userId);
}
}
})
.catch((fetchError) => {
console.error("Failed to fetch the data", fetchError);
onCancel(null, userId);
});
};
13 changes: 10 additions & 3 deletions frontend/src/services/CustomDropdownService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import {
import { searchAnatomicalEntities } from "../helpers/helpers";
import connectivityStatementService from "./StatementService";
import statementService from "./StatementService";
import {checkOwnership} from "../helpers/ownershipAlert";

export async function getAnatomicalEntities(
searchValue: string,
Expand All @@ -42,18 +43,24 @@ export async function getAnatomicalEntities(
}
}

export async function updateOrigins(selected: Option[], statementId: number) {
export async function updateOrigins(selected: Option[], statementId: number,
setStatement: (statement: any) => void) {
const originIds = selected.map((option) => parseInt(option.id));
const patchedStatement: PatchedConnectivityStatementUpdate = {
origins: originIds,
};
try {
await api.composerConnectivityStatementPartialUpdate(
await statementService.partialUpdate(
statementId,
patchedStatement,
);
} catch (error) {
console.error("Error updating origins", error);
checkOwnership(
statementId,
() => statementService.partialUpdate(statementId, patchedStatement),
(fetchedStatement) => setStatement(fetchedStatement),
(owner) => `This statement is currently assigned to ${owner.first_name}. You are in read-only mode. Would you like to assign this statement to yourself and gain edit access?`
);
}
}

Expand Down

0 comments on commit caf19d8

Please sign in to comment.