it is currently not clear to me what the frontend needs to do in order to correctly update a workflow and its associated steps. it would be very helpful to have some documentation on this.
to be more concrete, this is one of the issues i am currently running into:
a user wants to create a new workflow and clicks "Create workflow" to open the form
the user fills the mandatory fields "label" and "description" for the workflow, and adds two workflow steps, also with "label" and "description"
the user clicks "Save as draft"
since we cannot save workflow+steps in one request, the frontend will now
dispatch POST /api/workflows?draft=true to create a new workflow, and keep the persistentId of the returned workflow in state
for every step, we dispatch POST /api/workflows/:persistentId/steps?draft=true (with the workflow's persistentId we just saved, and set the stepNo in the payload). we also keep the persistentIds of the newly created steps in state, because we will need them later
so far all is good, we have created a draft workflow with two steps and the user will see a "Successfully saved draft workflow" message
the user then decides to (maybe after editing some stuff) click "Save as draft" again
since we have already created a new workflow (we know this because we have kept its persistentId around), we update the existing workflow with PUT /api/workflows/:persistentId?draft=true
we then loop over all the steps existing in the form, and for every step we
check if we have already created that step (we know this because we have kept the persistentIds of created steps around)
if yes, we update the step with PUT /api/workflows/:persistentId/steps/:stepPersistentId?draft=true (again, we also provide the stepNo in the payload)
if no, we create a new step with POST /api/workflows/:persistentId/steps?draft=true (again, we also provide the stepNo in the payload)
we also need to check if the user has maybe deleted a step since saving the last draft, and dispatch DELETE /api/workflows/:persistentId/steps/:stepPersistentId?draft=true for every stepPersistentId that no longer exists in the form
when doing the above, i expect - after saving as draft twice - that the draft workflow will have two steps. HOWEVER we actually end up with a workflow with four steps: two pairs of duplicate steps.
In GitLab by @stefanprobst on Feb 4, 2022, 11:54
it is currently not clear to me what the frontend needs to do in order to correctly update a workflow and its associated steps. it would be very helpful to have some documentation on this.
to be more concrete, this is one of the issues i am currently running into:
POST /api/workflows?draft=true
to create a new workflow, and keep thepersistentId
of the returned workflow in statePOST /api/workflows/:persistentId/steps?draft=true
(with the workflow'spersistentId
we just saved, and set thestepNo
in the payload). we also keep thepersistentId
s of the newly created steps in state, because we will need them laterPUT /api/workflows/:persistentId?draft=true
PUT /api/workflows/:persistentId/steps/:stepPersistentId?draft=true
(again, we also provide thestepNo
in the payload)POST /api/workflows/:persistentId/steps?draft=true
(again, we also provide thestepNo
in the payload)DELETE /api/workflows/:persistentId/steps/:stepPersistentId?draft=true
for every stepPersistentId that no longer exists in the formwhat am i doing wrong here?
here's what the draft workflow looks like after the first "Save as draft"
```json { "id": 52, "category": "workflow", "label": "workflow", "persistentId": "la4jjM", "lastInfoUpdate": "2022-02-04T10:48:07+0000", "status": "draft", "informationContributor": { "id": 1, "username": "Administrator", "displayName": "Administrator", "status": "enabled", "registrationDate": "2020-08-04T12:29:00+0000", "role": "administrator", "email": "administrator@example.com", "config": true }, "description": "workflow", "contributors": [], "properties": [], "externalIds": [], "accessibleAt": [], "relatedItems": [], "media": [], "composedOf": [ { "id": 53, "category": "step", "label": "first step", "persistentId": "GjkpzS", "lastInfoUpdate": "2022-02-04T10:48:08+0000", "status": "draft", "informationContributor": { "id": 1, "username": "Administrator", "displayName": "Administrator", "status": "enabled", "registrationDate": "2020-08-04T12:29:00+0000", "role": "administrator", "email": "administrator@example.com", "config": true }, "description": "first step", "contributors": [], "properties": [], "externalIds": [], "accessibleAt": [], "relatedItems": [], "media": [], "composedOf": [] }, { "id": 54, "category": "step", "label": "second step", "persistentId": "FueAzf", "lastInfoUpdate": "2022-02-04T10:48:08+0000", "status": "draft", "informationContributor": { "id": 1, "username": "Administrator", "displayName": "Administrator", "status": "enabled", "registrationDate": "2020-08-04T12:29:00+0000", "role": "administrator", "email": "administrator@example.com", "config": true }, "description": "second step", "contributors": [], "properties": [], "externalIds": [], "accessibleAt": [], "relatedItems": [], "media": [], "composedOf": [] } ] } ```here's what the draft workflow looks like after the second "Save as draft" (nothing was edited since)
```json { "id": 52, "category": "workflow", "label": "workflow", "persistentId": "la4jjM", "lastInfoUpdate": "2022-02-04T10:49:03+0000", "status": "draft", "informationContributor": { "id": 1, "username": "Administrator", "displayName": "Administrator", "status": "enabled", "registrationDate": "2020-08-04T12:29:00+0000", "role": "administrator", "email": "administrator@example.com", "config": true }, "description": "workflow", "contributors": [], "properties": [], "externalIds": [], "accessibleAt": [], "relatedItems": [], "media": [], "composedOf": [ { "id": 53, "category": "step", "label": "first step", "persistentId": "GjkpzS", "lastInfoUpdate": "2022-02-04T10:49:03+0000", "status": "draft", "informationContributor": { "id": 1, "username": "Administrator", "displayName": "Administrator", "status": "enabled", "registrationDate": "2020-08-04T12:29:00+0000", "role": "administrator", "email": "administrator@example.com", "config": true }, "description": "first step", "contributors": [], "properties": [], "externalIds": [], "accessibleAt": [], "relatedItems": [], "media": [], "composedOf": [] }, { "id": 54, "category": "step", "label": "second step", "persistentId": "FueAzf", "lastInfoUpdate": "2022-02-04T10:49:03+0000", "status": "draft", "informationContributor": { "id": 1, "username": "Administrator", "displayName": "Administrator", "status": "enabled", "registrationDate": "2020-08-04T12:29:00+0000", "role": "administrator", "email": "administrator@example.com", "config": true }, "description": "second step", "contributors": [], "properties": [], "externalIds": [], "accessibleAt": [], "relatedItems": [], "media": [], "composedOf": [] }, { "id": 53, "category": "step", "label": "first step", "persistentId": "GjkpzS", "lastInfoUpdate": "2022-02-04T10:49:03+0000", "status": "draft", "informationContributor": { "id": 1, "username": "Administrator", "displayName": "Administrator", "status": "enabled", "registrationDate": "2020-08-04T12:29:00+0000", "role": "administrator", "email": "administrator@example.com", "config": true }, "description": "first step", "contributors": [], "properties": [], "externalIds": [], "accessibleAt": [], "relatedItems": [], "media": [], "composedOf": [] }, { "id": 54, "category": "step", "label": "second step", "persistentId": "FueAzf", "lastInfoUpdate": "2022-02-04T10:49:03+0000", "status": "draft", "informationContributor": { "id": 1, "username": "Administrator", "displayName": "Administrator", "status": "enabled", "registrationDate": "2020-08-04T12:29:00+0000", "role": "administrator", "email": "administrator@example.com", "config": true }, "description": "second step", "contributors": [], "properties": [], "externalIds": [], "accessibleAt": [], "relatedItems": [], "media": [], "composedOf": [] } ] } ```