Skip to content

Commit

Permalink
CSCKAN-323 feat: Move ownership check to statement service
Browse files Browse the repository at this point in the history
  • Loading branch information
afonsobspinto committed Oct 16, 2024
1 parent ee4a5b5 commit f7c5f1b
Show file tree
Hide file tree
Showing 9 changed files with 516 additions and 113 deletions.
3 changes: 2 additions & 1 deletion backend/composer/api/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -388,13 +388,14 @@ def partial_update(self, request, *args, **kwargs):

return response

@action(detail=True, methods=['post'], permission_classes=[permissions.IsAuthenticated])
@action(detail=True, methods=['patch'], permission_classes=[permissions.IsAuthenticated])
def assign_owner(self, request, pk=None):
instance = self.get_object()
instance.owner = request.user
instance.save()
return Response(self.get_serializer(instance).data)


@extend_schema(tags=["public"])
class KnowledgeStatementViewSet(
generics.ListAPIView,
Expand Down
2 changes: 1 addition & 1 deletion frontend/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

233 changes: 219 additions & 14 deletions frontend/src/apiclient/backend/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1336,6 +1336,211 @@ export interface PaginatedViaList {
*/
'results'?: Array<Via>;
}
/**
* Connectivity Statement
* @export
* @interface PatchedConnectivityStatement
*/
export interface PatchedConnectivityStatement {
/**
*
* @type {number}
* @memberof PatchedConnectivityStatement
*/
'id'?: number | null;
/**
*
* @type {number}
* @memberof PatchedConnectivityStatement
*/
'sentence_id'?: number;
/**
*
* @type {Sentence}
* @memberof PatchedConnectivityStatement
*/
'sentence'?: Sentence;
/**
*
* @type {string}
* @memberof PatchedConnectivityStatement
*/
'knowledge_statement'?: string;
/**
*
* @type {Array<Tag>}
* @memberof PatchedConnectivityStatement
*/
'tags'?: Array<Tag>;
/**
*
* @type {Array<Provenance>}
* @memberof PatchedConnectivityStatement
*/
'provenances'?: Array<Provenance>;
/**
*
* @type {User}
* @memberof PatchedConnectivityStatement
*/
'owner'?: User;
/**
*
* @type {number}
* @memberof PatchedConnectivityStatement
*/
'owner_id'?: number | null;
/**
*
* @type {string}
* @memberof PatchedConnectivityStatement
*/
'state'?: string;
/**
*
* @type {Array<AvailableTransitions24dEnum>}
* @memberof PatchedConnectivityStatement
*/
'available_transitions'?: Array<AvailableTransitions24dEnum>;
/**
*
* @type {Array<AnatomicalEntity>}
* @memberof PatchedConnectivityStatement
*/
'origins'?: Array<AnatomicalEntity>;
/**
*
* @type {Array<ViaSerializerDetails>}
* @memberof PatchedConnectivityStatement
*/
'vias'?: Array<ViaSerializerDetails>;
/**
*
* @type {Array<DestinationSerializerDetails>}
* @memberof PatchedConnectivityStatement
*/
'destinations'?: Array<DestinationSerializerDetails>;
/**
*
* @type {number}
* @memberof PatchedConnectivityStatement
*/
'phenotype_id'?: number | null;
/**
*
* @type {Phenotype}
* @memberof PatchedConnectivityStatement
*/
'phenotype'?: Phenotype;
/**
*
* @type {ProjectionPhenotype}
* @memberof PatchedConnectivityStatement
*/
'projection_phenotype'?: ProjectionPhenotype;
/**
*
* @type {number}
* @memberof PatchedConnectivityStatement
*/
'projection_phenotype_id'?: number | null;
/**
*
* @type {string}
* @memberof PatchedConnectivityStatement
*/
'journey'?: string;
/**
*
* @type {string}
* @memberof PatchedConnectivityStatement
*/
'entities_journey'?: string;
/**
*
* @type {ConnectivityStatementLaterality}
* @memberof PatchedConnectivityStatement
*/
'laterality'?: ConnectivityStatementLaterality | null;
/**
*
* @type {ConnectivityStatementProjection}
* @memberof PatchedConnectivityStatement
*/
'projection'?: ConnectivityStatementProjection | null;
/**
*
* @type {ConnectivityStatementCircuitType}
* @memberof PatchedConnectivityStatement
*/
'circuit_type'?: ConnectivityStatementCircuitType | null;
/**
*
* @type {Array<Specie>}
* @memberof PatchedConnectivityStatement
*/
'species'?: Array<Specie>;
/**
*
* @type {number}
* @memberof PatchedConnectivityStatement
*/
'sex_id'?: number | null;
/**
*
* @type {Sex}
* @memberof PatchedConnectivityStatement
*/
'sex'?: Sex;
/**
*
* @type {Array<number>}
* @memberof PatchedConnectivityStatement
*/
'forward_connection'?: Array<number>;
/**
*
* @type {string}
* @memberof PatchedConnectivityStatement
*/
'apinatomy_model'?: string | null;
/**
*
* @type {string}
* @memberof PatchedConnectivityStatement
*/
'additional_information'?: string | null;
/**
*
* @type {string}
* @memberof PatchedConnectivityStatement
*/
'modified_date'?: string;
/**
*
* @type {boolean}
* @memberof PatchedConnectivityStatement
*/
'has_notes'?: boolean;
/**
*
* @type {string}
* @memberof PatchedConnectivityStatement
*/
'statement_preview'?: string;
/**
*
* @type {Array<any>}
* @memberof PatchedConnectivityStatement
*/
'errors'?: Array<any>;
/**
*
* @type {GraphState}
* @memberof PatchedConnectivityStatement
*/
'graph_rendering_state'?: GraphState | null;
}
/**
* Connectivity Statement
* @export
Expand Down Expand Up @@ -2628,13 +2833,13 @@ export const ComposerApiAxiosParamCreator = function (configuration?: Configurat
/**
* ConnectivityStatement
* @param {number} id A unique integer value identifying this connectivity statement.
* @param {ConnectivityStatement} [connectivityStatement]
* @param {PatchedConnectivityStatement} [patchedConnectivityStatement]
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
composerConnectivityStatementAssignOwnerCreate: async (id: number, connectivityStatement?: ConnectivityStatement, options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
composerConnectivityStatementAssignOwnerPartialUpdate: async (id: number, patchedConnectivityStatement?: PatchedConnectivityStatement, options: AxiosRequestConfig = {}): Promise<RequestArgs> => {
// verify required parameter 'id' is not null or undefined
assertParamExists('composerConnectivityStatementAssignOwnerCreate', 'id', id)
assertParamExists('composerConnectivityStatementAssignOwnerPartialUpdate', 'id', id)
const localVarPath = `/api/composer/connectivity-statement/{id}/assign_owner/`
.replace(`{${"id"}}`, encodeURIComponent(String(id)));
// use dummy base URL string because the URL constructor only accepts absolute URLs.
Expand All @@ -2644,7 +2849,7 @@ export const ComposerApiAxiosParamCreator = function (configuration?: Configurat
baseOptions = configuration.baseOptions;
}

const localVarRequestOptions = { method: 'POST', ...baseOptions, ...options};
const localVarRequestOptions = { method: 'PATCH', ...baseOptions, ...options};
const localVarHeaderParameter = {} as any;
const localVarQueryParameter = {} as any;

Expand All @@ -2664,7 +2869,7 @@ export const ComposerApiAxiosParamCreator = function (configuration?: Configurat
setSearchParams(localVarUrlObj, localVarQueryParameter);
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
localVarRequestOptions.headers = {...localVarHeaderParameter, ...headersFromBaseOptions, ...options.headers};
localVarRequestOptions.data = serializeDataIfNeeded(connectivityStatement, localVarRequestOptions, configuration)
localVarRequestOptions.data = serializeDataIfNeeded(patchedConnectivityStatement, localVarRequestOptions, configuration)

return {
url: toPathString(localVarUrlObj),
Expand Down Expand Up @@ -5141,12 +5346,12 @@ export const ComposerApiFp = function(configuration?: Configuration) {
/**
* ConnectivityStatement
* @param {number} id A unique integer value identifying this connectivity statement.
* @param {ConnectivityStatement} [connectivityStatement]
* @param {PatchedConnectivityStatement} [patchedConnectivityStatement]
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
async composerConnectivityStatementAssignOwnerCreate(id: number, connectivityStatement?: ConnectivityStatement, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<ConnectivityStatement>> {
const localVarAxiosArgs = await localVarAxiosParamCreator.composerConnectivityStatementAssignOwnerCreate(id, connectivityStatement, options);
async composerConnectivityStatementAssignOwnerPartialUpdate(id: number, patchedConnectivityStatement?: PatchedConnectivityStatement, options?: AxiosRequestConfig): Promise<(axios?: AxiosInstance, basePath?: string) => AxiosPromise<ConnectivityStatement>> {
const localVarAxiosArgs = await localVarAxiosParamCreator.composerConnectivityStatementAssignOwnerPartialUpdate(id, patchedConnectivityStatement, options);
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration);
},
/**
Expand Down Expand Up @@ -5772,12 +5977,12 @@ export const ComposerApiFactory = function (configuration?: Configuration, baseP
/**
* ConnectivityStatement
* @param {number} id A unique integer value identifying this connectivity statement.
* @param {ConnectivityStatement} [connectivityStatement]
* @param {PatchedConnectivityStatement} [patchedConnectivityStatement]
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
composerConnectivityStatementAssignOwnerCreate(id: number, connectivityStatement?: ConnectivityStatement, options?: any): AxiosPromise<ConnectivityStatement> {
return localVarFp.composerConnectivityStatementAssignOwnerCreate(id, connectivityStatement, options).then((request) => request(axios, basePath));
composerConnectivityStatementAssignOwnerPartialUpdate(id: number, patchedConnectivityStatement?: PatchedConnectivityStatement, options?: any): AxiosPromise<ConnectivityStatement> {
return localVarFp.composerConnectivityStatementAssignOwnerPartialUpdate(id, patchedConnectivityStatement, options).then((request) => request(axios, basePath));
},
/**
* ConnectivityStatement
Expand Down Expand Up @@ -6361,13 +6566,13 @@ export class ComposerApi extends BaseAPI {
/**
* ConnectivityStatement
* @param {number} id A unique integer value identifying this connectivity statement.
* @param {ConnectivityStatement} [connectivityStatement]
* @param {PatchedConnectivityStatement} [patchedConnectivityStatement]
* @param {*} [options] Override http request option.
* @throws {RequiredError}
* @memberof ComposerApi
*/
public composerConnectivityStatementAssignOwnerCreate(id: number, connectivityStatement?: ConnectivityStatement, options?: AxiosRequestConfig) {
return ComposerApiFp(this.configuration).composerConnectivityStatementAssignOwnerCreate(id, connectivityStatement, options).then((request) => request(this.axios, this.basePath));
public composerConnectivityStatementAssignOwnerPartialUpdate(id: number, patchedConnectivityStatement?: PatchedConnectivityStatement, options?: AxiosRequestConfig) {
return ComposerApiFp(this.configuration).composerConnectivityStatementAssignOwnerPartialUpdate(id, patchedConnectivityStatement, options).then((request) => request(this.axios, this.basePath));
}

/**
Expand Down
11 changes: 4 additions & 7 deletions frontend/src/components/Forms/FormBase.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ export const FormBase = (props: any) => {
showErrorList,
submitOnChangeFields = [],
submitOnBlurFields = [],
onErrorAction,
onUnauthorizedSave: onSaveCancel,
} = props;
const [localData, setLocalData] = useState<any>(data);
const [isSaving, setIsSaving] = useState<boolean>(false);
Expand Down Expand Up @@ -104,9 +104,10 @@ export const FormBase = (props: any) => {

const handleSubmit = async (event: IChangeEvent) => {
const formData = {...event.formData, ...extraData};
const saveOptions = onSaveCancel ? { onCancel: onSaveCancel } : {};
setIsSaving(true);
service
.save(formData)
.save(formData, saveOptions)
.then((newData: any) => {
setter && setter(newData);
// todo: improve UI feedback
Expand All @@ -117,11 +118,7 @@ export const FormBase = (props: any) => {
setLocalData(formData);
})
.catch((error: any) => {
if (onErrorAction) {
onErrorAction(error, formData); // Custom error handling
} else {
log(`Something went wrong ${error}`); // Default error handling
}
log(`Something went wrong ${error}`); // Default error handling
})
.finally(() => {
setIsSaving(false);
Expand Down
12 changes: 1 addition & 11 deletions frontend/src/components/Forms/StatementForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -700,21 +700,12 @@ const StatementForm = (props: any) => {
SelectWidget: CustomSingleSelect,
};

const handleErrorAction = (error: any, newStatementData: ConnectivityStatement) => {
checkOwnership(
statement.id,
(fetchedData, userId) => statementService.save({...newStatementData, owner_id: userId})
.then(() => refreshStatement()),
() => refreshStatement(),
(owner) => getOwnershipAlertMessage(owner)
);
};


return (
<FormBase
data={statement}
service={statementService}
onSaveCancel={refreshStatement}
schema={copiedSchema}
uiSchema={copiedUISchema}
uiFields={uiFields}
Expand All @@ -735,7 +726,6 @@ const StatementForm = (props: any) => {
"projection",
"projection_phenotype_id",
]}
onErrorAction={(error: any, formData: any) => handleErrorAction(error, formData)}
{...props}
/>
);
Expand Down
Loading

0 comments on commit f7c5f1b

Please sign in to comment.