appender events and applications are updated

This commit is contained in:
Berkay 2025-05-06 12:03:58 +03:00
parent dd707b2463
commit e0ae1ee80a
53 changed files with 2358 additions and 829 deletions

View File

@ -5,8 +5,10 @@ from fastapi.responses import RedirectResponse
cluster_is_set = False cluster_is_set = False
def create_events_if_any_cluster_set(): def create_events_if_any_cluster_set():
import Events import Events
global cluster_is_set global cluster_is_set
if not Events.__all__ or cluster_is_set: if not Events.__all__ or cluster_is_set:
return return

View File

@ -1,12 +1,12 @@
from Controllers.Postgres.database import get_db from Controllers.Postgres.database import get_db
from Schemas import Users, Employees, BuildLivingSpace from Schemas import Users, Employees, BuildLivingSpace, Services
from init_service_to_events import init_service_to_event_matches_for_super_user from init_service_to_events import init_service_to_event_matches_for_super_user
from init_applications import ( from init_applications import (
init_applications_for_super_user, init_applications_for_super_user,
init_applications_for_general_manager, # init_applications_for_general_manager,
init_applications_for_build_manager, # init_applications_for_build_manager,
init_applications_for_owner, # init_applications_for_owner,
init_applications_for_tenant, # init_applications_for_tenant,
) )
@ -16,62 +16,59 @@ if __name__ == "__main__":
Set Events to service | Set Service to employee Set Events to service | Set Service to employee
""" """
with get_db() as db_session: with get_db() as db_session:
if super_man := Users.filter_one( service_super_user = Services.filter_one(Services.service_code == "SRE-SUE", db=db_session).data
Users.email == "karatay.berkay.sup@evyos.com.tr", db=db_session user_super_user = Users.filter_one(Users.email == "karatay.berkay.sup@evyos.com.tr", db=db_session).data
).data: employee_super_user = Employees.filter_one(Employees.people_id == user_super_user.person_id, db=db_session).data
super_employee = Employees.filter_one( if service_super_user and user_super_user and employee_super_user:
Employees.people_id == super_man.person_id, db=db_session
).data
init_service_to_event_matches_for_super_user( init_service_to_event_matches_for_super_user(
super_user=super_employee, db_session=db_session service_match=service_super_user, employee_match=employee_super_user, db_session=db_session
) )
init_applications_for_super_user( init_applications_for_super_user(
super_user=super_employee, db_session=db_session service_match=service_super_user, employee_match=employee_super_user, db_session=db_session
) )
with get_db() as db_session: # with get_db() as db_session:
print("Createing GM") # print("Createing GM")
if gen_man := Users.filter_one( # if gen_man := Users.filter_one(
Users.email == "example.general@evyos.com.tr", db=db_session # Users.email == "example.general@evyos.com.tr", db=db_session
).data: # ).data:
gen_man_employee = Employees.filter_one( # gen_man_employee = Employees.filter_one(
Employees.people_id == gen_man.person_id, db=db_session # Employees.people_id == gen_man.person_id, db=db_session
).data # ).data
print("General Manager : ", gen_man_employee) # print("General Manager : ", gen_man_employee)
init_applications_for_general_manager( # init_applications_for_general_manager(
super_user=gen_man_employee, db_session=db_session # super_user=gen_man_employee, db_session=db_session
) # )
with get_db() as db_session: # with get_db() as db_session:
if build_man := Users.filter_one( # if build_man := Users.filter_one(
Users.email == "example.build.manager@gmail.com", db=db_session # Users.email == "example.build.manager@gmail.com", db=db_session
).data: # ).data:
build_man_employee = BuildLivingSpace.filter_one( # build_man_employee = BuildLivingSpace.filter_one(
BuildLivingSpace.person_id == build_man.person_id, db=db_session # BuildLivingSpace.person_id == build_man.person_id, db=db_session
).data # ).data
init_applications_for_build_manager( # init_applications_for_build_manager(
super_user=build_man_employee, db_session=db_session # super_user=build_man_employee, db_session=db_session
) # )
with get_db() as db_session: # with get_db() as db_session:
if own_flt := Users.filter_one( # if own_flt := Users.filter_one(
Users.email == "example.owner@gmail.com", db=db_session # Users.email == "example.owner@gmail.com", db=db_session
).data: # ).data:
own_flt_employee = BuildLivingSpace.filter_one( # own_flt_employee = BuildLivingSpace.filter_one(
BuildLivingSpace.person_id == own_flt.person_id, db=db_session # BuildLivingSpace.person_id == own_flt.person_id, db=db_session
).data # ).data
init_applications_for_owner( # init_applications_for_owner(
super_user=own_flt_employee, db_session=db_session # super_user=own_flt_employee, db_session=db_session
) # )
with get_db() as db_session: # with get_db() as db_session:
if ten_flt := Users.filter_one( # if ten_flt := Users.filter_one(
Users.email == "example.tenant@gmail.com", db=db_session # Users.email == "example.tenant@gmail.com", db=db_session
).data: # ).data:
ten_flt_employee = BuildLivingSpace.filter_one( # ten_flt_employee = BuildLivingSpace.filter_one(
BuildLivingSpace.person_id == ten_flt.person_id, db=db_session # BuildLivingSpace.person_id == ten_flt.person_id, db=db_session
).data # ).data
init_applications_for_tenant( # init_applications_for_tenant(
super_user=ten_flt_employee, db_session=db_session # super_user=ten_flt_employee, db_session=db_session
) # )

View File

@ -4,222 +4,193 @@ from Schemas import (
Application2Occupant, Application2Occupant,
Employees, Employees,
BuildLivingSpace, BuildLivingSpace,
Services,
Service2Application,
) )
def init_applications_for_super_user(super_user: Employees, db_session=None) -> None: def init_applications_for_super_user(service_match: Services, employee_match: Employees, db_session=None) -> None:
list_of_created_apps = [ list_of_all_events = Applications.filter_all(db=db_session).data
dict( Service2Application.filter_all(db=db_session).query.delete()
name="Dashboard1", Service2Application.save(db=db_session)
application_code="app000001",
site_url="/dashboard", for list_of_event_code in list_of_all_events:
application_type="info", service_to_event_found = Service2Application.filter_one_system(
description="Dashboard Page", Service2Application.application_id == list_of_event_code.id,
), Service2Application.service_id == service_match.id,
dict(
name="Individual",
application_code="app000003",
site_url="/individual",
application_type="Dash",
description="Individual Page for people",
),
dict(
name="User",
application_code="app000004",
site_url="/user",
application_type="Dash",
description="Individual Page for user",
),
dict(
name="Build",
application_code="app000005",
site_url="/build",
application_type="Dash",
description="Individual Page for build",
),
dict(
name="BuildParts",
application_code="app000006",
site_url="/build/parts",
application_type="Dash",
description="Individual Page for build parts",
),
dict(
name="BuildArea",
application_code="app000007",
site_url="/build/area",
application_type="Dash",
description="Individual Page for build area",
),
dict(
name="ManagementAccounting",
application_code="app000008",
site_url="/management/accounting",
application_type="Dash",
description="Individual Page for management accounting",
),
dict(
name="ManagementBudget",
application_code="app000009",
site_url="/management/budget",
application_type="Dash",
description="Individual Page for management accounting2",
),
dict(
name="ManagementMeetingClose",
application_code="app000010",
site_url="/annual/meeting/close",
application_type="Dash",
description="Individual Page for management accounting3",
),
dict(
name="EmergencyMeeting",
application_code="app000011",
site_url="/emergency/meeting",
application_type="Dash",
description="Individual Page for management accounting4",
),
dict(
name="EmergencyMeetingClose",
application_code="app000012",
site_url="/emergency/meeting/close",
application_type="Dash",
description="Individual Page for management accounting5",
),
dict(
name="MeetingParticipation",
application_code="app000013",
site_url="/meeting/participation",
application_type="Dash",
description="Individual Page for management accounting6",
),
]
for list_of_created_app in list_of_created_apps:
created_page = Applications.find_or_create(
**list_of_created_app,
db=db_session, db=db_session,
)
if service_to_event_found.data:
service_to_event_found.destroy(db=db_session)
print(
f"UUID: {service_to_event_found.uu_id} application is deleted from {service_match.service_description}"
)
employee_added_application = Service2Application.find_or_create(
service_id=service_match.id,
service_uu_id=str(service_match.uu_id),
application_id=list_of_event_code.id,
application_uu_id=str(list_of_event_code.uu_id),
application_code=list_of_event_code.application_code,
site_url=list_of_event_code.site_url,
is_confirmed=True, is_confirmed=True,
) active=True,
if created_page.meta_data.created:
created_page.save(db=db_session)
application_employee_created = Application2Employee.find_or_create(
employee_id=super_user.id,
employee_uu_id=str(super_user.uu_id),
site_url=created_page.site_url,
application_code=created_page.application_code,
application_id=created_page.id,
application_uu_id=str(created_page.uu_id),
is_confirmed=True,
db=db_session, db=db_session,
) )
if application_employee_created.meta_data.created: if employee_added_application.meta_data.created:
application_employee_created.save(db=db_session) employee_added_application.save(db=db_session)
print(
f"UUID: {employee_added_application.uu_id} application is saved to {service_match.service_description}"
)
employee_added_service = Application2Employee.find_or_create(
def init_applications_for_general_manager( service_id=service_match.id,
super_user: Employees, db_session=None service_uu_id=str(service_match.uu_id),
) -> None: employee_id=employee_match.id,
list_of_created_apps = [ employee_uu_id=str(employee_match.uu_id),
dict( is_confirmed=True,
name="Dashboard1", db=db_session,
application_code="app000001", )
site_url="/dashboard", if employee_added_service.meta_data.created:
application_type="info", employee_added_service.save(db=db_session)
description="Dashboard Page", print(
), f"UUID: {employee_added_service.uu_id} service is saved to {employee_match.uu_id}"
dict(
name="ManagementAccounting",
application_code="app000008",
site_url="/management/accounting",
application_type="Dash",
description="Individual Page for management accounting",
),
]
for list_of_created_app in list_of_created_apps:
created_page = Applications.find_or_create(
**list_of_created_app,
db=db_session,
) )
print("Application : ", created_page)
if created_page.meta_data.created:
created_page.save(db=db_session)
application_employee_created = Application2Employee.find_or_create(
employee_id=super_user.id,
employee_uu_id=str(super_user.uu_id),
site_url=created_page.site_url,
application_code=created_page.application_code,
application_id=created_page.id,
application_uu_id=str(created_page.uu_id),
is_confirmed=True,
db=db_session,
)
print("Application Employee : ", application_employee_created)
if application_employee_created.meta_data.created:
application_employee_created.save(db=db_session)
def init_applications_for_build_manager( # def init_applications_for_general_manager(
super_user: BuildLivingSpace, db_session=None # super_user: Employees, db_session=None
) -> None: # ) -> None:
list_of_created_apps = [] # list_of_created_apps = Applications.filter_all_system(db=db_session).data
# if not list_of_created_apps:
# raise Exception("No applications found")
# for list_of_created_app in list_of_created_apps:
# application_employee_created = Application2Employee.find_or_create(
# employee_id=super_user.id,
# employee_uu_id=str(super_user.uu_id),
# site_url=list_of_created_app.site_url,
# application_code=list_of_created_app.application_code,
# application_id=list_of_created_app.id,
# application_uu_id=str(list_of_created_app.uu_id),
# is_confirmed=True,
# db=db_session,
# )
# if application_employee_created.meta_data.created:
# application_employee_created.save(db=db_session)
def init_applications_for_owner(super_user: BuildLivingSpace, db_session=None) -> None:
pass # def init_applications_for_build_manager(
# super_user: BuildLivingSpace, db_session=None
# ) -> None:
# list_of_created_apps = Applications.filter_all_system(db=db_session).data
# if not list_of_created_apps:
# raise Exception("No applications found")
# for list_of_created_app in list_of_created_apps:
# application_employee_created = Application2Employee.find_or_create(
# employee_id=super_user.id,
# employee_uu_id=str(super_user.uu_id),
# site_url=list_of_created_app.site_url,
# application_code=list_of_created_app.application_code,
# application_id=list_of_created_app.id,
# application_uu_id=str(list_of_created_app.uu_id),
# is_confirmed=True,
# db=db_session,
# )
# if application_employee_created.meta_data.created:
# application_employee_created.save(db=db_session)
def init_applications_for_tenant(super_user: BuildLivingSpace, db_session=None) -> None: # def init_applications_for_owner(super_user: BuildLivingSpace, db_session=None) -> None:
list_of_created_apps = [ # list_of_created_apps = Applications.filter_all_system(db=db_session).data
dict( # if not list_of_created_apps:
name="Dashboard1", # raise Exception("No applications found")
application_code="app000001",
site_url="/dashboard",
application_type="info",
description="Dashboard Page",
),
dict(
name="TenantSendMessageToBuildManager",
application_code="app000022",
site_url="/tenant/messageToBM",
application_type="Dash",
description="Individual Page for tenant send message to build manager",
),
dict(
name="TenantSendMessageToOwner",
application_code="app000018",
site_url="/tenant/messageToOwner",
application_type="Dash",
description="Individual Page for tenant send message to owner",
),
dict(
name="TenantAccountView",
application_code="app000019",
site_url="/tenant/accounting",
application_type="Dash",
description="Individual Page for tenant account view",
),
]
for list_of_created_app in list_of_created_apps: # for list_of_created_app in list_of_created_apps:
created_page = Applications.find_or_create( # application_employee_created = Application2Employee.find_or_create(
**list_of_created_app, # employee_id=super_user.id,
db=db_session, # employee_uu_id=str(super_user.uu_id),
is_confirmed=True, # site_url=list_of_created_app.site_url,
) # application_code=list_of_created_app.application_code,
if created_page.meta_data.created: # application_id=list_of_created_app.id,
created_page.save(db=db_session) # application_uu_id=str(list_of_created_app.uu_id),
# is_confirmed=True,
# db=db_session,
# )
# if application_employee_created.meta_data.created:
# application_employee_created.save(db=db_session)
application_occupant_created = Application2Occupant.find_or_create(
build_living_space_id=super_user.id, # def init_applications_for_tenant(super_user: BuildLivingSpace, db_session=None) -> None:
build_living_space_uu_id=str(super_user.uu_id), # list_of_created_apps = Applications.filter_all_system(db=db_session).data
site_url=created_page.site_url, # if not list_of_created_apps:
application_code=created_page.application_code, # raise Exception("No applications found")
application_id=created_page.id,
application_uu_id=str(created_page.uu_id), # for list_of_created_app in list_of_created_apps:
is_confirmed=True, # application_employee_created = Application2Employee.find_or_create(
db=db_session, # employee_id=super_user.id,
) # employee_uu_id=str(super_user.uu_id),
if application_occupant_created.meta_data.created: # site_url=list_of_created_app.site_url,
application_occupant_created.save(db=db_session) # application_code=list_of_created_app.application_code,
# application_id=list_of_created_app.id,
# application_uu_id=str(list_of_created_app.uu_id),
# is_confirmed=True,
# db=db_session,
# )
# if application_employee_created.meta_data.created:
# application_employee_created.save(db=db_session)
# list_of_created_apps = [
# dict(
# name="Dashboard1",
# application_code="app000001",
# site_url="/dashboard",
# application_type="info",
# description="Dashboard Page",
# ),
# dict(
# name="TenantSendMessageToBuildManager",
# application_code="app000022",
# site_url="/tenant/messageToBM",
# application_type="Dash",
# description="Individual Page for tenant send message to build manager",
# ),
# dict(
# name="TenantSendMessageToOwner",
# application_code="app000018",
# site_url="/tenant/messageToOwner",
# application_type="Dash",
# description="Individual Page for tenant send message to owner",
# ),
# dict(
# name="TenantAccountView",
# application_code="app000019",
# site_url="/tenant/accounting",
# application_type="Dash",
# description="Individual Page for tenant account view",
# ),
# ]
# for list_of_created_app in list_of_created_apps:
# created_page = Applications.find_or_create(
# **list_of_created_app,
# db=db_session,
# is_confirmed=True,
# )
# if created_page.meta_data.created:
# created_page.save(db=db_session)
# application_occupant_created = Application2Occupant.find_or_create(
# build_living_space_id=super_user.id,
# build_living_space_uu_id=str(super_user.uu_id),
# site_url=created_page.site_url,
# application_code=created_page.application_code,
# application_id=created_page.id,
# application_uu_id=str(created_page.uu_id),
# is_confirmed=True,
# db=db_session,
# )
# if application_occupant_created.meta_data.created:
# application_occupant_created.save(db=db_session)

View File

