Skip to content

Commit

Permalink
Editing the schedule (#770)
Browse files Browse the repository at this point in the history
* Create popup component to edit or delete events

Signed-off-by: angatupyry <fierrofenix@gmail.com>

* Create popup component to edit or delete events

Signed-off-by: angatupyry <fierrofenix@gmail.com>

* Adding popup to edit events

Signed-off-by: angatupyry <fierrofenix@gmail.com>

* Enable or disable cells

Signed-off-by: angatupyry <fierrofenix@gmail.com>

* Add schedule and openSchedulepopup props

Signed-off-by: angatupyry <fierrofenix@gmail.com>

* Open create task form in edit event

Signed-off-by: angatupyry <fierrofenix@gmail.com>

* Update entire schedule

Signed-off-by: angatupyry <fierrofenix@gmail.com>

* Update entire schedule

Signed-off-by: angatupyry <fierrofenix@gmail.com>

* Fix endpoint to receive task request

Signed-off-by: angatupyry <fierrofenix@gmail.com>

* Remove unnecesary function and rename props

Signed-off-by: angatupyry <fierrofenix@gmail.com>

* Create hooks to reuse function

Signed-off-by: angatupyry <fierrofenix@gmail.com>

* Editing entire schedule

Signed-off-by: angatupyry <fierrofenix@gmail.com>

* Using custom hook

Signed-off-by: angatupyry <fierrofenix@gmail.com>

* Repeated functions sends to utils file

Signed-off-by: angatupyry <fierrofenix@gmail.com>

* Create method to handle editing single event

Signed-off-by: angatupyry <fierrofenix@gmail.com>

* Add utils file to be more cleaner

Signed-off-by: angatupyry <fierrofenix@gmail.com>

* Setting on or never depending of the schedule value

Signed-off-by: angatupyry <fierrofenix@gmail.com>

* Editing single event

Signed-off-by: angatupyry <fierrofenix@gmail.com>

* Create a custom hook to get username

Signed-off-by: angatupyry <fierrofenix@gmail.com>

* Use custom hook to get usernmae

Signed-off-by: angatupyry <fierrofenix@gmail.com>

* Disabling cells without events

Signed-off-by: angatupyry <fierrofenix@gmail.com>

* Add test for new component

Signed-off-by: angatupyry <fierrofenix@gmail.com>

* Test created

Signed-off-by: angatupyry <fierrofenix@gmail.com>

* Order status according to meaning and use ref instead of state to set the current event id

Signed-off-by: angatupyry <fierrofenix@gmail.com>

* End of day using insted of end of minutes in until date

Signed-off-by: angatupyry <fierrofenix@gmail.com>

* Set current state when click onSubmit button

Signed-off-by: angatupyry <fierrofenix@gmail.com>

* Refresh events after sending submit and after close create task form

Signed-off-by: angatupyry <fierrofenix@gmail.com>

* Fix bug editing entire events

Signed-off-by: angatupyry <fierrofenix@gmail.com>

* Setting except dates as empty in editing mode

Signed-off-by: angatupyry <fierrofenix@gmail.com>

* Separete scheduled component and tasks

Signed-off-by: angatupyry <fierrofenix@gmail.com>

* Add explanation comment in new route

Signed-off-by: angatupyry <fierrofenix@gmail.com>

* Default cursor in cells without events

Signed-off-by: angatupyry <fierrofenix@gmail.com>

* Using the same terminology between edit and delete.

Signed-off-by: angatupyry <fierrofenix@gmail.com>

* Rename file name to be more descriptive

Signed-off-by: angatupyry <fierrofenix@gmail.com>

* Change name of Radio group

Signed-off-by: angatupyry <fierrofenix@gmail.com>

* Move function from utils to task/utils since it is related to just tasks

Signed-off-by: angatupyry <fierrofenix@gmail.com>

* Rename component name to be more descriptive

Signed-off-by: angatupyry <fierrofenix@gmail.com>

* Fix test accoriing to changes on the component

Signed-off-by: angatupyry <fierrofenix@gmail.com>

* Delete unnecesary props

Signed-off-by: angatupyry <fierrofenix@gmail.com>

* Rename props to be more descriptive

Signed-off-by: angatupyry <fierrofenix@gmail.com>

* Some minor changes to be more descriptive and clear

Signed-off-by: angatupyry <fierrofenix@gmail.com>

* Make comments a little more descriptive, instead of pseudocode.

Signed-off-by: angatupyry <fierrofenix@gmail.com>

* Add at time in schedule interface to set the time correctly

Signed-off-by: angatupyry <fierrofenix@gmail.com>

---------

Signed-off-by: angatupyry <fierrofenix@gmail.com>
  • Loading branch information
Angatupyry authored Sep 19, 2023
1 parent c885e3d commit a3f3615
Show file tree
Hide file tree
Showing 15 changed files with 975 additions and 362 deletions.
142 changes: 142 additions & 0 deletions packages/api-client/lib/openapi/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8431,6 +8431,69 @@ export const TasksApiAxiosParamCreator = function (configuration?: Configuration
...options.headers,
};

return {
url: toPathString(localVarUrlObj),
options: localVarRequestOptions,
};
},
/**
*
* @summary Update Schedule Task
* @param {number} taskId
* @param {PostScheduledTaskRequest} postScheduledTaskRequest
* @param {string} [exceptDate]
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
updateScheduleTaskScheduledTasksTaskIdUpdatePost: async (
taskId: number,
postScheduledTaskRequest: PostScheduledTaskRequest,
exceptDate?: string,
options: AxiosRequestConfig = {},
): Promise<RequestArgs> => {
// verify required parameter 'taskId' is not null or undefined
assertParamExists('updateScheduleTaskScheduledTasksTaskIdUpdatePost', 'taskId', taskId);
// verify required parameter 'postScheduledTaskRequest' is not null or undefined
assertParamExists(
'updateScheduleTaskScheduledTasksTaskIdUpdatePost',
'postScheduledTaskRequest',
postScheduledTaskRequest,
);
const localVarPath = `/scheduled_tasks/{task_id}/update`.replace(
`{${'task_id'}}`,
encodeURIComponent(String(taskId)),
);
// use dummy base URL string because the URL constructor only accepts absolute URLs.
const localVarUrlObj = new URL(localVarPath, DUMMY_BASE_URL);
let baseOptions;
if (configuration) {
baseOptions = configuration.baseOptions;
}

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

if (exceptDate !== undefined) {
localVarQueryParameter['except_date'] =
(exceptDate as any) instanceof Date ? (exceptDate as any).toISOString() : exceptDate;
}

localVarHeaderParameter['Content-Type'] = 'application/json';

setSearchParams(localVarUrlObj, localVarQueryParameter);
let headersFromBaseOptions = baseOptions && baseOptions.headers ? baseOptions.headers : {};
localVarRequestOptions.headers = {
...localVarHeaderParameter,
...headersFromBaseOptions,
...options.headers,
};
localVarRequestOptions.data = serializeDataIfNeeded(
postScheduledTaskRequest,
localVarRequestOptions,
configuration,
);

return {
url: toPathString(localVarUrlObj),
options: localVarRequestOptions,
Expand Down Expand Up @@ -8891,6 +8954,35 @@ export const TasksApiFp = function (configuration?: Configuration) {
);
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration);
},
/**
*
* @summary Update Schedule Task
* @param {number} taskId
* @param {PostScheduledTaskRequest} postScheduledTaskRequest
* @param {string} [exceptDate]
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
async updateScheduleTaskScheduledTasksTaskIdUpdatePost(
taskId: number,
postScheduledTaskRequest: PostScheduledTaskRequest,
exceptDate?: string,
options?: AxiosRequestConfig,
): Promise<
(
axios?: AxiosInstance,
basePath?: string,
) => AxiosPromise<ApiServerModelsTortoiseModelsScheduledTaskScheduledTask>
> {
const localVarAxiosArgs =
await localVarAxiosParamCreator.updateScheduleTaskScheduledTasksTaskIdUpdatePost(
taskId,
postScheduledTaskRequest,
exceptDate,
options,
);
return createRequestFunction(localVarAxiosArgs, globalAxios, BASE_PATH, configuration);
},
};
};

Expand Down Expand Up @@ -9271,6 +9363,30 @@ export const TasksApiFactory = function (
)
.then((request) => request(axios, basePath));
},
/**
*
* @summary Update Schedule Task
* @param {number} taskId
* @param {PostScheduledTaskRequest} postScheduledTaskRequest
* @param {string} [exceptDate]
* @param {*} [options] Override http request option.
* @throws {RequiredError}
*/
updateScheduleTaskScheduledTasksTaskIdUpdatePost(
taskId: number,
postScheduledTaskRequest: PostScheduledTaskRequest,
exceptDate?: string,
options?: any,
): AxiosPromise<ApiServerModelsTortoiseModelsScheduledTaskScheduledTask> {
return localVarFp
.updateScheduleTaskScheduledTasksTaskIdUpdatePost(
taskId,
postScheduledTaskRequest,
exceptDate,
options,
)
.then((request) => request(axios, basePath));
},
};
};

