Skip to content

Commit ead8d85

Browse files
authored
Implement edit metadata definition (#977)
* initial draft * fix react state mutation issue * fix black formatting * Added check not to edit definition if metadata exists and addressed feedbacks
1 parent eaeec68 commit ead8d85

File tree

11 files changed

+802
-3
lines changed

11 files changed

+802
-3
lines changed

backend/app/models/metadata.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ class MetadataDefinitionBase(BaseModel):
104104
] # https://json-ld.org/spec/latest/json-ld/#the-context
105105
context_url: Optional[str] # single URL applying to contents
106106
fields: List[MetadataField]
107+
modified: datetime = Field(default_factory=datetime.utcnow)
107108

108109
# TODO: Space-level requirements?
109110

backend/app/routers/metadata.py

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import datetime
12
from typing import Optional
23

34
from app import dependencies
@@ -70,6 +71,62 @@ async def get_metadata_definition_list(
7071
return page.dict()
7172

7273

74+
@router.put(
75+
"/definition/{metadata_definition_id}", response_model=MetadataDefinitionOut
76+
)
77+
async def update_metadata_definition(
78+
metadata_definition: MetadataDefinitionIn,
79+
metadata_definition_id: str,
80+
user=Depends(get_current_user),
81+
):
82+
existing_count = await MetadataDefinitionDB.find(
83+
{
84+
"$and": [
85+
{"_id": {"$ne": PydanticObjectId(metadata_definition_id)}},
86+
{"name": {"$eq": metadata_definition.name}},
87+
]
88+
}
89+
).count()
90+
if existing_count > 0:
91+
raise HTTPException(
92+
status_code=409,
93+
detail=f"Metadata definition named {metadata_definition.name} already exists.",
94+
)
95+
else:
96+
if (
97+
mdd := await MetadataDefinitionDB.get(
98+
PydanticObjectId(metadata_definition_id)
99+
)
100+
) is not None:
101+
# Check if metadata using this definition exists
102+
metadata_using_definition = await MetadataDB.find(
103+
MetadataDB.definition == mdd.name
104+
).to_list()
105+
106+
if len(metadata_using_definition) > 0:
107+
raise HTTPException(
108+
status_code=400,
109+
detail=f"Metadata definition: {mdd.name} ({metadata_definition_id}) in use. "
110+
f"You cannot edit it if there are existing metadata using this definition.",
111+
)
112+
try:
113+
metadata_update = metadata_definition.dict()
114+
metadata_update["modified"] = datetime.datetime.utcnow()
115+
116+
# Update mdd's attributes using the updated dictionary
117+
for key, value in metadata_update.items():
118+
setattr(mdd, key, value)
119+
await mdd.save()
120+
return mdd.dict()
121+
except Exception as e:
122+
raise HTTPException(status_code=500, detail=e.args[0])
123+
else:
124+
raise HTTPException(
125+
status_code=404,
126+
detail=f"Metadata definition id {metadata_definition_id} not found",
127+
)
128+
129+
73130
@router.get(
74131
"/definition/{metadata_definition_id}", response_model=MetadataDefinitionOut
75132
)

frontend/src/actions/metadata.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,29 @@ export function postMetadataDefinition(metadataDefinition) {
9797
};
9898
}
9999

100+
export const EDIT_METADATA_DEFINITION = "EDIT_METADATA_DEFINITION";
101+
102+
export function updateMetadataDefinition(id, metadataDefinition) {
103+
return (dispatch) => {
104+
return V2.MetadataService.updateMetadataDefinitionApiV2MetadataDefinitionMetadataDefinitionIdPut(
105+
id,
106+
metadataDefinition
107+
)
108+
.then((json) => {
109+
dispatch({
110+
type: EDIT_METADATA_DEFINITION,
111+
metadataDefinition: json,
112+
receivedAt: Date.now(),
113+
});
114+
})
115+
.catch((reason) => {
116+
dispatch(
117+
handleErrors(reason, updateMetadataDefinition(id, metadataDefinition))
118+
);
119+
});
120+
};
121+
}
122+
100123
export const RESET_SAVE_METADATA_DEFINITIONS =
101124
"RESET_SAVE_METADATA_DEFINITIONS";
102125

0 commit comments

Comments
 (0)