@ -11,11 +11,7 @@ from Schemas import (
) )
def init_service_to_event_matches_for_super_user(super_user, db_session=None) -> None: def init_service_to_event_matches_for_super_user(service_match: Services, employee_match: Employees, db_session=None) -> None:
service_match = Services.filter_one(
Services.service_name == "Super User",
db=db_session,
).data
list_of_all_events = Events.filter_all(db=db_session).data list_of_all_events = Events.filter_all(db=db_session).data
Service2Events.filter_all(db=db_session).query.delete() Service2Events.filter_all(db=db_session).query.delete()
Service2Events.save(db=db_session) Service2Events.save(db=db_session)
@ -29,10 +25,9 @@ def init_service_to_event_matches_for_super_user(super_user, db_session=None) ->
if service_to_event_found.data: if service_to_event_found.data:
service_to_event_found.destroy(db=db_session) service_to_event_found.destroy(db=db_session)
print( print(
f"UUID: {service_to_event_found.uu_id} event is deleted from {service_match.uu_id}" f"UUID: {service_to_event_found.uu_id} event is deleted from {service_match.service_description}"
) )
added_service = Service2Events.find_or_create(
created_service = Service2Events.find_or_create(
service_id=service_match.id, service_id=service_match.id,
service_uu_id=str(service_match.uu_id), service_uu_id=str(service_match.uu_id),
event_id=list_of_event_code.id, event_id=list_of_event_code.id,
@ -41,23 +36,22 @@ def init_service_to_event_matches_for_super_user(super_user, db_session=None) ->
active=True, active=True,
db=db_session, db=db_session,
) )
if created_service.meta_data.created: if added_service.meta_data.created:
created_service.save(db=db_session) added_service.save(db=db_session)
print( print(
f"UUID: {created_service.uu_id} event is saved to {service_match.uu_id}" f"UUID: {added_service.uu_id} event is saved to {service_match.service_description}"
) )
employee_added_service = Event2Employee.find_or_create(
employee_added_service = Event2Employee.find_or_create( event_service_id=service_match.id,
event_service_id=service_match.id, event_service_uu_id=str(service_match.uu_id),
event_service_uu_id=str(service_match.uu_id), employee_id=employee_match.id,
employee_id=super_user.id, employee_uu_id=str(employee_match.uu_id),
employee_uu_id=str(super_user.uu_id), is_confirmed=True,
is_confirmed=True, db=db_session,
db=db_session, )
if employee_added_service.meta_data.created:
employee_added_service.save(db=db_session)
print(
f"UUID: {employee_added_service.uu_id} event is saved to employee {employee_match.uu_id}"
) )
if employee_added_service.meta_data.created:
employee_added_service.save(db=db_session)
print(
f"UUID: {employee_added_service.uu_id} event is saved to {super_user.uu_id}"
)

View File