Expand Down Expand Up @@ -9680,4 +9796,30 @@ export class TasksApi extends BaseAPI {
)
.then((request) => request(this.axios, this.basePath));
}

/**
*
* @summary Update Schedule Task
* @param {number} taskId
* @param {PostScheduledTaskRequest} postScheduledTaskRequest
* @param {string} [exceptDate]
* @param {*} [options] Override http request option.
* @throws {RequiredError}
* @memberof TasksApi
*/
public updateScheduleTaskScheduledTasksTaskIdUpdatePost(
taskId: number,
postScheduledTaskRequest: PostScheduledTaskRequest,
exceptDate?: string,
options?: AxiosRequestConfig,
) {
return TasksApiFp(this.configuration)
.updateScheduleTaskScheduledTasksTaskIdUpdatePost(
taskId,
postScheduledTaskRequest,
exceptDate,
options,
)
.then((request) => request(this.axios, this.basePath));
}
}
2 changes: 1 addition & 1 deletion packages/api-client/lib/version.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ import { version as rmfModelVer } from 'rmf-models';

export const version = {
rmfModels: rmfModelVer,
rmfServer: 'c8c43e395caae7ccc858008b7663d30914b2cc62',
rmfServer: '60cfa28fb26433cb33254ba1522fc00466fe7146',
openapiGenerator: '6.2.1',
};
47 changes: 47 additions & 0 deletions packages/api-client/schema/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1283,6 +1283,53 @@ export default {
},
},
},
'/scheduled_tasks/{task_id}/update': {
post: {
tags: ['Tasks'],
summary: 'Update Schedule Task',
operationId: 'update_schedule_task_scheduled_tasks__task_id__update_post',
parameters: [
{
required: true,
schema: { title: 'Task Id', type: 'integer' },
name: 'task_id',
in: 'path',
},
{
required: false,
schema: { title: 'Except Date', type: 'string', format: 'date-time' },
name: 'except_date',
in: 'query',
},
],
requestBody: {
content: {
'application/json': {
schema: { $ref: '#/components/schemas/PostScheduledTaskRequest' },
},
},
required: true,
},
responses: {
'201': {
description: 'Successful Response',
content: {
'application/json': {
schema: {
$ref: '#/components/schemas/api_server.models.tortoise_models.scheduled_task.ScheduledTask',
},
},
},
},
'422': {
description: 'Validation Error',
content: {
'application/json': { schema: { $ref: '#/components/schemas/HTTPValidationError' } },
},
},
},
},
},
'/favorite_tasks': {
get: {
tags: ['Tasks'],
Expand Down
77 changes: 77 additions & 0 deletions packages/api-server/api_server/routes/tasks/scheduled_tasks.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import asyncio
from datetime import datetime
from typing import Optional

import schedule
import tortoise.transactions
Expand Down Expand Up @@ -159,6 +160,82 @@ async def del_scheduled_tasks_event(
await schedule_task(task, task_repo)


@router.post(
"/{task_id}/update", status_code=201, response_model=ttm.ScheduledTaskPydantic
)
async def update_schedule_task(
task_id: int,
scheduled_task_request: PostScheduledTaskRequest,
except_date: Optional[datetime] = None,
task_repo: TaskRepository = Depends(task_repo_dep),
):
try:
task = await get_scheduled_task(task_id)
if task is None:
raise HTTPException(404)
# If "except_date" is provided, it means a single event is being updated.
# In this case, we perform the following steps:
# 1. Add the "except_date" to the list of exception dates for the task.
# 2. Clear all existing schedules associated with the task.
# 3. Create a new scheduled task with the requested data from the schedule form.

async with tortoise.transactions.in_transaction():
if except_date:
task.except_dates.append(datetime_to_date_format(except_date))
await task.save()

for sche in task.schedules:
schedule.clear(sche.get_id())

await schedule_task(task, task_repo)

scheduled_task = await ttm.ScheduledTask.create(
task_request=scheduled_task_request.task_request.json(
exclude_none=True
),
created_by=task.created_by,
)
schedules = [
ttm.ScheduledTaskSchedule(scheduled_task=scheduled_task, **x.dict())
for x in scheduled_task_request.schedules
]
await ttm.ScheduledTaskSchedule.bulk_create(schedules)

await schedule_task(scheduled_task, task_repo)
else:
# If "except_date" is not provided, it means the entire series is being updated.
# In this case, we perform the following steps:
# 1. Update the task with the requested data from the schedule form and clear exception dates.
# 2. Clear all existing schedules associated with the task.
# 3. Delete all existing schedules associated with the task.
# 4. Create new schedules based on the requested data.
task.update_from_dict(
{
"task_request": scheduled_task_request.task_request.json(
exclude_none=True
),
"except_dates": [],
}
)

for sche in task.schedules:
schedule.clear(sche.get_id())
for sche in task.schedules:
await sche.delete()

await task.save()
schedules = [
ttm.ScheduledTaskSchedule(scheduled_task=task, **x.dict())
for x in scheduled_task_request.schedules
]

await ttm.ScheduledTaskSchedule.bulk_create(schedules)

await schedule_task(task, task_repo)
except schedule.ScheduleError as e:
raise HTTPException(422, str(e)) from e


@router.delete("/{task_id}")
async def del_scheduled_tasks(task_id: int):
async with tortoise.transactions.in_transaction():
Expand Down
Loading

0 comments on commit a3f3615

Please sign in to comment.