@ -7,45 +7,113 @@ from ApiControllers.providers.token_provider import TokenProvider
from Controllers.Postgres.pagination import PaginateOnly, Pagination, PaginationResult from Controllers.Postgres.pagination import PaginateOnly, Pagination, PaginationResult
from Controllers.Postgres.response import EndpointResponse, CreateEndpointResponse from Controllers.Postgres.response import EndpointResponse, CreateEndpointResponse
from Schemas import Applications from Schemas import Applications
from Validations.application.validations import ( from Validations.application.validations import RequestApplication
RequestApplication, from Events.application.cluster import ApplicationRouterCluster
) from Validations.application.validations import AddRemoveService
# Create API router # Create API router
application_route = APIRouter(prefix="/application", tags=["Application Management"]) application_route = APIRouter(prefix="/application", tags=["Application Management"])
@application_route.post( @application_route.post(
path="/list", path="/list/all",
description="List applications endpoint", description="List all applications endpoint",
operation_id="3189a049-bdb0-49f3-83ff-feb8cb4cb57a", operation_id="fe30481d-802c-4490-897f-a4e95310e6bc",
) )
def application_list_route( def application_list_all_route(
list_options: PaginateOnly, data: PaginateOnly,
headers: CommonHeaders = Depends(CommonHeaders.as_dependency), headers: CommonHeaders = Depends(CommonHeaders.as_dependency),
): ):
""" """
List applications with pagination and filtering options List all applications with pagination and filtering options
""" """
token_object = TokenProvider.get_dict_from_redis(token=headers.token) token_object = TokenProvider.get_dict_from_redis(token=headers.token)
list_options = PaginateOnly(**list_options.model_dump()) event_founder_dict = dict(endpoint_code=headers.operation_id, token=token_object)
with Applications.new_session() as db_session: event_key = TokenProvider.retrieve_event_codes(**event_founder_dict)
if list_options.query: FoundCluster = ApplicationRouterCluster.get_event_cluster("ApplicationListAll")
applications_list = Applications.filter_all( event_cluster_matched = FoundCluster.match_event(event_key=event_key)
*Applications.convert(list_options.query), db=db_session return event_cluster_matched.event_callable(list_options=data)
)
else:
applications_list = Applications.filter_all(db=db_session) @application_route.post(
pagination = Pagination(data=applications_list) path="/list/available",
pagination.change(**list_options.model_dump()) description="List available applications endpoint",
pagination_result = PaginationResult( operation_id="7492bb02-a074-4320-b58c-4bc7d9fba3a6",
data=applications_list, )
pagination=pagination, def application_list_available_route(
) data: PaginateOnly,
return EndpointResponse( headers: CommonHeaders = Depends(CommonHeaders.as_dependency),
message="MSG0003-LIST", ):
pagination_result=pagination_result, """
).response List available applications with pagination and filtering options
"""
token_object = TokenProvider.get_dict_from_redis(token=headers.token)
event_founder_dict = dict(endpoint_code=headers.operation_id, token=token_object)
event_key = TokenProvider.retrieve_event_codes(**event_founder_dict)
FoundCluster = ApplicationRouterCluster.get_event_cluster("ApplicationListAvailable")
event_cluster_matched = FoundCluster.match_event(event_key=event_key)
return event_cluster_matched.event_callable(list_options=data)
@application_route.post(
path="/list/appended",
description="List appended applications endpoint",
operation_id="ea7bbd58-da09-407c-a630-c324e0272385",
)
def application_list_appended_route(
data: PaginateOnly,
headers: CommonHeaders = Depends(CommonHeaders.as_dependency),
):
"""
List appended applications with pagination and filtering options
"""
token_object = TokenProvider.get_dict_from_redis(token=headers.token)
event_founder_dict = dict(endpoint_code=headers.operation_id, token=token_object)
event_key = TokenProvider.retrieve_event_codes(**event_founder_dict)
FoundCluster = ApplicationRouterCluster.get_event_cluster("ApplicationListAppended")
event_cluster_matched = FoundCluster.match_event(event_key=event_key)
return event_cluster_matched.event_callable(list_options=data)
@application_route.post(
path="/register/service",
description="Register event to service endpoint",
operation_id="92e0870f-f8bb-4879-ba03-c2901cc70ecc",
)
def application_register_service_route(
data: AddRemoveService,
headers: CommonHeaders = Depends(CommonHeaders.as_dependency),
):
"""
Register event to service
"""
token_object = TokenProvider.get_dict_from_redis(token=headers.token)
event_founder_dict = dict(endpoint_code=headers.operation_id, token=token_object)
event_key = TokenProvider.retrieve_event_codes(**event_founder_dict)
FoundCluster = ApplicationRouterCluster.get_event_cluster("ApplicationRegisterService")
event_cluster_matched = FoundCluster.match_event(event_key=event_key)
return event_cluster_matched.event_callable(data=data)
@application_route.post(
path="/unregister/service",
description="Unregister event from service endpoint",
operation_id="7fa1a183-4c99-4746-b675-148f65ad7ba7",
)
def application_unregister_service_route(
data: AddRemoveService,
headers: CommonHeaders = Depends(CommonHeaders.as_dependency),
):
"""
Unregister event from service
"""
token_object = TokenProvider.get_dict_from_redis(token=headers.token)
event_founder_dict = dict(endpoint_code=headers.operation_id, token=token_object)
event_key = TokenProvider.retrieve_event_codes(**event_founder_dict)
FoundCluster = ApplicationRouterCluster.get_event_cluster("ApplicationUnRegisterService")
event_cluster_matched = FoundCluster.match_event(event_key=event_key)
return event_cluster_matched.event_callable(data=data)
@application_route.post( @application_route.post(
@ -61,26 +129,11 @@ def application_create_route(
Create a new application Create a new application
""" """
token_object = TokenProvider.get_dict_from_redis(token=headers.token) token_object = TokenProvider.get_dict_from_redis(token=headers.token)
with Applications.new_session() as db_session: event_founder_dict = dict(endpoint_code=headers.operation_id, token=token_object)
created_application_dict = data.model_dump() event_key = TokenProvider.retrieve_event_codes(**event_founder_dict)
created_application = Applications.find_or_create( FoundCluster = ApplicationRouterCluster.get_event_cluster("ApplicationCreate")
db=db_session, event_cluster_matched = FoundCluster.match_event(event_key=event_key)
include_args=[ return event_cluster_matched.event_callable(data=data)
Applications.application_for,
Applications.application_code,
Applications.site_url,
],
**created_application_dict,
)
if created_application.meta_data.created:
return CreateEndpointResponse(
message="MSG0001-INSERT",
data=created_application,
).response
return CreateEndpointResponse(
message="MSG0002-FOUND",
data=created_application,
).response
@application_route.post( @application_route.post(
@ -97,27 +150,11 @@ def application_update_route(
Update an existing application Update an existing application
""" """
token_object = TokenProvider.get_dict_from_redis(token=headers.token) token_object = TokenProvider.get_dict_from_redis(token=headers.token)
with Applications.new_session() as db_session: event_founder_dict = dict(endpoint_code=headers.operation_id, token=token_object)
updated_application_dict = data.model_dump(exclude_unset=True, exclude_none=True) event_key = TokenProvider.retrieve_event_codes(**event_founder_dict)
found_application = Applications.filter_one( FoundCluster = ApplicationRouterCluster.get_event_cluster("ApplicationUpdate")
Applications.uu_id == application_uuid, db=db_session event_cluster_matched = FoundCluster.match_event(event_key=event_key)
).data return event_cluster_matched.event_callable(data=data, uu_id=application_uuid)
if not found_application:
return CreateEndpointResponse(
message="MSG0002-FOUND",
data=found_application,
).response
updated_application = found_application.update(db=db_session,**updated_application_dict)
updated_application.save(db_session)
if updated_application.meta_data.updated:
return CreateEndpointResponse(
message="MSG0003-UPDATE",
data=updated_application,
).response
return CreateEndpointResponse(
message="MSG0003-UPDATE",
data=updated_application,
).response
@application_route.post( @application_route.post(
@ -158,4 +195,3 @@ def application_bind_occupant_route(
FoundCluster = ApplicationRouterCluster.get_event_cluster("ApplicationBindOccupant") FoundCluster = ApplicationRouterCluster.get_event_cluster("ApplicationBindOccupant")
event_cluster_matched = FoundCluster.match_event(event_key=event_key) event_cluster_matched = FoundCluster.match_event(event_key=event_key)
return event_cluster_matched.event_callable(data=data) return event_cluster_matched.event_callable(data=data)

View File

@ -5,7 +5,11 @@ from ApiControllers.abstracts.default_validations import CommonHeaders
from ApiControllers.providers.token_provider import TokenProvider from ApiControllers.providers.token_provider import TokenProvider
from Controllers.Postgres.pagination import PaginateOnly, Pagination, PaginationResult from Controllers.Postgres.pagination import PaginateOnly, Pagination, PaginationResult
from Controllers.Postgres.response import EndpointResponse from Controllers.Postgres.response import EndpointResponse
from Validations.service_endpoints.validations import Event2Employee, Event2Occupant, AddRemoveService from Validations.service_endpoints.validations import (
Event2Employee,
Event2Occupant,
AddRemoveService,
)
from Events.event_endpoints.cluster import EventsEndpointRouterCluster from Events.event_endpoints.cluster import EventsEndpointRouterCluster
# Create API router # Create API router
@ -87,7 +91,9 @@ def event_unregister_service_route(
token_object = TokenProvider.get_dict_from_redis(token=headers.token) token_object = TokenProvider.get_dict_from_redis(token=headers.token)
event_founder_dict = dict(endpoint_code=headers.operation_id, token=token_object) event_founder_dict = dict(endpoint_code=headers.operation_id, token=token_object)
event_key = TokenProvider.retrieve_event_codes(**event_founder_dict) event_key = TokenProvider.retrieve_event_codes(**event_founder_dict)
FoundCluster = EventsEndpointRouterCluster.get_event_cluster("EventUnregisterService") FoundCluster = EventsEndpointRouterCluster.get_event_cluster(
"EventUnregisterService"
)
event_cluster_matched = FoundCluster.match_event(event_key=event_key) event_cluster_matched = FoundCluster.match_event(event_key=event_key)
return event_cluster_matched.event_callable(data=data) return event_cluster_matched.event_callable(data=data)
@ -107,7 +113,9 @@ def event_bind_employee_extra_route(
token_object = TokenProvider.get_dict_from_redis(token=headers.token) token_object = TokenProvider.get_dict_from_redis(token=headers.token)
event_founder_dict = dict(endpoint_code=headers.operation_id, token=token_object) event_founder_dict = dict(endpoint_code=headers.operation_id, token=token_object)
event_key = TokenProvider.retrieve_event_codes(**event_founder_dict) event_key = TokenProvider.retrieve_event_codes(**event_founder_dict)
FoundCluster = EventsEndpointRouterCluster.get_event_cluster("EventBindEmployeeExtra") FoundCluster = EventsEndpointRouterCluster.get_event_cluster(
"EventBindEmployeeExtra"
)
event_cluster_matched = FoundCluster.match_event(event_key=event_key) event_cluster_matched = FoundCluster.match_event(event_key=event_key)
return event_cluster_matched.event_callable(data=data) return event_cluster_matched.event_callable(data=data)
@ -127,6 +135,8 @@ def event_bind_occupant_extra_route(
token_object = TokenProvider.get_dict_from_redis(token=headers.token) token_object = TokenProvider.get_dict_from_redis(token=headers.token)
event_founder_dict = dict(endpoint_code=headers.operation_id, token=token_object) event_founder_dict = dict(endpoint_code=headers.operation_id, token=token_object)
event_key = TokenProvider.retrieve_event_codes(**event_founder_dict) event_key = TokenProvider.retrieve_event_codes(**event_founder_dict)
FoundCluster = EventsEndpointRouterCluster.get_event_cluster("EventBindOccupantExtra") FoundCluster = EventsEndpointRouterCluster.get_event_cluster(
"EventBindOccupantExtra"
)
event_cluster_matched = FoundCluster.match_event(event_key=event_key) event_cluster_matched = FoundCluster.match_event(event_key=event_key)
return event_cluster_matched.event_callable(data=data) return event_cluster_matched.event_callable(data=data)

View File

@ -7,7 +7,12 @@ def get_routes() -> list[APIRouter]:
from .service_managements.route import service_management_route from .service_managements.route import service_management_route
from .event_endpoints.route import event_endpoint_route from .event_endpoints.route import event_endpoint_route
return [application_route, service_endpoint_route, service_management_route, event_endpoint_route] return [
application_route,
service_endpoint_route,
service_management_route,
event_endpoint_route,
]
def get_safe_endpoint_urls() -> list[tuple[str, str]]: def get_safe_endpoint_urls() -> list[tuple[str, str]]:

View File

@ -2,4 +2,8 @@ from .service_endpoints.cluster import ServiceEndpointRouterCluster
from .event_endpoints.cluster import EventsEndpointRouterCluster from .event_endpoints.cluster import EventsEndpointRouterCluster
from .application.cluster import ApplicationRouterCluster from .application.cluster import ApplicationRouterCluster
__all__ = ["ServiceEndpointRouterCluster", "EventsEndpointRouterCluster", "ApplicationRouterCluster"] __all__ = [
"ServiceEndpointRouterCluster",
"EventsEndpointRouterCluster",
"ApplicationRouterCluster",
]

View File

@ -1,18 +1,40 @@
from ApiControllers.abstracts.event_clusters import EventCluster, RouterCluster from ApiControllers.abstracts.event_clusters import EventCluster, RouterCluster
from .supers_events import ( from .supers_events import (
ApplicationListEvent, ApplicationListAllEvent,
ApplicationListAvailableEvent,
ApplicationListAppendedEvent,
ApplicationRegisterServiceEvent,
ApplicationUnRegisterServiceEvent,
ApplicationCreateEvent, ApplicationCreateEvent,
ApplicationUpdateEvent, ApplicationUpdateEvent,
ApplicationBindEmployeeEvent,
ApplicationBindOccupantEvent,
) )
ApplicationRouterCluster = RouterCluster(name="ApplicationRouterCluster") ApplicationRouterCluster = RouterCluster(name="ApplicationRouterCluster")
ApplicationEventClusterList = EventCluster( ApplicationEventClusterListAll = EventCluster(
name="ApplicationList", endpoint_uu_id="3189a049-bdb0-49f3-83ff-feb8cb4cb57a" name="ApplicationListAll", endpoint_uu_id="fe30481d-802c-4490-897f-a4e95310e6bc"
) )
ApplicationEventClusterList.add_event(ApplicationListEvent) ApplicationEventClusterListAll.add_event(ApplicationListAllEvent)
ApplicationEventClusterListAvailable = EventCluster(
name="ApplicationListAvailable", endpoint_uu_id="7492bb02-a074-4320-b58c-4bc7d9fba3a6"
)
ApplicationEventClusterListAvailable.add_event(ApplicationListAvailableEvent)
ApplicationEventClusterListAppended = EventCluster(
name="ApplicationListAppended", endpoint_uu_id="ea7bbd58-da09-407c-a630-c324e0272385"
)
ApplicationEventClusterListAppended.add_event(ApplicationListAppendedEvent)
ApplicationEventClusterRegisterService = EventCluster(
name="ApplicationRegisterService", endpoint_uu_id="92e0870f-f8bb-4879-ba03-c2901cc70ecc"
)
ApplicationEventClusterRegisterService.add_event(ApplicationRegisterServiceEvent)
ApplicationEventClusterUnregisterService = EventCluster(
name="ApplicationUnRegisterService", endpoint_uu_id="7fa1a183-4c99-4746-b675-148f65ad7ba7"
)
ApplicationEventClusterUnregisterService.add_event(ApplicationUnRegisterServiceEvent)
ApplicationEventClusterCreate = EventCluster( ApplicationEventClusterCreate = EventCluster(
name="ApplicationCreate", endpoint_uu_id="5570be78-030a-438e-8674-7e751447608b" name="ApplicationCreate", endpoint_uu_id="5570be78-030a-438e-8674-7e751447608b"
@ -24,18 +46,10 @@ ApplicationEventClusterUpdate = EventCluster(
) )
ApplicationEventClusterUpdate.add_event(ApplicationUpdateEvent) ApplicationEventClusterUpdate.add_event(ApplicationUpdateEvent)
ApplicationEventClusterBindEmployee = EventCluster( ApplicationRouterCluster.set_event_cluster(ApplicationEventClusterListAvailable)
name="ApplicationBindEmployee", endpoint_uu_id="2bab94fa-becb-4d8e-80f1-f4631119a521" ApplicationRouterCluster.set_event_cluster(ApplicationEventClusterListAppended)
) ApplicationRouterCluster.set_event_cluster(ApplicationEventClusterListAll)
ApplicationEventClusterBindEmployee.add_event(ApplicationBindEmployeeEvent) ApplicationRouterCluster.set_event_cluster(ApplicationEventClusterRegisterService)
ApplicationRouterCluster.set_event_cluster(ApplicationEventClusterUnregisterService)
ApplicationEventClusterBindOccupant = EventCluster(
name="ApplicationBindOccupant", endpoint_uu_id="fccf1a59-0650-4e5c-ba8d-f389dadce01c"
)
ApplicationEventClusterBindOccupant.add_event(ApplicationBindOccupantEvent)
ApplicationRouterCluster.set_event_cluster(ApplicationEventClusterList)
ApplicationRouterCluster.set_event_cluster(ApplicationEventClusterCreate) ApplicationRouterCluster.set_event_cluster(ApplicationEventClusterCreate)
ApplicationRouterCluster.set_event_cluster(ApplicationEventClusterUpdate) ApplicationRouterCluster.set_event_cluster(ApplicationEventClusterUpdate)
ApplicationRouterCluster.set_event_cluster(ApplicationEventClusterBindEmployee)
ApplicationRouterCluster.set_event_cluster(ApplicationEventClusterBindOccupant)

View File

@ -1,3 +1,5 @@
from typing import Any
from ApiControllers.abstracts.event_clusters import Event from ApiControllers.abstracts.event_clusters import Event
from Controllers.Postgres.pagination import Pagination, PaginationResult, PaginateOnly from Controllers.Postgres.pagination import Pagination, PaginationResult, PaginateOnly
from Controllers.Postgres.response import EndpointResponse from Controllers.Postgres.response import EndpointResponse
@ -5,16 +7,53 @@ from Schemas import (
Applications, Applications,
Application2Employee, Application2Employee,
Application2Occupant, Application2Occupant,
Service2Application,
Services,
) )
# List all endpoint
# List endpoint ApplicationListAllEvent = Event(
ApplicationListEvent = Event( name="application_list_all",
name="application_list", key="1971ce4d-4f59-4aa8-83e2-ca19d7da6d11",
key="b4efda1e-bde7-4659-ab1a-ef74c0fd88b6",
request_validator=None, # TODO: Add request validator request_validator=None, # TODO: Add request validator
response_validator=None, # TODO: Add response validator response_validator=None, # TODO: Add response validator
description="Super Users List applications endpoint", description="Super Users List all applications endpoint",
)
# List available endpoint
ApplicationListAvailableEvent = Event(
name="application_list_available",
key="d8e733f5-b53a-4c36-9082-12579bf9cc4a",
request_validator=None, # TODO: Add request validator
response_validator=None, # TODO: Add response validator
description="Super Users List available applications endpoint",
)
# List appended endpoint
ApplicationListAppendedEvent = Event(
name="application_list_appended",
key="ea7bbd58-da09-407c-a630-c324e0272385",
request_validator=None, # TODO: Add request validator
response_validator=None, # TODO: Add response validator
description="Super Users List appended applications endpoint",
)
# Register application to service endpoint
ApplicationRegisterServiceEvent = Event(
name="application_register_service",
key="47d7cfc8-6004-4442-8357-16ceac5d9d18",
request_validator=None, # TODO: Add request validator
response_validator=None, # TODO: Add response validator
description="Super Users Register application to service endpoint",
)
# Unregister application to service endpoint
ApplicationUnRegisterServiceEvent = Event(
name="application_unregister_service",
key="d228ab26-0b74-440f-8f1f-8f40be5a22f2",
request_validator=None, # TODO: Add request validator
response_validator=None, # TODO: Add response validator
description="Super Users Unregister application to service endpoint",
) )
# Create endpoint # Create endpoint
@ -35,114 +74,247 @@ ApplicationUpdateEvent = Event(
description="Super Users Update applications endpoint", description="Super Users Update applications endpoint",
) )
#Bind Application to employee
ApplicationBindEmployeeEvent = Event(
name="application_bind_employee",
key="26a96c2d-bca8-41cb-8ac1-f3ca8124434b",
request_validator=None, # TODO: Add request validator
response_validator=None, # TODO: Add response validator
description="Super Users Application Bind employee endpoint",
)
#Bind Application to occupant def application_list_all_callable(list_options: PaginateOnly):
ApplicationBindOccupantEvent = Event(
name="application_bind_occupant",
key="4eaf2bb0-2a42-4d21-ae65-a9259ebee189",
request_validator=None, # TODO: Add request validator
response_validator=None, # TODO: Add response validator
description="Super Users Application Bind occupant endpoint",
)
def application_list_callable(list_options: PaginateOnly):
"""
Example callable method
"""
list_options = PaginateOnly(**list_options.model_dump()) list_options = PaginateOnly(**list_options.model_dump())
with Applications.new_session() as db_session: with Applications.new_session() as db_session:
if list_options.query: if list_options.query:
applications_list = Applications.filter_all( applications_list = Applications.filter_all(*Applications.convert(list_options.query), db=db_session)
*Applications.convert(list_options.query), db=db_session
)
else: else:
applications_list = Applications.filter_all(db=db_session) applications_list = Applications.filter_all(db=db_session)
pagination = Pagination(data=applications_list) pagination = Pagination(data=applications_list)
pagination.change(**list_options.model_dump()) pagination.change(**list_options.model_dump())
pagination_result = PaginationResult( pagination_result = PaginationResult(data=applications_list, pagination=pagination)
data=applications_list, return EndpointResponse(message="MSG0003-LIST", pagination_result=pagination_result).response
pagination=pagination,
# response_model="",
)
return EndpointResponse(
message="MSG0003-LIST",
pagination_result=pagination_result,
).response
ApplicationListEvent.event_callable = application_list_callable ApplicationListAllEvent.event_callable = application_list_all_callable
def application_create_callable(): def application_list_available_callable(list_options: PaginateOnly):
""" """
Example callable method Example callable method
""" """
return { list_options = PaginateOnly(**list_options.model_dump())
"completed": True, service_uu_id = list_options.query.get("service_uu_id__ilike", None)
"message": "Example callable method 2", if not service_uu_id:
"info": { return {
"host": "example_host", "message": "MSG0003-PARAM-MISSING",
"user_agent": "example_user_agent", "data": list_options.query,
}, "completed": False,
} }
list_options.query.pop("service_uu_id__ilike", None)
list_options.query.pop("service_uu_id", None)
with Applications.new_session() as db_session:
service2applications = Service2Application.filter_all(
*Service2Application.convert({"service_uu_id__ilike": service_uu_id}),
db=db_session,
)
already_events = [
service_to_application.application_id for service_to_application in service2applications.data
]
if list_options.query:
applications_list = Applications.filter_all(
*Applications.convert(list_options.query), Applications.id.not_in(already_events), db=db_session
)
else:
applications_list = Applications.filter_all(Applications.id.not_in(already_events), db=db_session)
pagination = Pagination(data=applications_list)
pagination.change(**list_options.model_dump())
pagination_result = PaginationResult(data=applications_list, pagination=pagination)
return EndpointResponse(message="MSG0003-LIST", pagination_result=pagination_result).response
ApplicationListAvailableEvent.event_callable = application_list_available_callable
def application_list_appended_callable(list_options: PaginateOnly):
"""
Example callable method
"""
list_options = PaginateOnly(**list_options.model_dump())
service_uu_id = list_options.query.get("service_uu_id__ilike", None)
if not service_uu_id:
return {
"message": "MSG0003-PARAM-MISSING",
"data": list_options.query,
"completed": False,
}
list_options.query.pop("service_uu_id__ilike", None)
list_options.query.pop("service_uu_id", None)
with Applications.new_session() as db_session:
service2applications = Service2Application.filter_all(
*Service2Application.convert({"service_uu_id__ilike": service_uu_id}),
db=db_session,
)
already_events = [
service_to_application.application_id for service_to_application in service2applications.data
]
if list_options.query:
applications_list = Applications.filter_all(
*Applications.convert(list_options.query), Applications.id.in_(already_events), db=db_session
)
else:
applications_list = Applications.filter_all(Applications.id.in_(already_events), db=db_session)
pagination = Pagination(data=applications_list)
pagination.change(**list_options.model_dump())
pagination_result = PaginationResult(data=applications_list, pagination=pagination)
return EndpointResponse(message="MSG0003-LIST", pagination_result=pagination_result).response
ApplicationListAppendedEvent.event_callable = application_list_appended_callable
def application_create_callable(data: Any):
"""
Create a new application
"""
with Applications.new_session() as db_session:
created_application_dict = data.model_dump()
created_application = Applications.find_or_create(
db=db_session,
include_args=[Applications.application_for, Applications.application_code, Applications.site_url],
**created_application_dict,
)
if created_application.meta_data.created:
created_application.save(db=db_session)
return {
"completed": True,
"message": "MSG0001-INSERT",
"data": created_application,
}
return {
"completed": False,
"message": "MSG0002-ERROR",
"data": created_application,
}
ApplicationCreateEvent.event_callable = application_create_callable ApplicationCreateEvent.event_callable = application_create_callable
def application_update_callable(): def application_update_callable(data: Any, uu_id: str):
""" """
Example callable method Update an existing application
""" """
return { with Applications.new_session() as db_session:
"completed": True, updated_application_dict = data.model_dump(
"message": "Example callable method 2", exclude_unset=True, exclude_none=True
"info": { )
"host": "example_host", found_application = Applications.filter_one(
"user_agent": "example_user_agent", Applications.uu_id == uu_id, db=db_session
}, ).data
} if not found_application:
return {
"completed": False,
"message": "MSG0002-FOUND",
"data": found_application,
}
updated_application = found_application.update(
db=db_session, **updated_application_dict
)
updated_application.save(db_session)
if updated_application.meta_data.updated:
return {
"completed": True,
"message": "MSG0003-UPDATE",
"data": updated_application,
}
return {
"completed": False,
"message": "MSG0003-UPDATE",
"data": updated_application,
}
ApplicationUpdateEvent.event_callable = application_update_callable ApplicationUpdateEvent.event_callable = application_update_callable
def application_bind_employee_callable(): def application_register_service_callable(data: Any):
""" """
Example callable method Register an application to a service
""" """
with Applications.new_session() as db_session:
event = Applications.filter_one_system(Applications.uu_id == data.application_uu_id, db=db_session)
if not event.data:
return {
"message": "MSG0003-NOT-FOUND",
"data": data.model_dump(),
"completed": False,
}
service = Services.filter_one_system(Services.uu_id == data.service_uu_id, db=db_session)
if not service.data:
return {
"message": "MSG0003-NOT-FOUND",
"data": data.model_dump(),
"completed": False,
}
service_to_application = Service2Application.find_or_create(
db=db_session,
include_args=[Service2Application.service_uu_id, Service2Application.application_uu_id],
service_id=service.data.id,
service_uu_id=str(service.data.uu_id),
application_id=event.data.id,
application_uu_id=str(event.data.uu_id),
application_code=event.data.application_code,
site_url=event.data.site_url,
is_confirmed=True,
)
if not service_to_application.meta_data.created:
return {
"message": "MSG0003-ALREADY-FOUND",
"data": data.model_dump(),
"completed": False,
}
service_to_application.save(db=db_session)
return { return {
"message": "MSG0003-REGISTER",
"data": data.model_dump(),
"completed": True, "completed": True,
"message": "Example callable method 2",
"info": {
"host": "example_host",
"user_agent": "example_user_agent",
},
} }
ApplicationBindEmployeeEvent.event_callable = application_bind_employee_callable
ApplicationRegisterServiceEvent.event_callable = application_register_service_callable
def application_bind_occupant_callable(): def application_unregister_service_callable(data: Any):
""" """
Example callable method Unregister an application from a service
""" """
with Applications.new_session() as db_session:
application = Applications.filter_one_system(Applications.uu_id == data.application_uu_id, db=db_session)
if not application.data:
return {
"message": "MSG0003-NOT-FOUND",
"data": data.model_dump(),
"completed": False,
}
service = Services.filter_one_system(Services.uu_id == data.service_uu_id, db=db_session)
if not service.data:
return {
"message": "MSG0003-NOT-FOUND",
"data": data.model_dump(),
"completed": False,
}
service_to_application = Service2Application.filter_one_system(
Service2Application.service_id == service.data.id,
Service2Application.application_id == application.data.id,
db=db_session,
)
if not service_to_application.data:
return {
"message": "MSG0003-NOT-FOUND",
"data": data.model_dump(),
"completed": False,
}
service_to_application.query.delete()
db_session.commit()
return { return {
"message": "MSG0003-UNREGISTER",
"data": data.model_dump(),
"completed": True, "completed": True,
"message": "Example callable method 2",
"info": {
"host": "example_host",
"user_agent": "example_user_agent",
},
} }
ApplicationBindOccupantEvent.event_callable = application_bind_occupant_callable
ApplicationUnRegisterServiceEvent.event_callable = application_unregister_service_callable

View File

@ -43,6 +43,12 @@ EventsEndpointEventClusterBindOccupantExtra.add_event(EventBindOccupantExtraEven
EventsEndpointRouterCluster.set_event_cluster(EventsEndpointEventClusterListAvailable) EventsEndpointRouterCluster.set_event_cluster(EventsEndpointEventClusterListAvailable)
EventsEndpointRouterCluster.set_event_cluster(EventsEndpointEventClusterListAppended) EventsEndpointRouterCluster.set_event_cluster(EventsEndpointEventClusterListAppended)
EventsEndpointRouterCluster.set_event_cluster(EventsEndpointEventClusterRegisterService) EventsEndpointRouterCluster.set_event_cluster(EventsEndpointEventClusterRegisterService)
EventsEndpointRouterCluster.set_event_cluster(EventsEndpointEventClusterUnregisterService) EventsEndpointRouterCluster.set_event_cluster(
EventsEndpointRouterCluster.set_event_cluster(EventsEndpointEventClusterBindEmployeeExtra) EventsEndpointEventClusterUnregisterService
EventsEndpointRouterCluster.set_event_cluster(EventsEndpointEventClusterBindOccupantExtra) )
EventsEndpointRouterCluster.set_event_cluster(
EventsEndpointEventClusterBindEmployeeExtra
)
EventsEndpointRouterCluster.set_event_cluster(
EventsEndpointEventClusterBindOccupantExtra
)

View File

@ -72,22 +72,33 @@ def events_list_available_callable(list_options: PaginateOnly):
List available events with pagination and filtering options List available events with pagination and filtering options
""" """
list_options = PaginateOnly(**list_options.model_dump()) list_options = PaginateOnly(**list_options.model_dump())
service_uu_id = list_options.query.get('service_uu_id__ilike', None) service_uu_id = list_options.query.get("service_uu_id__ilike", None)
if not service_uu_id: if not service_uu_id:
return { return {
"message": "MSG0003-PARAM-MISSING", "message": "MSG0003-PARAM-MISSING",
"data": list_options.query, "data": list_options.query,
"completed": False, "completed": False,
} }
list_options.query.pop("service_uu_id__ilike", None)
list_options.query.pop("service_uu_id", None)
with Events.new_session() as db_session: with Events.new_session() as db_session:
service2events = Service2Events.filter_all(*Service2Events.convert(list_options.query), db=db_session) service2events = Service2Events.filter_all(
already_events = [service_to_event.event_id for service_to_event in service2events.data] *Service2Events.convert({"service_uu_id__ilike": service_uu_id}),
list_options.query.pop('service_uu_id__ilike', None) db=db_session,
list_options.query.pop('service_uu_id', None) )
already_events = [
service_to_event.event_id for service_to_event in service2events.data
]
if list_options.query: if list_options.query:
events_list = Events.filter_all(*Events.convert(list_options.query), Events.id.not_in(already_events), db=db_session) events_list = Events.filter_all(
*Events.convert(list_options.query),
Events.id.not_in(already_events),
db=db_session,
)
else: else:
events_list = Events.filter_all(Events.id.not_in(already_events), db=db_session) events_list = Events.filter_all(
Events.id.not_in(already_events), db=db_session
)
pagination = Pagination(data=events_list) pagination = Pagination(data=events_list)
pagination.change(**list_options.model_dump()) pagination.change(**list_options.model_dump())
pagination_result = PaginationResult(data=events_list, pagination=pagination) pagination_result = PaginationResult(data=events_list, pagination=pagination)
@ -105,22 +116,34 @@ def events_list_appended_callable(list_options: PaginateOnly):
List appended events with pagination and filtering options List appended events with pagination and filtering options
""" """
list_options = PaginateOnly(**list_options.model_dump()) list_options = PaginateOnly(**list_options.model_dump())
service_uu_id = list_options.query.get('service_uu_id__ilike', None) service_uu_id = list_options.query.get("service_uu_id__ilike", None)
if not service_uu_id: if not service_uu_id:
return { return {
"message": "MSG0003-PARAM-MISSING", "message": "MSG0003-PARAM-MISSING",
"data": list_options.query, "data": list_options.query,
"completed": False, "completed": False,
} }
list_options.query.pop("service_uu_id__ilike", None)
list_options.query.pop("service_uu_id", None)
with Events.new_session() as db_session: with Events.new_session() as db_session:
service2events = Service2Events.filter_all(*Service2Events.convert(list_options.query), db=db_session) service2events = Service2Events.filter_all(
already_events = [service_to_event.event_id for service_to_event in service2events.data] *Service2Events.convert({"service_uu_id__ilike": service_uu_id}),
list_options.query.pop('service_uu_id__ilike', None) db=db_session,
list_options.query.pop('service_uu_id', None) )
already_events = [
service_to_event.event_id for service_to_event in service2events.data
]
if list_options.query: if list_options.query:
events_list = Events.filter_all(*Events.convert(list_options.query), Events.id.in_(already_events), db=db_session) events_list = Events.filter_all(
*Events.convert(list_options.query),
Events.id.in_(already_events),
db=db_session,
)
else: else:
events_list = Events.filter_all(Events.id.in_(already_events), db=db_session) events_list = Events.filter_all(
Events.id.in_(already_events), db=db_session
)
pagination = Pagination(data=events_list) pagination = Pagination(data=events_list)
pagination.change(**list_options.model_dump()) pagination.change(**list_options.model_dump())
pagination_result = PaginationResult(data=events_list, pagination=pagination) pagination_result = PaginationResult(data=events_list, pagination=pagination)
@ -139,10 +162,9 @@ def event_register_service_callable(data: Any):
""" """
with Events.new_session() as db_session: with Events.new_session() as db_session:
event = Events.filter_one_system( event = Events.filter_one_system(
Events.uu_id == data.event_uu_id, Events.uu_id == data.event_uu_id, db=db_session
db=db_session
) )
print('event', event.data) print("event", event.data)
if not event.data: if not event.data:
return { return {
"message": "MSG0003-NOT-FOUND", "message": "MSG0003-NOT-FOUND",
@ -150,10 +172,9 @@ def event_register_service_callable(data: Any):
"completed": False, "completed": False,
} }
service = Services.filter_one_system( service = Services.filter_one_system(
Services.uu_id == data.service_uu_id, Services.uu_id == data.service_uu_id, db=db_session
db=db_session
) )
print('service', service.data) print("service", service.data)
if not service.data: if not service.data:
return { return {
"message": "MSG0003-NOT-FOUND", "message": "MSG0003-NOT-FOUND",
@ -172,7 +193,7 @@ def event_register_service_callable(data: Any):
service_uu_id=str(service.data.uu_id), service_uu_id=str(service.data.uu_id),
event_uu_id=str(event.data.uu_id), event_uu_id=str(event.data.uu_id),
) )
print('service_to_event', service_to_event) print("service_to_event", service_to_event)
if not service_to_event.meta_data.created: if not service_to_event.meta_data.created:
return { return {
"message": "MSG0003-ALREADY-FOUND", "message": "MSG0003-ALREADY-FOUND",
@ -214,8 +235,8 @@ def event_unregister_service_callable(data: Any):
"completed": False, "completed": False,
} }
service_to_event = Service2Events.filter_one_system( service_to_event = Service2Events.filter_one_system(
Service2Events.service_id==service.data.id, Service2Events.service_id == service.data.id,
Service2Events.event_id==event.data.id, Service2Events.event_id == event.data.id,
db=db_session, db=db_session,
) )
if not service_to_event.data: if not service_to_event.data:

View File

@ -21,13 +21,17 @@ def service_endpoint_list_callable(data: PaginateOnly):
list_options = PaginateOnly(**data.model_dump()) list_options = PaginateOnly(**data.model_dump())
with Services.new_session() as db_session: with Services.new_session() as db_session:
if data.query: if data.query:
services_list = Services.filter_all_system(*Services.convert(data.query), db=db_session) services_list = Services.filter_all_system(
*Services.convert(data.query), db=db_session
)
else: else:
services_list = Services.filter_all_system(db=db_session) services_list = Services.filter_all_system(db=db_session)
pagination = Pagination(data=services_list) pagination = Pagination(data=services_list)
pagination.change(**data.model_dump()) pagination.change(**data.model_dump())
pagination_result = PaginationResult(data=services_list, pagination=pagination) pagination_result = PaginationResult(data=services_list, pagination=pagination)
return EndpointResponse(message="MSG0003-LIST", pagination_result=pagination_result).response return EndpointResponse(
message="MSG0003-LIST", pagination_result=pagination_result
).response
ServiceEndpointListEvent.event_callable = service_endpoint_list_callable ServiceEndpointListEvent.event_callable = service_endpoint_list_callable
@ -49,13 +53,17 @@ def service_endpoint_to_events_callable(data: PaginateOnly):
list_options = PaginateOnly(**data.model_dump()) list_options = PaginateOnly(**data.model_dump())
with Service2Events.new_session() as db_session: with Service2Events.new_session() as db_session:
if data.query: if data.query:
services_list = Service2Events.filter_all_system(*Service2Events.convert(data.query), db=db_session) services_list = Service2Events.filter_all_system(
*Service2Events.convert(data.query), db=db_session
)
else: else:
services_list = Service2Events.filter_all_system(db=db_session) services_list = Service2Events.filter_all_system(db=db_session)
pagination = Pagination(data=services_list) pagination = Pagination(data=services_list)
pagination.change(**data.model_dump()) pagination.change(**data.model_dump())
pagination_result = PaginationResult(data=services_list, pagination=pagination) pagination_result = PaginationResult(data=services_list, pagination=pagination)
return EndpointResponse(message="MSG0003-LIST", pagination_result=pagination_result).response return EndpointResponse(
message="MSG0003-LIST", pagination_result=pagination_result
).response
ServiceEndpointToEventsEvent.event_callable = service_endpoint_to_events_callable ServiceEndpointToEventsEvent.event_callable = service_endpoint_to_events_callable

View File

@ -13,3 +13,10 @@ class RequestApplication(BaseModel):
) )
application_for: str = Field(..., description="Application for (EMP, OCC)") application_for: str = Field(..., description="Application for (EMP, OCC)")
description: Optional[str] = Field(None, description="Application description") description: Optional[str] = Field(None, description="Application description")
class AddRemoveService(BaseModel):
"""Base model for add/remove service data"""
application_uu_id: str = Field(..., description="Application UUID")
service_uu_id: str = Field(..., description="Service UUID")

View File

@ -1,5 +1,6 @@
from pydantic import BaseModel from pydantic import BaseModel
class Event2Employee(BaseModel): class Event2Employee(BaseModel):
pass pass

View File

@ -108,7 +108,9 @@ def set_account_records_to_send_email() -> bool:
balance_error = expected_second_balance != second_record.bank_balance balance_error = expected_second_balance != second_record.bank_balance
if balance_error: if balance_error:
print(f"Balance error detected {expected_second_balance} != {second_record.bank_balance}") print(
f"Balance error detected {expected_second_balance} != {second_record.bank_balance}"
)
# Format rows for the email template # Format rows for the email template
list_of_rows = [] list_of_rows = []

View File

@ -75,6 +75,7 @@ from Schemas.event.event import (
Modules, Modules,
Services, Services,
Service2Events, Service2Events,
Service2Application,
Events, Events,
Event2Occupant, Event2Occupant,
Event2Employee, Event2Employee,
@ -83,6 +84,8 @@ from Schemas.event.event import (
Applications, Applications,
Application2Employee, Application2Employee,
Application2Occupant, Application2Occupant,
Application2EmployeeExtra,
Application2OccupantExtra,
) )
from Schemas.identity.identity import ( from Schemas.identity.identity import (
UsersTokens, UsersTokens,

View File

@ -27,7 +27,9 @@ class Applications(CrudCollection):
String, nullable=False, comment="Application Code" String, nullable=False, comment="Application Code"
) )
application_type: Mapped[str] = mapped_column(String, comment="Application Type") application_type: Mapped[str] = mapped_column(String, comment="Application Type")
application_for: Mapped[str] = mapped_column(String, server_default="EMP", comment="Application For") application_for: Mapped[str] = mapped_column(
String, server_default="EMP", comment="Application For"
)
description: Mapped[str] = mapped_column(String, comment="Application Description") description: Mapped[str] = mapped_column(String, comment="Application Description")
@ -199,8 +201,30 @@ class Service2Events(CrudCollection):
__table_args__ = ({"comment": "Service2Events Information"},) __table_args__ = ({"comment": "Service2Events Information"},)
# class Service2Application(CrudCollection): class Service2Application(CrudCollection):
# pass """
Service2Application class based on declarative_base and BaseMixin via session
"""
__tablename__ = "services2applications"
__exclude__fields__ = []
application_id: Mapped[int] = mapped_column(
ForeignKey("applications.id"), nullable=False
)
application_uu_id: Mapped[str] = mapped_column(
String, nullable=False, comment="Application UUID"
)
service_id: Mapped[int] = mapped_column(ForeignKey("services.id"), nullable=False)
service_uu_id: Mapped[str] = mapped_column(
String, nullable=False, comment="Service UUID"
)
application_code: Mapped[str] = mapped_column(
String, nullable=False, comment="Application Code"
)
site_url: Mapped[str] = mapped_column(String, nullable=False, comment="Site URL")
__table_args__ = {"comment": "Service2Applications Information"}
class Event2OccupantExtra(CrudCollection): class Event2OccupantExtra(CrudCollection):
@ -295,17 +319,14 @@ class Event2Employee(CrudCollection):
db=db, db=db,
).data ).data
service_ids = list(set([event.event_service_id for event in employee_events])) service_ids = list(set([event.event_service_id for event in employee_events]))
print("service_ids", service_ids)
active_event_ids = Service2Events.filter_all( active_event_ids = Service2Events.filter_all(
Service2Events.service_id.in_(service_ids), Service2Events.service_id.in_(service_ids),
db=db, db=db,
).data ).data
print("active_event_ids", active_event_ids)
active_events = Events.filter_all( active_events = Events.filter_all(
Events.id.in_([event.event_id for event in active_event_ids]), Events.id.in_([event.event_id for event in active_event_ids]),
db=db, db=db,
).data ).data
print("active_events", active_events)
if extra_events := Event2EmployeeExtra.filter_all( if extra_events := Event2EmployeeExtra.filter_all(
Event2EmployeeExtra.employee_id == employee_id, Event2EmployeeExtra.employee_id == employee_id,
db=db, db=db,
@ -321,7 +342,6 @@ class Event2Employee(CrudCollection):
events_dict[str(event.endpoint_code)] = str(event.function_code) events_dict[str(event.endpoint_code)] = str(event.function_code)
else: else:
ValueError("Duplicate event code found for single endpoint") ValueError("Duplicate event code found for single endpoint")
print("events_dict", events_dict)
return events_dict return events_dict
@ -400,45 +420,54 @@ class Application2Employee(CrudCollection):
__exclude__fields__ = [] __exclude__fields__ = []
employee_id: Mapped[int] = mapped_column(ForeignKey("employees.id"), nullable=False) employee_id: Mapped[int] = mapped_column(ForeignKey("employees.id"), nullable=False)
employee_uu_id: Mapped[str] = mapped_column( employee_uu_id = mapped_column(String, nullable=False, comment="Employee UUID")
String, nullable=False, comment="Employee UUID" service_id: Mapped[int] = mapped_column(ForeignKey("services.id"), nullable=False)
) service_uu_id = mapped_column(String, nullable=False, comment="Service UUID")
application_id: Mapped[int] = mapped_column(ForeignKey("applications.id"))
application_uu_id: Mapped[str] = mapped_column(
String, nullable=False, comment="Application UUID"
)
site_url: Mapped[str] = mapped_column(String, nullable=False, comment="Site URL")
application_code: Mapped[str] = mapped_column(
String, nullable=False, comment="Application Code"
)
@classmethod @classmethod
def get_application_codes(cls, employee_id: int, db) -> dict[str, str]: def get_application_codes(cls, employee_id: int, db) -> list[int]:
print("employee_id", employee_id) employee_services = cls.filter_all(
employee_applications = cls.filter_all( cls.employee_id == employee_id,
Application2Employee.employee_id == employee_id,
db=db, db=db,
).data ).data
service_ids = [service.service_id for service in employee_services]
active_applications = Service2Application.filter_all(
Service2Application.service_id.in_(service_ids),
db=db,
).data
applications = Applications.filter_all(
Applications.id.in_(
[application.application_id for application in active_applications]
),
db=db,
).data
if extra_applications := Application2EmployeeExtra.filter_all(
Application2EmployeeExtra.employee_id == employee_id,
db=db,
).data:
applications_extra = Applications.filter_all(
Applications.id.in_(
[application.application_id for application in extra_applications]
),
db=db,
).data
applications.extend(applications_extra)
applications_dict = {} applications_dict = {}
print("employee_applications", employee_applications) for application in applications:
for employee_application in employee_applications: if not application.site_url in applications_dict:
if employee_application.site_url not in applications_dict: applications_dict[str(application.site_url)] = str(application.application_code)
applications_dict[str(employee_application.site_url)] = str( else:
employee_application.application_code ValueError("Duplicate application code found for single endpoint")
)
return applications_dict return applications_dict
__table_args__ = ( __table_args__ = (
Index( Index(
"application_to_employee", "application2employee_employee_to_service",
employee_id, employee_uu_id,
site_url, service_uu_id,
application_id,
unique=True, unique=True,
), ),
{"comment": "Application2Employee Information"}, {"comment": "Application to Employee Information"},
) )
@ -453,33 +482,114 @@ class Application2Occupant(CrudCollection):
build_living_space_id: Mapped[int] = mapped_column( build_living_space_id: Mapped[int] = mapped_column(
ForeignKey("build_living_space.id"), nullable=False ForeignKey("build_living_space.id"), nullable=False
) )
build_living_space_uu_id: Mapped[str] = mapped_column( build_living_space_uu_id = mapped_column(
String, nullable=False, comment="Build Living Space UUID" String, nullable=False, comment="Build Living Space UUID"
) )
service_id: Mapped[int] = mapped_column(ForeignKey("services.id"), nullable=False)
service_uu_id = mapped_column(String, nullable=False, comment="Service UUID")
@classmethod
def get_application_codes(cls, build_living_space_id: int, db) -> list[int]:
occupant_services = cls.filter_all(
cls.build_living_space_id == build_living_space_id,
db=db,
).data
service_ids = [service.service_id for service in occupant_services]
active_applications = Service2Application.filter_all(
Service2Application.service_id.in_(service_ids),
db=db,
).data
applications = Applications.filter_all(
Applications.id.in_(
[application.application_id for application in active_applications]
),
db=db,
).data
if extra_applications := Application2OccupantExtra.filter_all(
Application2OccupantExtra.build_living_space_id == build_living_space_id,
db=db,
).data:
applications_extra = Applications.filter_all(
Applications.id.in_(
[application.application_id for application in extra_applications]
),
db=db,
).data
applications.extend(applications_extra)
applications_dict = {}
for application in applications:
if not application.site_url in applications_dict:
applications_dict[str(application.site_url)] = str(application.application_code)
else:
ValueError("Duplicate application code found for single endpoint")
return applications_dict
__table_args__ = (
Index(
"application2occupant_occupant_to_service",
build_living_space_uu_id,
service_uu_id,
unique=True,
),
{"comment": "Application to Occupant Information"},
)
class Application2EmployeeExtra(CrudCollection):
"""
Application2EmployeeExtra class based on declarative_base and BaseMixin via session
"""
__tablename__ = "application2employee_extra"
__exclude__fields__ = []
employee_id: Mapped[int] = mapped_column(ForeignKey("employees.id"), nullable=False)
employee_uu_id: Mapped[str] = mapped_column(
String, nullable=False, comment="Employee UUID"
)
application_id: Mapped[int] = mapped_column(ForeignKey("applications.id")) application_id: Mapped[int] = mapped_column(ForeignKey("applications.id"))
application_uu_id: Mapped[str] = mapped_column( application_uu_id: Mapped[str] = mapped_column(
String, nullable=False, comment="Application UUID" String, nullable=False, comment="Application UUID"
) )
site_url: Mapped[str] = mapped_column(String, nullable=False, comment="Site URL") site_url: Mapped[str] = mapped_column(String, nullable=False, comment="Site URL")
application_code: Mapped[str] = mapped_column( application_code: Mapped[str] = mapped_column(
String, nullable=False, comment="Application Code" String, nullable=False, comment="Application Code"
) )
@classmethod __table_args__ = (
def get_application_codes(cls, build_living_space_id: int, db) -> dict[str, str]: Index(
occupant_applications = cls.filter_all( "application_to_employee",
cls.build_living_space_id == build_living_space_id, employee_id,
db=db, site_url,
).data application_id,
applications_dict = {} unique=True,
for occupant_application in occupant_applications: ),
if occupant_application.site_url not in applications_dict: {"comment": "Application2Employee Information"},
applications_dict[str(occupant_application.site_url)] = str( )
occupant_application.application_code
)
return applications_dict class Application2OccupantExtra(CrudCollection):
"""
Application2OccupantExtra class based on declarative_base and BaseMixin via session
"""
__tablename__ = "application2occupant_extra"
__exclude__fields__ = []
build_living_space_id: Mapped[int] = mapped_column(
ForeignKey("build_living_space.id"), nullable=False
)
build_living_space_uu_id: Mapped[str] = mapped_column(
String, nullable=False, comment="Build Living Space UUID"
)
application_id: Mapped[int] = mapped_column(ForeignKey("applications.id"))
application_uu_id: Mapped[str] = mapped_column(
String, nullable=False, comment="Application UUID"
)
site_url: Mapped[str] = mapped_column(String, nullable=False, comment="Site URL")
application_code: Mapped[str] = mapped_column(
String, nullable=False, comment="Application Code"
)
__table_args__ = ( __table_args__ = (
Index( Index(

View File

@ -1,87 +1,198 @@
"use server"; "use server";
import { fetchDataWithToken } from "../api-fetcher"; import { fetchDataWithToken } from "../api-fetcher";
import { baseUrlApplication } from "../basics"; import { baseUrlApplication } from "../basics";
import { PaginationParams } from "../schemas/list"; import { PaginationParams } from "../schemas/list";
import type { PaginatedApiResponse } from "@/app/api/utils/types"; import {
collectPaginationFromApiResponse,
defaultPaginationResponse,
type PaginatedApiResponse
} from "@/app/api/utils/types";
const applicationListEndpoint = `${baseUrlApplication}/application/list/all`;
const applicationListAvailableEndpoint = `${baseUrlApplication}/application/list/available`;
const applicationListAppendedEndpoint = `${baseUrlApplication}/application/list/appended`;
const applicationRegisterServiceEndpoint = `${baseUrlApplication}/application/register/service`;
const applicationUnregisterServiceEndpoint = `${baseUrlApplication}/application/unregister/service`;
const applicationListEndpoint = `${baseUrlApplication}/application/list`;
const applicationUpdateEndpoint = `${baseUrlApplication}/application/update`; const applicationUpdateEndpoint = `${baseUrlApplication}/application/update`;
const applicationCreateEndpoint = `${baseUrlApplication}/application/create`; const applicationCreateEndpoint = `${baseUrlApplication}/application/create`;
const applicationDeleteEndpoint = `${baseUrlApplication}/application/delete`; const applicationDeleteEndpoint = `${baseUrlApplication}/application/delete`;
interface AppendApplicationToService {
application_uu_id: string;
service_uu_id: string;
}
interface RemoveApplicationFromService extends AppendApplicationToService { }
async function listApplicationsAvailable(payload: PaginationParams): Promise<PaginatedApiResponse<any>> {
if (!payload.query.service_uu_id__ilike) {
console.warn('Missing service_uu_id in query parameters');
return {
data: [],
pagination: defaultPaginationResponse,
};
}
async function listApplications(payload: PaginationParams): Promise<PaginatedApiResponse<any>> {
try { try {
const requestBody = {
page: payload.page,
size: payload.size,
order_field: payload.orderField,
order_type: payload.orderType,
query: payload.query,
};
console.log('Sending request to backend with service_uu_id:', payload.query.service_uu_id);
console.log('Full request body:', JSON.stringify(requestBody, null, 2));
const response = await fetchDataWithToken( const response = await fetchDataWithToken(
applicationListEndpoint, applicationListAvailableEndpoint,
{ requestBody,
page: payload.page,
size: payload.size,
order_field: payload.orderField,
order_type: payload.orderType,
query: payload.query,
},
"POST", "POST",
false false
); );
if (response?.status === 200 || response?.status === 202) { if (response?.status === 200 || response?.status === 202) {
const responseData = response.data as any; const responseData = response.data as PaginatedApiResponse<any>;
console.log('list_events_available responseData:', JSON.stringify(responseData, null, 2));
return { return {
data: responseData.data || [], data: responseData.data || [],
pagination: { pagination: collectPaginationFromApiResponse(responseData)
page: responseData.pagination?.page || 1,
size: responseData.pagination?.size || 10,
totalCount: responseData.pagination?.totalCount || 0,
totalItems: responseData.pagination?.totalItems || 0,
totalPages: responseData.pagination?.totalPages || 0,
pageCount: responseData.pagination?.pageCount || 0,
orderField: responseData.pagination?.orderField || ['name'],
orderType: responseData.pagination?.orderType || ['asc'],
query: responseData.pagination?.query || {},
next: responseData.pagination?.next || false,
back: responseData.pagination?.back || false
}
}; };
} }
return { return {
data: [], data: [],
pagination: { pagination: defaultPaginationResponse,
page: 1,
size: 10,
totalCount: 0,
totalItems: 0,
totalPages: 0,
pageCount: 0,
orderField: ['name'],
orderType: ['asc'],
query: {},
next: false,
back: false
}
}; };
} catch (error) { } catch (error) {
console.error("Error fetching application list:", error); console.error("Error fetching events list:", error);
return { return {
data: [], data: [],
pagination: { pagination: defaultPaginationResponse,
page: 1,
size: 10,
totalCount: 0,
totalItems: 0,
totalPages: 0,
pageCount: 0,
orderField: ['name'],
orderType: ['asc'],
query: {},
next: false,
back: false
}
}; };
} }
} }
async function listApplicationsAppended(payload: PaginationParams): Promise<PaginatedApiResponse<any>> {
if (!payload.query.service_uu_id__ilike) {
console.warn('Missing service_uu_id in query parameters');
return {
data: [],
pagination: defaultPaginationResponse,
};
}
try {
const requestBody = {
page: payload.page,
size: payload.size,
order_field: payload.orderField,
order_type: payload.orderType,
query: payload.query,
};
console.log('Sending request to backend with service_uu_id:', payload.query.service_uu_id);
console.log('Full request body:', JSON.stringify(requestBody, null, 2));
const response = await fetchDataWithToken(
applicationListAppendedEndpoint,
requestBody,
"POST",
false
);
if (response?.status === 200 || response?.status === 202) {
const responseData = response.data as PaginatedApiResponse<any>;
console.log('list_events_available responseData:', JSON.stringify(responseData, null, 2));
return {
data: responseData.data || [],
pagination: collectPaginationFromApiResponse(responseData)
};
}
return {
data: [],
pagination: defaultPaginationResponse,
};
} catch (error) {
console.error("Error fetching events list:", error);
return {
data: [],
pagination: defaultPaginationResponse,
};
}
}
async function listAllApplications(payload: PaginationParams): Promise<PaginatedApiResponse<any>> {
try {
const requestBody = {
page: payload.page,
size: payload.size,
order_field: payload.orderField,
order_type: payload.orderType,
query: payload.query,
};
console.log('Sending request to backend with service_uu_id:', payload.query.service_uu_id);
console.log('Full request body:', JSON.stringify(requestBody, null, 2));
const response = await fetchDataWithToken(
applicationListEndpoint,
requestBody,
"POST",
false
);
if (response?.status === 200 || response?.status === 202) {
const responseData = response.data as PaginatedApiResponse<any>;
console.log('list_events_available responseData:', JSON.stringify(responseData, null, 2));
return {
data: responseData.data || [],
pagination: collectPaginationFromApiResponse(responseData)
};
}
return {
data: [],
pagination: defaultPaginationResponse,
};
} catch (error) {
console.error("Error fetching events list:", error);
return {
data: [],
pagination: defaultPaginationResponse,
};
}
}
async function appendApplicationToService(payload: AppendApplicationToService) {
try {
const response = await fetchDataWithToken(
applicationRegisterServiceEndpoint,
payload,
"POST",
false
);
return response?.status === 200 || response?.status === 202 ? response.data : null;
} catch (error) {
console.error("Error appending event to service:", error);
}
}
async function removeApplicationFromService(payload: RemoveApplicationFromService) {
try {
const response = await fetchDataWithToken(
applicationUnregisterServiceEndpoint,
payload,
"POST",
false
);
return response?.status === 200 || response?.status === 202 ? response.data : null;
} catch (error) {
console.error("Error removing event from service:", error);
}
}
async function createApplication(payload: any) { async function createApplication(payload: any) {
try { try {
const response = await fetchDataWithToken( const response = await fetchDataWithToken(
@ -100,6 +211,7 @@ async function createApplication(payload: any) {
} }
async function updateApplication(payload: any, uuId: string) { async function updateApplication(payload: any, uuId: string) {
console.log("Updating application with payload:", payload, 'uuId:', uuId);
try { try {
const response = await fetchDataWithToken( const response = await fetchDataWithToken(
`${applicationUpdateEndpoint}/${uuId}`, `${applicationUpdateEndpoint}/${uuId}`,
@ -134,7 +246,11 @@ async function deleteApplication(uuId: string) {
} }
export { export {
listApplications, listApplicationsAvailable,
listApplicationsAppended,
listAllApplications,
appendApplicationToService,
removeApplicationFromService,
createApplication, createApplication,
updateApplication, updateApplication,
deleteApplication, deleteApplication,

View File

@ -0,0 +1,22 @@
import { appendApplicationToService } from "@/apicalls/application/endpoints";
import { NextRequest } from "next/server";
import { withErrorHandling } from "@/app/api/utils/requestHandlers";
import {
successResponse,
errorResponse,
} from "@/app/api/utils/responseHandlers";
export const POST = withErrorHandling(
async (request: NextRequest, body: any) => {
const payload = {
application_uu_id: body.application_uu_id,
service_uu_id: body.service_uu_id,
};
const result = await appendApplicationToService(payload);
if (!result) {
return errorResponse("Error appending application to service");
} else {
return successResponse(result);
}
}
);

View File

@ -0,0 +1,22 @@
import { removeApplicationFromService } from "@/apicalls/application/endpoints";
import { NextRequest } from "next/server";
import { withErrorHandling } from "@/app/api/utils/requestHandlers";
import {
successResponse,
errorResponse,
} from "@/app/api/utils/responseHandlers";
export const POST = withErrorHandling(
async (request: NextRequest, body: any) => {
const payload = {
application_uu_id: body.application_uu_id,
service_uu_id: body.service_uu_id,
};
const result = await removeApplicationFromService(payload);
if (!result) {
return errorResponse("Error removing application from service");
} else {
return successResponse(result);
}
}
);

View File

@ -0,0 +1,4 @@
import { listApplicationsAppended } from "@/apicalls/application/endpoints";
import { createListHandler } from "@/app/api/utils/apiOperations";
export const POST = createListHandler(listApplicationsAppended);

View File

@ -0,0 +1,4 @@
import { createCreateHandler } from "@/app/api/utils";
import { appendApplicationToService } from "@/apicalls/application/endpoints";
export const POST = createCreateHandler(appendApplicationToService);

View File

@ -1,4 +1,4 @@
import { listApplications } from "@/apicalls/application/endpoints"; import { listApplicationsAvailable } from "@/apicalls/application/endpoints";
import { createListHandler } from "@/app/api/utils"; import { createListHandler } from "@/app/api/utils";
export const POST = createListHandler(listApplications); export const POST = createListHandler(listApplicationsAvailable);

View File

@ -0,0 +1,4 @@
import { listAllApplications } from "@/apicalls/application/endpoints";
import { createListHandler } from "@/app/api/utils";
export const POST = createListHandler(listAllApplications);

View File

@ -0,0 +1,4 @@
import { createCreateHandler } from "@/app/api/utils";
import { removeApplicationFromService } from "@/apicalls/application/endpoints";
export const POST = createCreateHandler(removeApplicationFromService);

View File

@ -167,7 +167,7 @@ export function UpdateComponent<T>({
console.error("API URL is missing or undefined"); console.error("API URL is missing or undefined");
return; return;
} }
const uuid = initialData ? (initialData as any).uuid || (initialData as any).uu_id : null; const uuid = initialData ? (initialData as any).uu_id : null;
if (!uuid) { if (!uuid) {
console.error("UUID not found in initialData"); console.error("UUID not found in initialData");
throw new Error("UUID is required for update operations"); throw new Error("UUID is required for update operations");
@ -181,6 +181,7 @@ export function UpdateComponent<T>({
}); });
const updateUrl = `${apiUrl}/update?uuid=${uuid}`; const updateUrl = `${apiUrl}/update?uuid=${uuid}`;
console.log("Updating application with payload:", dataToSend, 'uuId:', uuid);
try { try {
let response = await fetch(updateUrl, { let response = await fetch(updateUrl, {
method: 'POST', method: 'POST',

View File

@ -0,0 +1,15 @@
import React from 'react'
const Loader = () => {
return (
<>
<div className="flex-1">
<div className="flex items-center justify-center h-40 bg-gray-100 rounded-md">
<div className="animate-spin rounded-full h-10 w-10 border-b-2 border-primary"></div>
</div>
</div>
</>
)
}
export default Loader

View File

@ -1,5 +1,6 @@
import { useDataFetching, ApiResponse } from "./useDataFetching"; import { useDataFetching, ApiResponse } from "./useDataFetching";
import { RequestParams } from "../schemas"; import { RequestParams } from "../schemas";
import { defaultPaginationResponse } from "@/app/api/utils/types";
/** /**
* Hook for fetching data from Next.js API routes * Hook for fetching data from Next.js API routes
@ -23,8 +24,7 @@ export function useApiData<T>(
query: params.query, query: params.query,
}; };
const listEndpoint = `${endpoint}/list`; const response = await fetch(endpoint, {
const response = await fetch(listEndpoint, {
method: "POST", method: "POST",
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",
@ -42,19 +42,7 @@ export function useApiData<T>(
return { return {
data: [], data: [],
pagination: { pagination: defaultPaginationResponse,
page: params.page,
size: params.size,
totalCount: 0,
totalItems: 0,
totalPages: 0,
pageCount: 0,
orderField: params.orderField,
orderType: params.orderType,
query: params.query,
next: false,
back: false,
},
}; };
} }
}; };

View File

@ -0,0 +1,168 @@
import {
LanguageKey,
TranslationSet,
} from "@/validations/translations/translation";
import {
ServiceBaseTranslationEn,
ServiceBaseTranslationTr,
} from "./schemaList/services";
import {
ApplicationBaseTranslationTr,
ApplicationBaseTranslationEn,
} from "./schemaList/application";
const translations = {
en: {
// Page title
mainTitle: "Services",
// Common actions
create: "Create",
update: "Update",
delete: "Delete",
view: "View",
save: "Save",
cancel: "Cancel",
// Search and filters
search: "Search",
typeSelection: "Type Selection",
filterSelection: "Filter Selection",
siteUrl: "Site URL",
resetAll: "Reset All",
// Type options
web: "Web",
mobile: "Mobile",
// Status options
status: "Status",
active: "Active",
inactive: "Inactive",
pending: "Pending",
// User types
employee: "Employee",
occupant: "Occupant",
// Pagination
showing: "Showing",
of: "of",
items: "items",
total: "Total",
filtered: "Filtered",
previous: "Previous",
next: "Next",
page: "Page",
itemsPerPage: "Items per page",
// Messages
noData: "No data found",
serviceSelectedTitle: "Selected Service",
serviceSelectedContent: "is selected to appende events",
// Other
applicationType: "Application Type",
availableApplications: "Available Applications",
code: "Code",
sortBy: "Sort by:",
formErrors: "Please correct the errors in the form",
// Form group titles
identificationInfo: "Identification Information",
applicationDetails: "Application Details",
statusInfo: "Status Information",
systemInfo: "System Information",
createDescription: "Create Application",
},
tr: {
// Page title
mainTitle: "Servisler",
// Common actions
create: "Oluştur",
update: "Güncelle",
delete: "Sil",
view: "Görüntüle",
save: "Kaydet",
cancel: "İptal",
// Search and filters
search: "Ara",
typeSelection: "Tür Seçimi",
filterSelection: "Filtre Seçimi",
siteUrl: "Site URL",
resetAll: "Tümünü Sıfırla",
// Type options
web: "Web",
mobile: "Mobil",
// Status options
status: "Durum",
active: "Aktif",
inactive: "Pasif",
pending: "Beklemede",
// User types
employee: "Çalışan",
occupant: "Sakin",
// Pagination
showing: "Gösteriliyor",
of: "of",
items: "öğeler",
total: "Toplam",
filtered: "Filtreli",
previous: "Önceki",
next: "Sonraki",
page: "Sayfa",
itemsPerPage: "Sayfa başına öğeler",
// Messages
noData: "Veri bulunamadı",
serviceSelectedTitle: "Seçili Servis",
serviceSelectedContent: "is selected to appende events",
// Other
applicationType: "Uygulama Türü",
availableApplications: "Mevcut Uygulamalar",
code: "Kod",
sortBy: "Sırala:",
formErrors: "Lütfen formdaki hataları düzeltiniz",
// Form group titles
identificationInfo: "Kimlik Bilgileri",
applicationDetails: "Uygulama Detayları",
statusInfo: "Durum Bilgileri",
systemInfo: "Sistem Bilgileri",
createDescription: "Yeni bir uygulama oluşturun",
},
};
const translationsServices = {
en: {
...translations.en,
...ServiceBaseTranslationEn,
},
tr: {
...translations.tr,
...ServiceBaseTranslationTr,
},
};
const translationsApplications = {
en: {
...translations.en,
...ApplicationBaseTranslationEn,
},
tr: {
...translations.tr,
...ApplicationBaseTranslationTr,
},
};
export { translations, translationsServices, translationsApplications };
export function getTranslation(lang: LanguageKey): TranslationSet {
return translations[lang];
}

View File

@ -0,0 +1,372 @@
"use client";
import React, { useState, useEffect } from "react";
import { z } from "zod";
import {
ServiceData,
serviceViewFieldDefinitions,
ServiceFieldDefinitionsType,
ServiceSchema,
serviceFieldsByMode,
} from "./schemaList/services";
import {
ApplicationData,
ApplicationFieldDefinitionsType,
ApplicationSchema,
applicationFieldsByMode,
applicationViewFieldDefinitions
} from "./schemaList/application";
import { ListComponentEvents, ListComponentServices } from "./listComponent";
import { translations, translationsServices, translationsApplications } from "./language";
import { PageProps } from "@/validations/translations/translation";
import { FormModeView, FormMode } from "@/components/common/FormDisplay/types";
import { FormDisplay } from "@/components/common/FormDisplay/FormDisplay";
import { GridSelectionComponent, GridSize } from "@/components/common/HeaderSelections/GridSelectionComponent";
import { useApiData } from "@/components/common";
import { Language } from "@/components/common/schemas";
import { Card, CardContent, CardHeader } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { CardSize } from "@/components/common/CardDisplay/schema";
import { translationsAppenders } from "../appendersEvents/language";
import Loader from "@/components/common/Loader/loader";
const AppendersApplicationPage: React.FC<PageProps> = ({ lang }: { lang: Language }) => {
const urlServices = '/api/services/list';
const urlEvents = '/api/applications/list';
const urlAppenders = '/api/appenders/applications/list';
const urlAppendersCreate = '/api/appenders/applications/create';
const urlAppendersDelete = '/api/appenders/applications/delete';
const showFieldsServices = ["service_name", "service_code", "related_responsibility"];
const showFieldsEvents = ["description", "name", "site_url", "application_code"];
const {
data: dataServices,
pagination: paginationServices,
loading: loadingServices,
error: errorServices,
updatePagination: updatePaginationServices,
refetch: refetchServices
} = useApiData<ServiceData>(urlServices);
const {
data: dataEvents,
pagination: paginationEvents,
loading: loadingEvents,
error: errorEvents,
updatePagination: updatePaginationEvents,
refetch: refetchEvents
} = useApiData<ApplicationData>(urlEvents);
const {
data: dataAppenders,
pagination: paginationAppenders,
loading: loadingAppenders,
error: errorAppenders,
updatePagination: updatePaginationAppenders,
refetch: refetchAppenders
} = useApiData<ApplicationData>(urlAppenders);
const [mode, setMode] = useState<FormModeView | FormMode>("list");
const [gridCols, setGridCols] = useState<GridSize>(3);
const [selectedItemServices, setSelectedItemServices] = useState<ServiceData | null>(null);
const [selectedItemEvents, setSelectedItemEvents] = useState<ApplicationData | null>(null);
const [selectedItemAppenders, setSelectedItemAppenders] = useState<ApplicationData | null>(null);
const [fieldDefinitionsServices, setFieldDefinitionsServices] = useState<ServiceFieldDefinitionsType | null>(null);
const [fieldDefinitionsEvents, setFieldDefinitionsEvents] = useState<ApplicationFieldDefinitionsType | null>(null);
const [fieldDefinitionsAppenders, setFieldDefinitionsAppenders] = useState<ApplicationFieldDefinitionsType | null>(null);
const [validationSchemaServices, setValidationSchemaServices] = useState<z.ZodSchema | null>(null);
const [validationSchemaEvents, setValidationSchemaEvents] = useState<z.ZodSchema | null>(null);
const [validationSchemaAppenders, setValidationSchemaAppenders] = useState<z.ZodSchema | null>(null);
const [selectionBar, setSelectionBar] = useState<string>("");
const [languageTranslations, setLanguageTranslations] = useState({
mainTitle: translations[lang].mainTitle,
serviceSelectedTitle: translations[lang].serviceSelectedTitle,
serviceSelectedContent: translations[lang].serviceSelectedContent,
cancel: translations[lang].cancel,
});
const appendServiceEvent = async (app: ApplicationData) => {
if (!selectedItemServices?.uu_id) {
throw new Error("Service not selected");
}
const payload = { application_uu_id: app.uu_id, service_uu_id: selectedItemServices.uu_id }
fetch(urlAppendersCreate, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
}).then((res) => {
if (res.ok) {
updatePaginationAppenders({
...paginationAppenders,
query: {
...paginationAppenders.query,
service_uu_id: selectedItemServices.uu_id
}
});
updatePaginationEvents({
...paginationEvents,
query: {
...paginationEvents.query,
service_uu_id: selectedItemServices.uu_id
}
});
}
})
}
const removeServiceEvent = async (app: ApplicationData) => {
if (!selectedItemServices?.uu_id) {
throw new Error("Service not selected");
}
const payload = { application_uu_id: app.uu_id, service_uu_id: selectedItemServices.uu_id }
fetch(urlAppendersDelete, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
}).then((res) => {
if (res.ok) {
updatePaginationAppenders({
...paginationAppenders,
query: {
...paginationAppenders.query,
service_uu_id: selectedItemServices.uu_id
}
});
updatePaginationEvents({
...paginationEvents,
query: {
...paginationEvents.query,
service_uu_id: selectedItemServices.uu_id
}
});
}
})
}
useEffect(() => {
setFieldDefinitionsServices(serviceViewFieldDefinitions); setValidationSchemaServices(ServiceSchema);
setFieldDefinitionsEvents(applicationViewFieldDefinitions); setValidationSchemaEvents(ApplicationSchema);
setFieldDefinitionsAppenders(applicationViewFieldDefinitions); setValidationSchemaAppenders(ApplicationSchema);
setLanguageTranslations({
mainTitle: translations[lang].mainTitle,
serviceSelectedTitle: translations[lang].serviceSelectedTitle,
serviceSelectedContent: translations[lang].serviceSelectedContent,
cancel: translations[lang].cancel,
});
}, [lang]);
useEffect(() => {
if (selectedItemServices && selectedItemServices?.uu_id) {
updatePaginationAppenders({
page: paginationAppenders.page,
size: paginationAppenders.size,
orderField: paginationAppenders.orderField,
orderType: paginationAppenders.orderType,
query: {
...paginationAppenders.query,
service_uu_id: selectedItemServices.uu_id
}
});
updatePaginationEvents({
page: paginationEvents.page,
size: paginationEvents.size,
orderField: paginationEvents.orderField,
orderType: paginationEvents.orderType,
query: {
...paginationEvents.query,
service_uu_id: selectedItemServices.uu_id
}
});
setSelectionBar(
selectedItemServices ?
`${selectedItemServices.uu_id} ${selectedItemServices?.service_name} ${translations[lang].serviceSelectedContent}` :
"No service is selected to be appended to applications"
);
}
}, [selectedItemServices]);
const handleQueryChangeServices = (key: string, value: string | null) => {
const newQuery = { ...paginationServices.query };
if (value === null) { delete newQuery[key] } else if (value.trim() === "") { delete newQuery[key] } else { newQuery[key] = value }
updatePaginationServices({ page: 1, query: newQuery })
};
const handleQueryChangeEvents = (key: string, value: string | null) => {
const newQuery = { ...paginationEvents.query };
if (value === null) { delete newQuery[key] } else if (value.trim() === "") { delete newQuery[key] } else { newQuery[key] = value }
if (selectedItemServices?.uu_id) {
newQuery.service_uu_id = selectedItemServices.uu_id;
}
updatePaginationEvents({ page: 1, query: newQuery });
};
const handleQueryChangeAppenders = (key: string, value: string | null) => {
const newQuery = { ...paginationAppenders.query };
if (value === null) { delete newQuery[key] } else if (value.trim() === "") { delete newQuery[key] } else { newQuery[key] = value }
if (selectedItemServices?.uu_id) {
newQuery.service_uu_id = selectedItemServices.uu_id;
}
updatePaginationAppenders({ page: 1, query: newQuery });
};
const handleServicesCardClick = (item: ServiceData) => { setSelectedItemServices(item) };
const handleServicesViewClick = (item: ServiceData) => { setSelectedItemServices(item); setMode("view"); };
const handleEventsCardClick = (item: ApplicationData) => { appendServiceEvent(item); };
const handleEventsViewClick = (item: ApplicationData) => { setSelectedItemEvents(item); setMode("view"); };
const handleAppendersCardClick = (item: ApplicationData) => { removeServiceEvent(item); };
const handleAppendersViewClick = (item: ApplicationData) => { setSelectedItemAppenders(item); setMode("view"); };
const cancelAllSelections = () => {
setMode("list");
setSelectedItemServices(null);
setSelectedItemEvents(null);
setSelectedItemAppenders(null);
};
const serviceListProps = {
lang,
loading: loadingServices,
error: errorServices,
data: dataServices,
pagination: paginationServices,
showFields: showFieldsServices,
gridCols: gridCols,
titleField: "service_name",
size: "lg" as CardSize,
handleQueryChange: handleQueryChangeServices,
updatePagination: updatePaginationServices,
handleCardClick: handleServicesCardClick,
handleViewClick: handleServicesViewClick
};
const eventsListProps = {
lang,
loading: loadingEvents,
error: errorEvents,
data: dataEvents,
pagination: paginationEvents,
showFields: showFieldsEvents,
gridCols: 1,
titleField: "description",
size: "lg" as CardSize,
handleQueryChange: handleQueryChangeEvents,
updatePagination: updatePaginationEvents,
handleCardClick: handleEventsCardClick,
handleViewClick: handleEventsViewClick
};
const appendersListProps = {
lang,
loading: loadingAppenders,
error: errorAppenders,
data: dataAppenders,
pagination: paginationAppenders,
showFields: showFieldsEvents,
gridCols: 1,
titleField: "description",
size: "lg" as CardSize,
handleQueryChange: handleQueryChangeAppenders,
updatePagination: updatePaginationAppenders,
handleCardClick: handleAppendersCardClick,
handleViewClick: handleAppendersViewClick
};
const serviceFormProps = {
initialData: selectedItemServices || undefined,
mode: mode,
refetch: refetchServices,
setMode: setMode,
setSelectedItem: setSelectedItemServices,
onCancel: cancelAllSelections,
lang: lang,
translations: translationsServices,
apiUrl: '/api/services',
formProps: {
fieldDefinitions: fieldDefinitionsServices,
validationSchema: validationSchemaServices,
fieldsByMode: serviceFieldsByMode
}
};
const eventsFormProps = {
initialData: selectedItemEvents || undefined,
mode: mode,
refetch: refetchEvents,
setMode: setMode,
setSelectedItem: setSelectedItemEvents,
onCancel: cancelAllSelections,
lang: lang,
translations: translationsApplications,
apiUrl: '/api/applications',
formProps: {
fieldDefinitions: fieldDefinitionsEvents,
validationSchema: validationSchemaEvents,
fieldsByMode: applicationFieldsByMode,
}
};
const appendersFormProps = {
initialData: selectedItemAppenders || undefined,
mode: mode,
refetch: refetchAppenders,
setMode: setMode,
setSelectedItem: setSelectedItemAppenders,
onCancel: cancelAllSelections,
lang: lang,
translations: translationsAppenders,
apiUrl: '/api/appenders/applications',
formProps: {
fieldDefinitions: fieldDefinitionsAppenders,
validationSchema: validationSchemaAppenders,
fieldsByMode: applicationFieldsByMode,
}
};
return (
<div className="container mx-auto p-4 overflow-y-auto" >
<div className="mb-4 flex justify-between items-center">
<h1 className="text-2xl font-bold">{languageTranslations.mainTitle}</h1>
<div className="flex space-x-4"><GridSelectionComponent gridCols={gridCols} setGridCols={setGridCols} /></div>
</div>
<Button onClick={cancelAllSelections}>{languageTranslations.cancel}</Button>
<Card className="my-5">
<CardHeader>{languageTranslations.serviceSelectedTitle}</CardHeader>
<CardContent>{selectionBar}</CardContent>
</Card>
{mode === "list" ? (
<div className="flex flex-col space-y-4">
{
!selectedItemServices ? <div className="w-full h-1/2"><ListComponentServices {...serviceListProps} /></div> :
<div className="w-full h-1/2">
<div className="flex flex-row space-x-4">
{
loadingEvents ? <Loader /> : <div className="flex-1"><ListComponentEvents {...eventsListProps} /></div>
}
{
loadingAppenders ? <Loader /> : <div className="flex-1"><ListComponentEvents {...appendersListProps} /></div>
}
</div>
</div>
}
</div>
) : (
<div className="flex flex-col space-y-4">
{selectedItemServices && <FormDisplay<ServiceData> {...serviceFormProps} />}
{selectedItemEvents && <FormDisplay<ApplicationData> {...eventsFormProps} />}
{selectedItemAppenders && <FormDisplay<ApplicationData> {...appendersFormProps} />}
</div>
)}
</div>
);
};
export default AppendersApplicationPage;

View File

@ -1,8 +1,8 @@
import { z } from "zod"; import { z } from "zod";
import { flattenFieldDefinitions } from "@/eventRouters/schemas/zodSchemas"; import { flattenFieldDefinitions } from "@/eventRouters/schemas/zodSchemas";
export interface ApplicationData { interface ApplicationData {
id?: number; uu_id: string;
name: string; name: string;
application_code: string; application_code: string;
site_url: string; site_url: string;
@ -15,7 +15,6 @@ export interface ApplicationData {
updated_at?: string; updated_at?: string;
} }
// Validation error messages by language
const errorMessages = { const errorMessages = {
en: { en: {
nameRequired: "Name is required", nameRequired: "Name is required",
@ -31,7 +30,6 @@ const errorMessages = {
}, },
}; };
// Function to get schema with language-specific validation messages
const getApplicationBaseSchema = (lang: "en" | "tr" = "en") => const getApplicationBaseSchema = (lang: "en" | "tr" = "en") =>
z.object({ z.object({
// Identification fields // Identification fields
@ -58,10 +56,9 @@ const getApplicationBaseSchema = (lang: "en" | "tr" = "en") =>
updated_at: z.string().optional(), updated_at: z.string().optional(),
}); });
// For backward compatibility
const ApplicationBaseSchema = getApplicationBaseSchema("en"); const ApplicationBaseSchema = getApplicationBaseSchema("en");
export const ApplicationBaseTranslationTr = { const ApplicationBaseTranslationTr = {
uu_id: "UUID", uu_id: "UUID",
name: "Name", name: "Name",
application_code: "Application Code", application_code: "Application Code",
@ -75,7 +72,7 @@ export const ApplicationBaseTranslationTr = {
updated_at: "Updated At", updated_at: "Updated At",
}; };
export const ApplicationBaseTranslationEn = { const ApplicationBaseTranslationEn = {
uu_id: "UUID", uu_id: "UUID",
name: "Name", name: "Name",
application_code: "Application Code", application_code: "Application Code",
@ -89,7 +86,6 @@ export const ApplicationBaseTranslationEn = {
updated_at: "Updated At", updated_at: "Updated At",
}; };
// Create schema for creating new applications with language support
const getCreateApplicationSchema = (lang: "en" | "tr" = "en") => const getCreateApplicationSchema = (lang: "en" | "tr" = "en") =>
getApplicationBaseSchema(lang).omit({ getApplicationBaseSchema(lang).omit({
uu_id: true, uu_id: true,
@ -98,7 +94,6 @@ const getCreateApplicationSchema = (lang: "en" | "tr" = "en") =>
deleted: true, deleted: true,
}); });
// Update schema for updating existing applications with language support
const getUpdateApplicationSchema = (lang: "en" | "tr" = "en") => const getUpdateApplicationSchema = (lang: "en" | "tr" = "en") =>
getApplicationBaseSchema(lang) getApplicationBaseSchema(lang)
.omit({ .omit({
@ -110,34 +105,14 @@ const getUpdateApplicationSchema = (lang: "en" | "tr" = "en") =>
uu_id: true, uu_id: true,
}); });
// For backward compatibility
const CreateApplicationSchema = getCreateApplicationSchema("en");
const UpdateApplicationSchema = getUpdateApplicationSchema("en");
// Schema for viewing an application (all fields)
const ViewApplicationSchema = ApplicationBaseSchema; const ViewApplicationSchema = ApplicationBaseSchema;
// Default schema (used for validation)
const ApplicationSchema = ApplicationBaseSchema; const ApplicationSchema = ApplicationBaseSchema;
// Export all schemas and schema generators type ApplicationFormData = z.infer<typeof ApplicationSchema>;
export { type ViewApplicationFormData = z.infer<typeof ViewApplicationSchema>;
ApplicationBaseSchema,
ApplicationSchema,
CreateApplicationSchema,
UpdateApplicationSchema,
ViewApplicationSchema,
getApplicationBaseSchema,
getCreateApplicationSchema,
getUpdateApplicationSchema,
};
export type ApplicationFormData = z.infer<typeof ApplicationSchema>; const applicationBaseFieldDefinitions = {
export type CreateApplicationFormData = z.infer<typeof CreateApplicationSchema>; // Identification fields
export type UpdateApplicationFormData = z.infer<typeof UpdateApplicationSchema>;
export type ViewApplicationFormData = z.infer<typeof ViewApplicationSchema>;
const baseFieldDefinitions = {
identificationInfo: { identificationInfo: {
title: "Identification Information", title: "Identification Information",
order: 1, order: 1,
@ -171,6 +146,8 @@ const baseFieldDefinitions = {
}, },
}, },
}, },
// Application details
applicationDetails: { applicationDetails: {
title: "Application Details", title: "Application Details",
order: 2, order: 2,
@ -215,6 +192,8 @@ const baseFieldDefinitions = {
}, },
}, },
}, },
// Status fields
statusInfo: { statusInfo: {
title: "Status Information", title: "Status Information",
order: 3, order: 3,
@ -241,6 +220,8 @@ const baseFieldDefinitions = {
}, },
}, },
}, },
// System fields
systemInfo: { systemInfo: {
title: "System Information", title: "System Information",
order: 4, order: 4,
@ -266,198 +247,101 @@ const baseFieldDefinitions = {
}, },
}, },
}; };
const applicationFlatFieldDefinitions = flattenFieldDefinitions(
applicationBaseFieldDefinitions
);
const flatFieldDefinitions = flattenFieldDefinitions(baseFieldDefinitions); const applicationViewFieldDefinitions = {
export const createFieldDefinitions = {
name: {
...flatFieldDefinitions.name,
readOnly: false,
required: true,
defaultValue: "",
},
application_code: {
...flatFieldDefinitions.application_code,
readOnly: false,
required: true,
defaultValue: "",
},
site_url: {
...flatFieldDefinitions.site_url,
readOnly: false,
required: true,
defaultValue: "",
},
application_type: {
...flatFieldDefinitions.application_type,
readOnly: false,
required: true,
defaultValue: "",
},
application_for: {
...flatFieldDefinitions.application_for,
readOnly: false,
required: false,
defaultValue: "EMP",
},
description: {
...flatFieldDefinitions.description,
readOnly: false,
required: false,
defaultValue: "",
},
active: {
...flatFieldDefinitions.active,
readOnly: false,
required: false,
defaultValue: true,
},
};
export const updateFieldDefinitions = {
uu_id: { uu_id: {
...flatFieldDefinitions.uu_id, ...applicationFlatFieldDefinitions.uu_id,
readOnly: true,
required: false,
defaultValue: "",
},
name: {
...flatFieldDefinitions.name,
readOnly: false,
required: true,
defaultValue: "",
},
application_code: {
...flatFieldDefinitions.application_code,
readOnly: false,
required: true,
defaultValue: "",
},
site_url: {
...flatFieldDefinitions.site_url,
readOnly: false,
required: true,
defaultValue: "",
},
application_type: {
...flatFieldDefinitions.application_type,
readOnly: false,
required: true,
defaultValue: "",
},
application_for: {
...flatFieldDefinitions.application_for,
readOnly: false,
required: false,
defaultValue: "",
},
description: {
...flatFieldDefinitions.description,
readOnly: false,
required: false,
defaultValue: "",
},
active: {
...flatFieldDefinitions.active,
readOnly: false,
required: false,
defaultValue: true,
},
};
export const viewFieldDefinitions = {
uu_id: {
...flatFieldDefinitions.uu_id,
readOnly: true, readOnly: true,
required: false, required: false,
defaultValue: 0, defaultValue: 0,
}, },
name: { name: {
...flatFieldDefinitions.name, ...applicationFlatFieldDefinitions.name,
readOnly: true, readOnly: true,
required: false, required: false,
defaultValue: "", defaultValue: "",
}, },
application_code: { application_code: {
...flatFieldDefinitions.application_code, ...applicationFlatFieldDefinitions.application_code,
readOnly: true, readOnly: true,
required: false, required: false,
defaultValue: "", defaultValue: "",
}, },
site_url: { site_url: {
...flatFieldDefinitions.site_url, ...applicationFlatFieldDefinitions.site_url,
readOnly: true, readOnly: true,
required: false, required: false,
defaultValue: "", defaultValue: "",
}, },
application_type: { application_type: {
...flatFieldDefinitions.application_type, ...applicationFlatFieldDefinitions.application_type,
readOnly: true, readOnly: true,
required: false, required: false,
defaultValue: "", defaultValue: "",
}, },
application_for: { application_for: {
...flatFieldDefinitions.application_for, ...applicationFlatFieldDefinitions.application_for,
readOnly: true, readOnly: true,
required: false, required: false,
defaultValue: "", defaultValue: "",
}, },
description: { description: {
...flatFieldDefinitions.description, ...applicationFlatFieldDefinitions.description,
readOnly: true, readOnly: true,
required: false, required: false,
defaultValue: "", defaultValue: "",
}, },
active: { active: {
...flatFieldDefinitions.active, ...applicationFlatFieldDefinitions.active,
readOnly: true, readOnly: true,
required: false, required: false,
defaultValue: true, defaultValue: true,
}, },
deleted: { deleted: {
...flatFieldDefinitions.deleted, ...applicationFlatFieldDefinitions.deleted,
readOnly: true, readOnly: true,
required: false, required: false,
defaultValue: false, defaultValue: false,
}, },
created_at: { created_at: {
...flatFieldDefinitions.created_at, ...applicationFlatFieldDefinitions.created_at,
readOnly: true, readOnly: true,
required: false, required: false,
defaultValue: "", defaultValue: "",
}, },
updated_at: { updated_at: {
...flatFieldDefinitions.updated_at, ...applicationFlatFieldDefinitions.updated_at,
readOnly: true, readOnly: true,
required: false, required: false,
defaultValue: "", defaultValue: "",
}, },
}; };
const applicationFieldDefinitions = {
export const fieldDefinitions = { ...applicationBaseFieldDefinitions,
...baseFieldDefinitions, getDefinitionsByMode: (mode: "view") => {
getDefinitionsByMode: (mode: "create" | "update" | "view") => {
switch (mode) { switch (mode) {
case "create":
return createFieldDefinitions;
case "update":
return updateFieldDefinitions;
case "view": case "view":
return viewFieldDefinitions; return applicationViewFieldDefinitions;
default: default:
return baseFieldDefinitions; return applicationFieldDefinitions;
} }
}, },
}; };
const applicationFieldsByMode = {
// Fields to show based on mode - dynamically generated from field definitions view: Object.keys(applicationViewFieldDefinitions),
export const fieldsByMode = {
create: Object.keys(createFieldDefinitions),
update: Object.keys(updateFieldDefinitions),
view: Object.keys(viewFieldDefinitions),
}; };
export type FieldDefinitionsType = type ApplicationFieldDefinitionsType = typeof applicationViewFieldDefinitions;
| typeof createFieldDefinitions
| typeof updateFieldDefinitions export type { ApplicationData, ApplicationFieldDefinitionsType };
| typeof viewFieldDefinitions; export {
ApplicationSchema,
applicationFlatFieldDefinitions,
ApplicationBaseTranslationEn,
ApplicationBaseTranslationTr,
applicationFieldsByMode,
applicationViewFieldDefinitions,
};

View File

@ -1,8 +0,0 @@
import { PageProps } from "@/validations/translations/translation";
import React from "react";
const EventAppendPage: React.FC<PageProps> = () => {
return <div>EventAppendPage</div>;
};
export default EventAppendPage;

View File

@ -0,0 +1,217 @@
import React from 'react';
import { translations } from './language';
import { Filter } from 'lucide-react';
import { Card, CardContent } from '@/components/ui/card';
import { TextQueryModifier } from '@/components/common/QueryModifiers/TextQueryModifier';
import { PaginationToolsComponent } from '@/components/common/PaginationModifiers/PaginationToolsComponent';
import { CardDisplay } from '@/components/common/CardDisplay/CardDisplay';
import { ListComponentEventsProps, ListComponentServicesProps } from './type';
const ListComponentServices: React.FC<ListComponentServicesProps> = ({
lang,
loading,
error,
data,
pagination,
showFields,
gridCols,
titleField,
size,
handleQueryChange,
updatePagination,
handleCardClick,
handleViewClick,
}) => {
const fieldKey = "service_name";
return (
<>
{/* Search Filters */}
<Card>
<CardContent className="pt-6">
<div className="flex flex-col md:flex-row">
{/* Filters on the right */}
<div className={`w-full flex flex-col space-y-4`}>
<div className="font-medium text-sm mb-2 flex justify-between items-center">
<div className="flex items-center">
<Filter className="mr-2 h-4 w-4" />{translations[lang].filterSelection}
</div>
</div>
{/* Search input */}
<TextQueryModifier
fieldKey={fieldKey}
value={pagination.query[`${fieldKey}__ilike`] ? pagination.query[`${fieldKey}__ilike`].replace(/%/g, "") : ""}
label={translations[lang].search}
onQueryChange={handleQueryChange}
translations={translations}
lang={lang}
/>
</div>
</div>
</CardContent>
</Card>
{/* Pagination Tools Component */}
<Card className="my-4">
<CardContent className="pt-6">
<PaginationToolsComponent
pagination={pagination}
updatePagination={updatePagination}
loading={loading}
lang={lang}
translations={translations}
/>
</CardContent>
</Card>
{/* Card Display Component */}
<div className="mt-6">
<CardDisplay
showFields={showFields}
data={data}
lang={lang}
translations={translations}
error={error}
loading={loading}
titleField={titleField}
onCardClick={handleCardClick}
gridCols={gridCols}
size={size}
showViewIcon={true}
onViewClick={handleViewClick}
/>
</div>
</>
);
};
const ListComponentEvents: React.FC<ListComponentEventsProps> = ({
lang,
loading,
error,
data,
pagination,
showFields,
gridCols,
size,
handleQueryChange,
updatePagination,
handleCardClick,
handleViewClick,
}) => {
const fieldKey = "description";
return (
<>
{/* Search Filters */}
<Card>
<CardContent className="pt-6">
<div className="flex flex-col md:flex-row">
{/* Filters on the right */}
<div className={`w-full flex flex-col space-y-4`}>
<div className="font-medium text-sm mb-2 flex justify-between items-center">
<div className="flex items-center">
<Filter className="mr-2 h-4 w-4" />{translations[lang].filterSelection}
</div>
</div>
{/* Search input */}
<TextQueryModifier
fieldKey={fieldKey}
value={pagination.query[`${fieldKey}__ilike`] ? pagination.query[`${fieldKey}__ilike`].replace(/%/g, "") : ""}
label={translations[lang].search}
onQueryChange={handleQueryChange}
translations={translations}
lang={lang}
/>
</div>
</div>
</CardContent>
</Card>
{/* Pagination Tools Component */}
<Card className="my-4">
<CardContent className="pt-6">
<PaginationToolsComponent
pagination={pagination}
updatePagination={updatePagination}
loading={loading}
lang={lang}
translations={translations}
/>
</CardContent>
</Card>
{/* Card Display Component */}
<div className="mt-6">
<CardDisplay
showFields={showFields}
data={data}
lang={lang}
translations={translations}
error={error}
loading={loading}
titleField="name"
onCardClick={handleCardClick}
gridCols={gridCols}
showViewIcon={true}
onViewClick={handleViewClick}
size={size}
/>
</div>
</>
);
};
const ListComponentAppenders: React.FC<ListComponentEventsProps> = ({
lang,
loading,
error,
data,
pagination,
showFields,
gridCols,
size,
updatePagination,
handleCardClick,
handleViewClick,
}) => {
return (
<>
{/* Pagination Tools Component */}
<Card className="my-4">
<CardContent className="pt-6">
<PaginationToolsComponent
pagination={pagination}
updatePagination={updatePagination}
loading={loading}
lang={lang}
translations={translations}
/>
</CardContent>
</Card>
{/* Card Display Component */}
<div className="mt-6">
<CardDisplay
showFields={showFields}
data={data}
lang={lang}
translations={translations}
error={error}
loading={loading}
titleField="name"
onCardClick={handleCardClick}
gridCols={gridCols}
showViewIcon={true}
onViewClick={handleViewClick}
size={size}
/>
</div>
</>
);
};
export {
ListComponentEvents,
ListComponentServices,
ListComponentAppenders,
};

View File

@ -1,7 +1,6 @@
"use client"; "use client";
import React, { useState, useEffect } from "react"; import React, { useState, useEffect } from "react";
import { z } from "zod"; import { z } from "zod";
import { import {
ServiceData, ServiceData,
serviceViewFieldDefinitions, serviceViewFieldDefinitions,
@ -18,7 +17,6 @@ import {
} from "./schemaList/events"; } from "./schemaList/events";
import { ListComponentEvents, ListComponentServices } from "./listComponent"; import { ListComponentEvents, ListComponentServices } from "./listComponent";
import { translations, translationsServices, translationsAppenders, translationsEvents } from "./language"; import { translations, translationsServices, translationsAppenders, translationsEvents } from "./language";
import { PageProps } from "@/validations/translations/translation"; import { PageProps } from "@/validations/translations/translation";
import { FormModeView, FormMode } from "@/components/common/FormDisplay/types"; import { FormModeView, FormMode } from "@/components/common/FormDisplay/types";
import { FormDisplay } from "@/components/common/FormDisplay/FormDisplay"; import { FormDisplay } from "@/components/common/FormDisplay/FormDisplay";
@ -28,8 +26,17 @@ import { Language } from "@/components/common/schemas";
import { Card, CardContent, CardHeader } from "@/components/ui/card"; import { Card, CardContent, CardHeader } from "@/components/ui/card";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import { CardSize } from "@/components/common/CardDisplay/schema"; import { CardSize } from "@/components/common/CardDisplay/schema";
import Loader from "@/components/common/Loader/loader";
const AppendersServicePage: React.FC<PageProps> = ({ lang }: { lang: Language }) => { const AppendersEventsPage: React.FC<PageProps> = ({ lang }: { lang: Language }) => {
const urlServices = '/api/services/list';
const urlEvents = '/api/events/list';
const urlAppenders = '/api/appenders/events/list';
const urlAppendersCreate = '/api/appenders/events/create';
const urlAppendersDelete = '/api/appenders/events/delete';
const showFieldsServices = ["service_name", "service_code", "related_responsibility"];
const showFieldsEvents = ["description", "marketing_layer", "cost"];
const { const {
data: dataServices, data: dataServices,
@ -38,7 +45,7 @@ const AppendersServicePage: React.FC<PageProps> = ({ lang }: { lang: Language })
error: errorServices, error: errorServices,
updatePagination: updatePaginationServices, updatePagination: updatePaginationServices,
refetch: refetchServices refetch: refetchServices
} = useApiData<ServiceData>('/api/services'); } = useApiData<ServiceData>(urlServices);
const { const {
data: dataEvents, data: dataEvents,
pagination: paginationEvents, pagination: paginationEvents,
@ -46,7 +53,7 @@ const AppendersServicePage: React.FC<PageProps> = ({ lang }: { lang: Language })
error: errorEvents, error: errorEvents,
updatePagination: updatePaginationEvents, updatePagination: updatePaginationEvents,
refetch: refetchEvents refetch: refetchEvents
} = useApiData<EventData>('/api/events'); } = useApiData<EventData>(urlEvents);
const { const {
data: dataAppenders, data: dataAppenders,
pagination: paginationAppenders, pagination: paginationAppenders,
@ -54,7 +61,7 @@ const AppendersServicePage: React.FC<PageProps> = ({ lang }: { lang: Language })
error: errorAppenders, error: errorAppenders,
updatePagination: updatePaginationAppenders, updatePagination: updatePaginationAppenders,
refetch: refetchAppenders refetch: refetchAppenders
} = useApiData<EventData>('/api/appenders'); } = useApiData<EventData>(urlAppenders);
const [mode, setMode] = useState<FormModeView | FormMode>("list"); const [mode, setMode] = useState<FormModeView | FormMode>("list");
const [gridCols, setGridCols] = useState<GridSize>(3); const [gridCols, setGridCols] = useState<GridSize>(3);
@ -70,14 +77,33 @@ const AppendersServicePage: React.FC<PageProps> = ({ lang }: { lang: Language })
const [validationSchemaServices, setValidationSchemaServices] = useState<z.ZodSchema | null>(null); const [validationSchemaServices, setValidationSchemaServices] = useState<z.ZodSchema | null>(null);
const [validationSchemaEvents, setValidationSchemaEvents] = useState<z.ZodSchema | null>(null); const [validationSchemaEvents, setValidationSchemaEvents] = useState<z.ZodSchema | null>(null);
const [validationSchemaAppenders, setValidationSchemaAppenders] = useState<z.ZodSchema | null>(null); const [validationSchemaAppenders, setValidationSchemaAppenders] = useState<z.ZodSchema | null>(null);
const [selectionBar, setSelectionBar] = useState<string>("");
const [languageTranslations, setLanguageTranslations] = useState({
mainTitle: translations[lang].mainTitle,
serviceSelectedTitle: translations[lang].serviceSelectedTitle,
serviceSelectedContent: translations[lang].serviceSelectedContent,
cancel: translations[lang].cancel,
});
const showFieldsServices = ["service_name", "service_code", "related_responsibility"]; const handleServicesCardClick = (item: ServiceData) => { setSelectedItemServices(item) };
const showFieldsEvents = ["description", "marketing_layer", "cost"]; const handleServicesViewClick = (item: ServiceData) => { setSelectedItemServices(item); setMode("view"); };
const handleEventsCardClick = (item: EventData) => { appendServiceEvent(item); };
const handleEventsViewClick = (item: EventData) => { setSelectedItemEvents(item); setMode("view"); };
const handleAppendersCardClick = (item: EventData) => { removeServiceEvent(item); };
const handleAppendersViewClick = (item: EventData) => { setSelectedItemAppenders(item); setMode("view"); };
useEffect(() => { useEffect(() => {
setFieldDefinitionsServices(serviceViewFieldDefinitions); setValidationSchemaServices(ServiceSchema); setFieldDefinitionsServices(serviceViewFieldDefinitions); setValidationSchemaServices(ServiceSchema);
setFieldDefinitionsEvents(eventFlatFieldDefinitions); setValidationSchemaEvents(EventSchema); setFieldDefinitionsEvents(eventFlatFieldDefinitions); setValidationSchemaEvents(EventSchema);
setFieldDefinitionsAppenders(eventFlatFieldDefinitions); setValidationSchemaAppenders(EventSchema); setFieldDefinitionsAppenders(eventFlatFieldDefinitions); setValidationSchemaAppenders(EventSchema);
setLanguageTranslations({
mainTitle: translations[lang].mainTitle,
serviceSelectedTitle: translations[lang].serviceSelectedTitle,
serviceSelectedContent: translations[lang].serviceSelectedContent,
cancel: translations[lang].cancel,
});
}, [lang]); }, [lang]);
useEffect(() => { useEffect(() => {
@ -92,7 +118,6 @@ const AppendersServicePage: React.FC<PageProps> = ({ lang }: { lang: Language })
service_uu_id: selectedItemServices.uu_id service_uu_id: selectedItemServices.uu_id
} }
}); });
updatePaginationEvents({ updatePaginationEvents({
page: paginationEvents.page, page: paginationEvents.page,
size: paginationEvents.size, size: paginationEvents.size,
@ -103,7 +128,13 @@ const AppendersServicePage: React.FC<PageProps> = ({ lang }: { lang: Language })
service_uu_id: selectedItemServices.uu_id service_uu_id: selectedItemServices.uu_id
} }
}); });
setSelectionBar(
selectedItemServices ?
`${selectedItemServices.uu_id} ${selectedItemServices?.service_name} ${translations[lang].serviceSelectedContent}` :
"No service is selected to be appended to events"
);
} }
}, [selectedItemServices]); }, [selectedItemServices]);
const handleQueryChangeServices = (key: string, value: string | null) => { const handleQueryChangeServices = (key: string, value: string | null) => {
@ -115,7 +146,6 @@ const AppendersServicePage: React.FC<PageProps> = ({ lang }: { lang: Language })
const handleQueryChangeEvents = (key: string, value: string | null) => { const handleQueryChangeEvents = (key: string, value: string | null) => {
const newQuery = { ...paginationEvents.query }; const newQuery = { ...paginationEvents.query };
if (value === null) { delete newQuery[key] } else if (value.trim() === "") { delete newQuery[key] } else { newQuery[key] = value } if (value === null) { delete newQuery[key] } else if (value.trim() === "") { delete newQuery[key] } else { newQuery[key] = value }
if (selectedItemServices?.uu_id) { if (selectedItemServices?.uu_id) {
newQuery.service_uu_id = selectedItemServices.uu_id; newQuery.service_uu_id = selectedItemServices.uu_id;
} }
@ -136,7 +166,7 @@ const AppendersServicePage: React.FC<PageProps> = ({ lang }: { lang: Language })
throw new Error("Service not selected"); throw new Error("Service not selected");
} }
const payload = { event_uu_id: event.uu_id, service_uu_id: selectedItemServices.uu_id } const payload = { event_uu_id: event.uu_id, service_uu_id: selectedItemServices.uu_id }
fetch('/api/appenders/create', { fetch(urlAppendersCreate, {
method: 'POST', method: 'POST',
headers: { 'Content-Type': 'application/json' }, headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload) body: JSON.stringify(payload)
@ -165,7 +195,7 @@ const AppendersServicePage: React.FC<PageProps> = ({ lang }: { lang: Language })
throw new Error("Service not selected"); throw new Error("Service not selected");
} }
const payload = { event_uu_id: event.uu_id, service_uu_id: selectedItemServices.uu_id } const payload = { event_uu_id: event.uu_id, service_uu_id: selectedItemServices.uu_id }
fetch('/api/appenders/delete', { fetch(urlAppendersDelete, {
method: 'POST', method: 'POST',
headers: { 'Content-Type': 'application/json' }, headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload) body: JSON.stringify(payload)
@ -189,15 +219,6 @@ const AppendersServicePage: React.FC<PageProps> = ({ lang }: { lang: Language })
}) })
} }
const handleServicesCardClick = (item: ServiceData) => { setSelectedItemServices(item); setMode("list"); };
const handleServicesViewClick = (item: ServiceData) => { setSelectedItemServices(item); setMode("view"); };
const handleEventsCardClick = (item: EventData) => { appendServiceEvent(item); };
const handleEventsViewClick = (item: EventData) => { setSelectedItemEvents(item); setMode("view"); };
const handleAppendersCardClick = (item: EventData) => { removeServiceEvent(item); };
const handleAppendersViewClick = (item: EventData) => { setSelectedItemAppenders(item); setMode("view"); };
const cancelAllSelections = () => { const cancelAllSelections = () => {
setMode("list"); setMode("list");
setSelectedItemServices(null); setSelectedItemServices(null);
@ -307,22 +328,22 @@ const AppendersServicePage: React.FC<PageProps> = ({ lang }: { lang: Language })
return ( return (
<div className="container mx-auto p-4 overflow-y-auto" > <div className="container mx-auto p-4 overflow-y-auto" >
<div className="mb-4 flex justify-between items-center"> <div className="mb-4 flex justify-between items-center">
<h1 className="text-2xl font-bold">{translations[lang].mainTitle}</h1> <h1 className="text-2xl font-bold">{languageTranslations.mainTitle}</h1>
<div className="flex space-x-4"><GridSelectionComponent gridCols={gridCols} setGridCols={setGridCols} /></div> <div className="flex space-x-4"><GridSelectionComponent gridCols={gridCols} setGridCols={setGridCols} /></div>
</div> </div>
<Button onClick={cancelAllSelections}>{languageTranslations.cancel}</Button>
<Card className="my-5">
<CardHeader>{languageTranslations.serviceSelectedTitle}</CardHeader>
<CardContent>{selectionBar}</CardContent>
</Card>
{mode === "list" ? ( {mode === "list" ? (
<div className="flex flex-col space-y-4"> <div className="flex flex-col space-y-4">
{ {
!selectedItemServices ? <div className="w-full h-1/2"><ListComponentServices {...serviceListProps} /></div> : !selectedItemServices ? <div className="w-full h-1/2"><ListComponentServices {...serviceListProps} /></div> :
<div className="w-full h-1/2"> <div className="w-full h-1/2">
<Button onClick={cancelAllSelections}>{translations[lang].cancel}</Button>
<Card className="my-5">
<CardHeader>{translations[lang].serviceSelectedTitle}</CardHeader>
<CardContent>{selectedItemServices.uu_id}{" "}{selectedItemServices?.service_name}{" "}{translations[lang].serviceSelectedContent}</CardContent>
</Card>
<div className="flex flex-row space-x-4"> <div className="flex flex-row space-x-4">
<div className="flex-1"><ListComponentEvents {...eventsListProps} /></div> {loadingEvents ? <Loader /> : <div className="flex-1"><ListComponentEvents {...eventsListProps} /></div>}
<div className="flex-1"><ListComponentEvents {...appendersListProps} /></div> {loadingAppenders ? <Loader /> : <div className="flex-1"><ListComponentEvents {...appendersListProps} /></div>}
</div> </div>
</div> </div>
} }
@ -338,4 +359,4 @@ const AppendersServicePage: React.FC<PageProps> = ({ lang }: { lang: Language })
); );
}; };
export default AppendersServicePage; export default AppendersEventsPage;

View File

@ -0,0 +1,295 @@
import { z } from "zod";
import { flattenFieldDefinitions } from "@/eventRouters/schemas/zodSchemas";
interface ServiceData {
uu_id: string;
module_uu_id: string;
service_name: string;
service_description?: string;
service_code: string;
related_responsibility?: string;
is_confirmed: boolean;
active: boolean;
deleted?: boolean;
created_at?: string;
updated_at?: string;
}
const errorMessages = {
en: {
moduleUuIdRequired: "Module UUID is required",
serviceNameRequired: "Service name is required",
serviceCodeRequired: "Service code is required",
},
tr: {
moduleUuIdRequired: "Modül UUID'si gereklidir",
serviceNameRequired: "Servis adı gereklidir",
serviceCodeRequired: "Servis kodu gereklidir",
},
};
const getServiceBaseSchema = (lang: "en" | "tr" = "en") =>
z.object({
uu_id: z.string().optional(),
module_uu_id: z.string().min(1, errorMessages[lang].moduleUuIdRequired),
service_name: z.string().min(1, errorMessages[lang].serviceNameRequired),
service_description: z.string().optional(),
service_code: z.string().min(1, errorMessages[lang].serviceCodeRequired),
related_responsibility: z.string().optional(),
is_confirmed: z.boolean().default(false),
active: z.boolean().default(true),
deleted: z.boolean().default(false),
created_at: z.string().optional(),
updated_at: z.string().optional(),
});
const ServiceBaseSchema = getServiceBaseSchema("en");
const ServiceBaseTranslationTr = {
uu_id: "UUID",
module_uu_id: "Modül UUID'si",
service_name: "Servis Adı",
service_description: "Servis Açıklaması",
service_code: "Servis Kodu",
related_responsibility: "İlgili Sorumluluk",
is_confirmed: "Onaylandı",
active: "Active",
deleted: "Deleted",
created_at: "Created At",
updated_at: "Updated At",
};
const ServiceBaseTranslationEn = {
uu_id: "UUID",
module_uu_id: "Module UUID",
service_name: "Service Name",
service_description: "Service Description",
service_code: "Service Code",
related_responsibility: "Related Responsibility",
is_confirmed: "Confirmed",
active: "Active",
deleted: "Deleted",
created_at: "Created At",
updated_at: "Updated At",
};
const ViewServiceSchema = ServiceBaseSchema;
const ServiceSchema = ServiceBaseSchema;
const serviceBaseFieldDefinitions = {
identificationInfo: {
title: "Service Information",
order: 1,
fields: {
uu_id: {
type: "text",
label: {
tr: ServiceBaseTranslationTr.uu_id,
en: ServiceBaseTranslationEn.uu_id,
},
readOnly: true,
required: false,
},
module_uu_id: {
type: "text",
label: {
tr: ServiceBaseTranslationTr.module_uu_id,
en: ServiceBaseTranslationEn.module_uu_id,
},
readOnly: false,
required: true,
},
service_name: {
type: "text",
label: {
tr: ServiceBaseTranslationTr.service_name,
en: ServiceBaseTranslationEn.service_name,
},
readOnly: false,
required: true,
},
service_description: {
type: "text",
label: {
tr: ServiceBaseTranslationTr.service_description,
en: ServiceBaseTranslationEn.service_description,
},
readOnly: false,
required: true,
},
service_code: {
type: "text",
label: {
tr: ServiceBaseTranslationTr.service_code,
en: ServiceBaseTranslationEn.service_code,
},
readOnly: false,
required: true,
},
related_responsibility: {
type: "text",
label: {
tr: ServiceBaseTranslationTr.related_responsibility,
en: ServiceBaseTranslationEn.related_responsibility,
},
readOnly: false,
required: false,
},
},
},
statusInfo: {
title: "Status Information",
order: 3,
fields: {
active: {
type: "checkbox",
label: {
tr: ServiceBaseTranslationTr.active,
en: ServiceBaseTranslationEn.active,
},
readOnly: false,
required: false,
defaultValue: true,
},
deleted: {
type: "checkbox",
label: {
tr: ServiceBaseTranslationTr.deleted,
en: ServiceBaseTranslationEn.deleted,
},
readOnly: true,
required: false,
defaultValue: false,
},
is_confirmed: {
type: "checkbox",
label: {
tr: ServiceBaseTranslationTr.is_confirmed,
en: ServiceBaseTranslationEn.is_confirmed,
},
readOnly: false,
required: true,
},
},
},
systemInfo: {
title: "System Information",
order: 4,
fields: {
created_at: {
type: "date",
label: {
tr: ServiceBaseTranslationTr.created_at,
en: ServiceBaseTranslationEn.created_at,
},
readOnly: true,
required: false,
},
updated_at: {
type: "date",
label: {
tr: ServiceBaseTranslationTr.updated_at,
en: ServiceBaseTranslationEn.updated_at,
},
readOnly: true,
required: false,
},
},
},
};
const serviceFlatFieldDefinitions = flattenFieldDefinitions(
serviceBaseFieldDefinitions
);
const serviceViewFieldDefinitions = {
uu_id: {
...serviceFlatFieldDefinitions.uu_id,
readOnly: true,
required: false,
defaultValue: 0,
},
module_uu_id: {
...serviceFlatFieldDefinitions.module_uu_id,
readOnly: true,
required: false,
defaultValue: "",
},
service_name: {
...serviceFlatFieldDefinitions.service_name,
readOnly: true,
required: false,
defaultValue: "",
},
service_description: {
...serviceFlatFieldDefinitions.service_description,
readOnly: true,
required: false,
defaultValue: "",
},
service_code: {
...serviceFlatFieldDefinitions.service_code,
readOnly: true,
required: false,
defaultValue: "",
},
related_responsibility: {
...serviceFlatFieldDefinitions.related_responsibility,
readOnly: true,
required: false,
defaultValue: "",
},
active: {
...serviceFlatFieldDefinitions.active,
readOnly: true,
required: false,
defaultValue: true,
},
is_confirmed: {
...serviceFlatFieldDefinitions.is_confirmed,
readOnly: true,
required: false,
defaultValue: true,
},
deleted: {
...serviceFlatFieldDefinitions.deleted,
readOnly: true,
required: false,
defaultValue: false,
},
created_at: {
...serviceFlatFieldDefinitions.created_at,
readOnly: true,
required: false,
defaultValue: "",
},
updated_at: {
...serviceFlatFieldDefinitions.updated_at,
readOnly: true,
required: false,
defaultValue: "",
},
};
const serviceFieldDefinitions = {
...serviceBaseFieldDefinitions,
getDefinitionsByMode: (mode: "view") => {
switch (mode) {
case "view":
return serviceViewFieldDefinitions;
default:
return serviceBaseFieldDefinitions;
}
},
};
const serviceFieldsByMode = {
view: Object.keys(serviceViewFieldDefinitions),
};
type ServiceFormData = z.infer<typeof ServiceSchema>;
type ServiceViewFormData = z.infer<typeof ViewServiceSchema>;
type ServiceFieldDefinitionsType = typeof serviceViewFieldDefinitions;
export type { ServiceData, ServiceFieldDefinitionsType };
export {
ServiceSchema,
serviceViewFieldDefinitions,
ServiceBaseTranslationEn,
ServiceBaseTranslationTr,
serviceFieldsByMode,
};

View File

@ -0,0 +1,37 @@
import { Language } from "@/components/common/schemas";
import { GridSize } from "@/components/common/HeaderSelections/GridSelectionComponent";
import { CardSize } from "@/components/common/CardDisplay/schema";
import * as schemaServices from "./schemaList/services";
import * as schemaEvents from "./schemaList/events";
export interface ListComponentServicesProps {
lang: Language;
loading: boolean;
error: any;
data: schemaServices.ServiceData[];
pagination: any;
showFields: string[];
gridCols: GridSize | number;
titleField: string;
size: CardSize;
handleQueryChange: (key: string, value: string | null) => void;
updatePagination: (pagination: any) => void;
handleCardClick: (item: schemaServices.ServiceData) => void;
handleViewClick: (item: schemaServices.ServiceData) => void;
}
export interface ListComponentEventsProps {
lang: Language;
loading: boolean;
error: any;
data: schemaEvents.EventData[];
pagination: any;
showFields: string[];
gridCols: GridSize | number;
titleField: string;
size: CardSize;
handleQueryChange: (key: string, value: string | null) => void;
updatePagination: (pagination: any) => void;
handleCardClick: (item: schemaEvents.EventData) => void;
handleViewClick: (item: schemaEvents.EventData) => void;
}

View File

@ -22,7 +22,7 @@ import { Language } from "@/components/common/schemas";
const ApplicationPage: React.FC<PageProps> = ({ lang }: { lang: Language }) => { const ApplicationPage: React.FC<PageProps> = ({ lang }: { lang: Language }) => {
const { data, pagination, loading, error, updatePagination, refetch } = useApiData<schema.ApplicationData>('/api/applications'); const { data, pagination, loading, error, updatePagination, refetch } = useApiData<schema.ApplicationData>('/api/applications/pages');
const [mode, setMode] = useState<FormMode>("list"); const [mode, setMode] = useState<FormMode>("list");
const [selectedItem, setSelectedItem] = useState<schema.ApplicationData | null>(null); const [selectedItem, setSelectedItem] = useState<schema.ApplicationData | null>(null);

View File

@ -2,7 +2,7 @@ import { z } from "zod";
import { flattenFieldDefinitions } from "@/eventRouters/schemas/zodSchemas"; import { flattenFieldDefinitions } from "@/eventRouters/schemas/zodSchemas";
export interface ApplicationData { export interface ApplicationData {
id?: number; uu_id: string;
name: string; name: string;
application_code: string; application_code: string;
site_url: string; site_url: string;

View File

@ -1,13 +1,13 @@
import DashboardPage from "./dashboard/page"; import DashboardPage from "./dashboard/page";
import ApplicationPage from "./application/page"; import ApplicationPage from "./application/page";
import EventAppendPage from "./appenderEvent/page"; import AppendersEventsPage from "./appenderApplication/page";
import ServiceAppendPage from "./appendersService/page"; import AppendersServicePage from "./appendersEvents/page";
const menuPages = { const menuPages = {
"/dashboard": DashboardPage, "/dashboard": DashboardPage,
"/application": ApplicationPage, "/application": ApplicationPage,
"/append/event": EventAppendPage, "/append/event": AppendersEventsPage,
"/append/service": ServiceAppendPage "/append/service": AppendersServicePage
}; };
export default menuPages; export default menuPages;

View File

@ -117,7 +117,19 @@ services:
context: . context: .
dockerfile: ApiServices/InitialService/Dockerfile dockerfile: ApiServices/InitialService/Dockerfile
environment: environment:
- SET_ALEMBIC=0 - SET_ALEMBIC=1
networks:
- wag-services
env_file:
- api_env.env
mem_limit: 512m
cpus: 0.5
dealer_service:
container_name: dealer_service
build:
context: .
dockerfile: ApiServices/DealerService/Dockerfile
networks: networks:
- wag-services - wag-services
env_file: env_file:
@ -152,18 +164,6 @@ services:
# mem_limit: 512m # mem_limit: 512m
# cpus: 0.5 # cpus: 0.5
dealer_service:
container_name: dealer_service
build:
context: .
dockerfile: ApiServices/DealerService/Dockerfile
networks:
- wag-services
env_file:
- api_env.env
mem_limit: 512m
cpus: 0.5
networks: networks:
wag-services: wag-services:
# template_service: # template_service: