Compare commits
11 Commits
VORKOUT-16
...
master
Author | SHA1 | Date | |
---|---|---|---|
5e3c3b4672 | |||
60160d46be | |||
d03600b23d | |||
82fcd22faf | |||
|
2690843954 | ||
2493cd0d9f | |||
|
f65f4caf5c | ||
|
a90a802659 | ||
|
3d5d717962 | ||
|
0bff556b10 | ||
|
f550b86c68 |
190
api/api/db/logic/listevents.py
Normal file
190
api/api/db/logic/listevents.py
Normal file
@ -0,0 +1,190 @@
|
|||||||
|
from typing import Optional
|
||||||
|
import math
|
||||||
|
|
||||||
|
from datetime import datetime, timezone
|
||||||
|
|
||||||
|
from sqlalchemy import insert, select, func
|
||||||
|
from sqlalchemy.ext.asyncio import AsyncConnection
|
||||||
|
from enum import Enum
|
||||||
|
|
||||||
|
from api.db.tables.events import list_events_table
|
||||||
|
|
||||||
|
|
||||||
|
from api.schemas.events.list_events import ListEvent
|
||||||
|
|
||||||
|
|
||||||
|
from api.schemas.endpoints.list_events import all_list_event_adapter, AllListEventResponse
|
||||||
|
|
||||||
|
|
||||||
|
async def get_listevents_page_by_creator_id(
|
||||||
|
connection: AsyncConnection, creator_id: int, page: int, limit: int
|
||||||
|
) -> Optional[AllListEventResponse]:
|
||||||
|
"""
|
||||||
|
Получает список событий заданного создателя по значениям page и limit и creator_id.
|
||||||
|
"""
|
||||||
|
|
||||||
|
first_event = page * limit - limit
|
||||||
|
query = (
|
||||||
|
select(
|
||||||
|
list_events_table.c.id,
|
||||||
|
list_events_table.c.name,
|
||||||
|
list_events_table.c.title,
|
||||||
|
list_events_table.c.creator_id,
|
||||||
|
list_events_table.c.created_at,
|
||||||
|
list_events_table.c.schema_,
|
||||||
|
list_events_table.c.state,
|
||||||
|
list_events_table.c.status,
|
||||||
|
)
|
||||||
|
.where(list_events_table.c.creator_id == creator_id) # Фильтрация по creator_id
|
||||||
|
.order_by(list_events_table.c.id)
|
||||||
|
.offset(first_event)
|
||||||
|
.limit(limit)
|
||||||
|
)
|
||||||
|
|
||||||
|
count_query = (
|
||||||
|
select(func.count())
|
||||||
|
.select_from(list_events_table)
|
||||||
|
.where(list_events_table.c.creator_id == creator_id) # Фильтрация по creator_id
|
||||||
|
)
|
||||||
|
|
||||||
|
result = await connection.execute(query)
|
||||||
|
count_result = await connection.execute(count_query)
|
||||||
|
|
||||||
|
events_data = result.mappings().all()
|
||||||
|
total_count = count_result.scalar()
|
||||||
|
total_pages = math.ceil(total_count / limit)
|
||||||
|
|
||||||
|
# Здесь предполагается, что all_list_event_adapter.validate_python корректно обрабатывает данные
|
||||||
|
validated_list_event = all_list_event_adapter.validate_python(events_data)
|
||||||
|
|
||||||
|
return AllListEventResponse(
|
||||||
|
list_event=validated_list_event,
|
||||||
|
amount_count=total_count,
|
||||||
|
amount_pages=total_pages,
|
||||||
|
current_page=page,
|
||||||
|
limit=limit,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def get_listevents_page(connection: AsyncConnection, page, limit) -> Optional[AllListEventResponse]:
|
||||||
|
"""
|
||||||
|
Получает список событий заданного создателя по значениям page и limit.
|
||||||
|
"""
|
||||||
|
|
||||||
|
first_event = page * limit - (limit)
|
||||||
|
|
||||||
|
query = (
|
||||||
|
select(
|
||||||
|
list_events_table.c.id,
|
||||||
|
list_events_table.c.name,
|
||||||
|
list_events_table.c.title,
|
||||||
|
list_events_table.c.creator_id,
|
||||||
|
list_events_table.c.created_at,
|
||||||
|
list_events_table.c.schema,
|
||||||
|
list_events_table.c.state,
|
||||||
|
list_events_table.c.status,
|
||||||
|
)
|
||||||
|
.order_by(list_events_table.c.id)
|
||||||
|
.offset(first_event)
|
||||||
|
.limit(limit)
|
||||||
|
)
|
||||||
|
|
||||||
|
count_query = select(func.count()).select_from(list_events_table)
|
||||||
|
|
||||||
|
result = await connection.execute(query)
|
||||||
|
count_result = await connection.execute(count_query)
|
||||||
|
|
||||||
|
events_data = result.mappings().all()
|
||||||
|
total_count = count_result.scalar()
|
||||||
|
total_pages = math.ceil(total_count / limit)
|
||||||
|
|
||||||
|
# Здесь предполагается, что all_list_event_adapter.validate_python корректно обрабатывает данные
|
||||||
|
validated_list_event = all_list_event_adapter.validate_python(events_data)
|
||||||
|
|
||||||
|
return AllListEventResponse(
|
||||||
|
list_event=validated_list_event,
|
||||||
|
amount_count=total_count,
|
||||||
|
amount_pages=total_pages,
|
||||||
|
current_page=page,
|
||||||
|
limit=limit,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def get_listevents_by_name(connection: AsyncConnection, name: str) -> Optional[ListEvent]:
|
||||||
|
"""
|
||||||
|
Получает list events по name.
|
||||||
|
"""
|
||||||
|
query = select(list_events_table).where(list_events_table.c.name == name)
|
||||||
|
|
||||||
|
listevents_db_cursor = await connection.execute(query)
|
||||||
|
listevents_db = listevents_db_cursor.one_or_none()
|
||||||
|
|
||||||
|
if not listevents_db:
|
||||||
|
return None
|
||||||
|
|
||||||
|
listevents_data = {
|
||||||
|
column.name: (
|
||||||
|
getattr(listevents_db, column.name).name
|
||||||
|
if isinstance(getattr(listevents_db, column.name), Enum)
|
||||||
|
else getattr(listevents_db, column.name)
|
||||||
|
)
|
||||||
|
for column in list_events_table.columns
|
||||||
|
}
|
||||||
|
|
||||||
|
return ListEvent.model_validate(listevents_data)
|
||||||
|
|
||||||
|
|
||||||
|
async def get_listevents_by_id(connection: AsyncConnection, id: int) -> Optional[ListEvent]:
|
||||||
|
"""
|
||||||
|
Получает listevent по id.
|
||||||
|
"""
|
||||||
|
query = select(list_events_table).where(list_events_table.c.id == id)
|
||||||
|
|
||||||
|
listevents_db_cursor = await connection.execute(query)
|
||||||
|
listevents_db = listevents_db_cursor.one_or_none()
|
||||||
|
|
||||||
|
if not listevents_db:
|
||||||
|
return None
|
||||||
|
|
||||||
|
listevents_data = {
|
||||||
|
column.name: (
|
||||||
|
getattr(listevents_db, column.name).name
|
||||||
|
if isinstance(getattr(listevents_db, column.name), Enum)
|
||||||
|
else getattr(listevents_db, column.name)
|
||||||
|
)
|
||||||
|
for column in list_events_table.columns
|
||||||
|
}
|
||||||
|
|
||||||
|
return ListEvent.model_validate(listevents_data)
|
||||||
|
|
||||||
|
|
||||||
|
async def update_listevents_by_id(connection: AsyncConnection, update_values, listevents):
|
||||||
|
"""
|
||||||
|
Вносит изменеия в нужное поле таблицы list_events_table.
|
||||||
|
"""
|
||||||
|
await connection.execute(
|
||||||
|
list_events_table.update().where(list_events_table.c.id == listevents.id).values(**update_values)
|
||||||
|
)
|
||||||
|
|
||||||
|
await connection.commit()
|
||||||
|
|
||||||
|
|
||||||
|
async def create_listevents(connection: AsyncConnection, listevents: ListEvent, creator_id: int) -> Optional[ListEvent]:
|
||||||
|
"""
|
||||||
|
Создает нове поле в таблице list_events_table.
|
||||||
|
"""
|
||||||
|
query = insert(list_events_table).values(
|
||||||
|
name=listevents.name,
|
||||||
|
title=listevents.title, # добавлено поле title
|
||||||
|
creator_id=creator_id,
|
||||||
|
created_at=datetime.now(timezone.utc),
|
||||||
|
schema=listevents.schema_, # добавлено поле schema
|
||||||
|
state=listevents.state.value, # добавлено поле state
|
||||||
|
status=listevents.status.value, # добавлено поле status
|
||||||
|
)
|
||||||
|
|
||||||
|
await connection.execute(query)
|
||||||
|
|
||||||
|
await connection.commit()
|
||||||
|
|
||||||
|
return listevents
|
@ -3,8 +3,6 @@ import enum
|
|||||||
from sqlalchemy import Table, Column, String, Enum as SQLAEnum, JSON, ForeignKey, DateTime, Index
|
from sqlalchemy import Table, Column, String, Enum as SQLAEnum, JSON, ForeignKey, DateTime, Index
|
||||||
from sqlalchemy.sql import func
|
from sqlalchemy.sql import func
|
||||||
|
|
||||||
from enum import Enum
|
|
||||||
|
|
||||||
from api.db.sql_types import UnsignedInt
|
from api.db.sql_types import UnsignedInt
|
||||||
from api.db import metadata
|
from api.db import metadata
|
||||||
|
|
||||||
|
@ -2,8 +2,9 @@ from api.endpoints.auth import api_router as auth_router
|
|||||||
from api.endpoints.profile import api_router as profile_router
|
from api.endpoints.profile import api_router as profile_router
|
||||||
from api.endpoints.account import api_router as account_router
|
from api.endpoints.account import api_router as account_router
|
||||||
from api.endpoints.keyring import api_router as keyring_router
|
from api.endpoints.keyring import api_router as keyring_router
|
||||||
|
from api.endpoints.listevents import api_router as listevents_router
|
||||||
|
|
||||||
list_of_routes = [auth_router, profile_router, account_router, keyring_router]
|
list_of_routes = [auth_router, profile_router, account_router, keyring_router, listevents_router]
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
"list_of_routes",
|
"list_of_routes",
|
||||||
|
169
api/api/endpoints/listevents.py
Normal file
169
api/api/endpoints/listevents.py
Normal file
@ -0,0 +1,169 @@
|
|||||||
|
from fastapi import (
|
||||||
|
APIRouter,
|
||||||
|
Depends,
|
||||||
|
HTTPException,
|
||||||
|
status,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
from sqlalchemy.ext.asyncio import AsyncConnection
|
||||||
|
|
||||||
|
from api.db.connection.session import get_connection_dep
|
||||||
|
|
||||||
|
from api.db.logic.account import get_user_by_login
|
||||||
|
|
||||||
|
from api.db.logic.listevents import (
|
||||||
|
get_listevents_by_name,
|
||||||
|
get_listevents_by_id,
|
||||||
|
create_listevents,
|
||||||
|
update_listevents_by_id,
|
||||||
|
get_listevents_page,
|
||||||
|
get_listevents_page_by_creator_id,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
from api.schemas.events.list_events import ListEvent
|
||||||
|
from api.db.tables.events import EventStatus
|
||||||
|
|
||||||
|
from api.schemas.base import bearer_schema
|
||||||
|
|
||||||
|
from api.schemas.endpoints.list_events import ListEventUpdate, AllListEventResponse
|
||||||
|
|
||||||
|
from api.services.auth import get_current_user
|
||||||
|
|
||||||
|
from api.services.user_role_validation import (
|
||||||
|
db_user_role_validation_for_listevents_by_listevent_id,
|
||||||
|
db_user_role_validation_for_listevents,
|
||||||
|
)
|
||||||
|
from api.services.update_data_validation import update_listevents_data_changes
|
||||||
|
|
||||||
|
|
||||||
|
api_router = APIRouter(
|
||||||
|
prefix="/listevents",
|
||||||
|
tags=["list events"],
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@api_router.get("", dependencies=[Depends(bearer_schema)], response_model=AllListEventResponse)
|
||||||
|
async def get_all_list_events(
|
||||||
|
page: int = 1,
|
||||||
|
limit: int = 10,
|
||||||
|
connection: AsyncConnection = Depends(get_connection_dep),
|
||||||
|
current_user=Depends(get_current_user),
|
||||||
|
):
|
||||||
|
authorize_user, page_flag = await db_user_role_validation_for_listevents(connection, current_user)
|
||||||
|
|
||||||
|
if page_flag:
|
||||||
|
list_eventslist = await get_listevents_page(connection, page, limit)
|
||||||
|
print(list_eventslist)
|
||||||
|
if list_eventslist is None:
|
||||||
|
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="List events not found")
|
||||||
|
|
||||||
|
return list_eventslist
|
||||||
|
else:
|
||||||
|
list_events_list = await get_listevents_page_by_creator_id(connection, authorize_user.id, page, limit)
|
||||||
|
|
||||||
|
if list_events_list is None:
|
||||||
|
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="List events not found")
|
||||||
|
|
||||||
|
return list_events_list
|
||||||
|
|
||||||
|
|
||||||
|
@api_router.get("/{listevents_id}", dependencies=[Depends(bearer_schema)], response_model=ListEvent)
|
||||||
|
async def get_list_events(
|
||||||
|
listevents_id: int,
|
||||||
|
connection: AsyncConnection = Depends(get_connection_dep),
|
||||||
|
current_user=Depends(get_current_user),
|
||||||
|
):
|
||||||
|
listevents_validation = await get_listevents_by_id(connection, listevents_id)
|
||||||
|
|
||||||
|
if listevents_validation is None:
|
||||||
|
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="List events not found")
|
||||||
|
|
||||||
|
authorize_user = await db_user_role_validation_for_listevents_by_listevent_id(
|
||||||
|
connection, current_user, listevents_validation.creator_id
|
||||||
|
)
|
||||||
|
|
||||||
|
if listevents_id is None:
|
||||||
|
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="List events not found")
|
||||||
|
|
||||||
|
return listevents_validation
|
||||||
|
|
||||||
|
|
||||||
|
@api_router.post("", dependencies=[Depends(bearer_schema)], response_model=ListEvent)
|
||||||
|
async def create_list_events(
|
||||||
|
listevents: ListEventUpdate,
|
||||||
|
connection: AsyncConnection = Depends(get_connection_dep),
|
||||||
|
current_user=Depends(get_current_user),
|
||||||
|
):
|
||||||
|
user_validation = await get_user_by_login(connection, current_user)
|
||||||
|
listevents_validation = await get_listevents_by_name(connection, listevents.name)
|
||||||
|
|
||||||
|
if listevents_validation is None:
|
||||||
|
await create_listevents(connection, listevents, user_validation.id)
|
||||||
|
listevents_new = await get_listevents_by_name(connection, listevents.name)
|
||||||
|
return listevents_new
|
||||||
|
|
||||||
|
else:
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_400_BAD_REQUEST, detail="An List events with this information already exists."
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@api_router.put("/{listevents_id}", dependencies=[Depends(bearer_schema)], response_model=ListEvent)
|
||||||
|
async def update_listevents(
|
||||||
|
listevents_id: int,
|
||||||
|
listevents_update: ListEventUpdate,
|
||||||
|
connection: AsyncConnection = Depends(get_connection_dep),
|
||||||
|
current_user=Depends(get_current_user),
|
||||||
|
):
|
||||||
|
listevents_validation = await get_listevents_by_id(connection, listevents_id)
|
||||||
|
|
||||||
|
if listevents_validation is None:
|
||||||
|
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="List events not found")
|
||||||
|
|
||||||
|
authorize_user = await db_user_role_validation_for_listevents_by_listevent_id(
|
||||||
|
connection, current_user, listevents_validation.creator_id
|
||||||
|
)
|
||||||
|
|
||||||
|
update_values = update_listevents_data_changes(listevents_update, listevents_validation)
|
||||||
|
|
||||||
|
if update_values is None:
|
||||||
|
return listevents_validation
|
||||||
|
|
||||||
|
listevents_update_data = ListEvent.model_validate({**listevents_validation.model_dump(), **update_values})
|
||||||
|
|
||||||
|
await update_listevents_by_id(connection, update_values, listevents_validation)
|
||||||
|
|
||||||
|
listevents = await get_listevents_by_id(connection, listevents_id)
|
||||||
|
|
||||||
|
return listevents
|
||||||
|
|
||||||
|
|
||||||
|
@api_router.delete("/{listevents_id}", dependencies=[Depends(bearer_schema)], response_model=ListEvent)
|
||||||
|
async def delete_list_events(
|
||||||
|
listevents_id: int,
|
||||||
|
connection: AsyncConnection = Depends(get_connection_dep),
|
||||||
|
current_user=Depends(get_current_user),
|
||||||
|
):
|
||||||
|
listevents_validation = await get_listevents_by_id(connection, listevents_id)
|
||||||
|
|
||||||
|
if listevents_validation is None:
|
||||||
|
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="List events not found")
|
||||||
|
|
||||||
|
authorize_user = await db_user_role_validation_for_listevents_by_listevent_id(
|
||||||
|
connection, current_user, listevents_validation.creator_id
|
||||||
|
)
|
||||||
|
|
||||||
|
listevents_update = ListEventUpdate(status=EventStatus.DELETED.value)
|
||||||
|
|
||||||
|
update_values = update_listevents_data_changes(listevents_update, listevents_validation)
|
||||||
|
|
||||||
|
if update_values is None:
|
||||||
|
return listevents_validation
|
||||||
|
|
||||||
|
await update_listevents_by_id(connection, update_values, listevents_validation)
|
||||||
|
|
||||||
|
listevents = await get_listevents_by_id(connection, listevents_id)
|
||||||
|
|
||||||
|
return listevents
|
@ -8,7 +8,6 @@ from api.schemas.base import Base
|
|||||||
|
|
||||||
|
|
||||||
class UserUpdate(Base):
|
class UserUpdate(Base):
|
||||||
id: Optional[int] = None
|
|
||||||
name: Optional[str] = Field(None, max_length=100)
|
name: Optional[str] = Field(None, max_length=100)
|
||||||
login: Optional[str] = Field(None, max_length=100)
|
login: Optional[str] = Field(None, max_length=100)
|
||||||
email: Optional[EmailStr] = None
|
email: Optional[EmailStr] = None
|
||||||
@ -16,8 +15,6 @@ class UserUpdate(Base):
|
|||||||
bind_tenant_id: Optional[str] = Field(None, max_length=40)
|
bind_tenant_id: Optional[str] = Field(None, max_length=40)
|
||||||
role: Optional[AccountRole] = None
|
role: Optional[AccountRole] = None
|
||||||
meta: Optional[dict] = None
|
meta: Optional[dict] = None
|
||||||
creator_id: Optional[int] = None
|
|
||||||
created_at: Optional[datetime] = None
|
|
||||||
status: Optional[AccountStatus] = None
|
status: Optional[AccountStatus] = None
|
||||||
|
|
||||||
|
|
||||||
|
@ -10,8 +10,5 @@ from api.schemas.base import Base
|
|||||||
class AccountKeyringUpdate(Base):
|
class AccountKeyringUpdate(Base):
|
||||||
owner_id: Optional[int] = None
|
owner_id: Optional[int] = None
|
||||||
key_type: Optional[KeyType] = None
|
key_type: Optional[KeyType] = None
|
||||||
key_id: Optional[str] = Field(None, max_length=40)
|
|
||||||
key_value: Optional[str] = Field(None, max_length=255)
|
key_value: Optional[str] = Field(None, max_length=255)
|
||||||
created_at: Optional[datetime] = None
|
|
||||||
expiry: Optional[datetime] = None
|
|
||||||
status: Optional[KeyStatus] = None
|
status: Optional[KeyStatus] = None
|
||||||
|
37
api/api/schemas/endpoints/list_events.py
Normal file
37
api/api/schemas/endpoints/list_events.py
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
from pydantic import Field, TypeAdapter
|
||||||
|
from typing import Optional, Dict, Any, List
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
|
||||||
|
from api.schemas.base import Base
|
||||||
|
from api.db.tables.events import EventState, EventStatus
|
||||||
|
|
||||||
|
|
||||||
|
class ListEventUpdate(Base):
|
||||||
|
name: Optional[str] = Field(None, max_length=40)
|
||||||
|
title: Optional[str] = Field(None, max_length=64)
|
||||||
|
schema_: Optional[Dict[str, Any]] = Field(None, alias="schema")
|
||||||
|
state: Optional[EventState] = None
|
||||||
|
status: Optional[EventStatus] = None
|
||||||
|
|
||||||
|
|
||||||
|
class AllListEvent(Base):
|
||||||
|
id: int
|
||||||
|
name: str
|
||||||
|
title: str
|
||||||
|
creator_id: int
|
||||||
|
created_at: datetime
|
||||||
|
schema_: Dict[str, Any] = Field(default={}, alias="schema")
|
||||||
|
state: EventState
|
||||||
|
status: EventStatus
|
||||||
|
|
||||||
|
|
||||||
|
class AllListEventResponse(Base):
|
||||||
|
list_event: List[AllListEvent]
|
||||||
|
amount_count: int
|
||||||
|
amount_pages: int
|
||||||
|
current_page: int
|
||||||
|
limit: int
|
||||||
|
|
||||||
|
|
||||||
|
all_list_event_adapter = TypeAdapter(List[AllListEvent])
|
@ -1,20 +1,9 @@
|
|||||||
from pydantic import Field
|
from pydantic import Field
|
||||||
from typing import Dict, Any
|
from typing import Dict, Any
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from enum import Enum
|
|
||||||
|
|
||||||
from api.schemas.base import Base
|
from api.schemas.base import Base
|
||||||
|
from api.db.tables.events import EventState, EventStatus
|
||||||
|
|
||||||
class State(Enum):
|
|
||||||
AUTO = "Auto"
|
|
||||||
DESCRIPTED = "Descripted"
|
|
||||||
|
|
||||||
|
|
||||||
class Status(Enum):
|
|
||||||
ACTIVE = "Active"
|
|
||||||
DISABLED = "Disabled"
|
|
||||||
DELETED = "Deleted"
|
|
||||||
|
|
||||||
|
|
||||||
class ListEvent(Base):
|
class ListEvent(Base):
|
||||||
@ -23,6 +12,6 @@ class ListEvent(Base):
|
|||||||
title: str = Field(..., max_length=64)
|
title: str = Field(..., max_length=64)
|
||||||
creator_id: int
|
creator_id: int
|
||||||
created_at: datetime
|
created_at: datetime
|
||||||
schema: Dict[str, Any]
|
schema_: Dict[str, Any] = Field(..., alias="schema")
|
||||||
state: State
|
state: EventState
|
||||||
status: Status
|
status: EventStatus
|
||||||
|
@ -4,6 +4,8 @@ from api.schemas.endpoints.account import UserUpdate
|
|||||||
from api.db.tables.account import KeyType, KeyStatus
|
from api.db.tables.account import KeyType, KeyStatus
|
||||||
from api.schemas.endpoints.account_keyring import AccountKeyringUpdate
|
from api.schemas.endpoints.account_keyring import AccountKeyringUpdate
|
||||||
from api.db.tables.account import AccountRole, AccountStatus
|
from api.db.tables.account import AccountRole, AccountStatus
|
||||||
|
from api.schemas.endpoints.list_events import ListEventUpdate
|
||||||
|
from api.db.tables.events import EventState, EventStatus
|
||||||
|
|
||||||
|
|
||||||
def update_user_data_changes(update_data: UserUpdate, user) -> Optional[dict]:
|
def update_user_data_changes(update_data: UserUpdate, user) -> Optional[dict]:
|
||||||
@ -72,3 +74,37 @@ def update_key_data_changes(update_data: AccountKeyringUpdate, key) -> Optional[
|
|||||||
changes[field] = new_value
|
changes[field] = new_value
|
||||||
|
|
||||||
return changes if changes else None
|
return changes if changes else None
|
||||||
|
|
||||||
|
|
||||||
|
def update_listevents_data_changes(update_data: ListEventUpdate, listevents) -> Optional[dict]:
|
||||||
|
"""
|
||||||
|
Сравнивает данные для обновления с текущими значениями listevents.
|
||||||
|
Возвращает:
|
||||||
|
- None, если нет изменений
|
||||||
|
- Словарь {поле: новое_значение} для измененных полей
|
||||||
|
"""
|
||||||
|
update_values = {}
|
||||||
|
changes = {}
|
||||||
|
|
||||||
|
for field, value in update_data.model_dump(exclude_unset=True).items():
|
||||||
|
if value is None:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if isinstance(value, (EventState, EventStatus)):
|
||||||
|
update_values[field] = value.value
|
||||||
|
else:
|
||||||
|
update_values[field] = value
|
||||||
|
|
||||||
|
for field, new_value in update_values.items():
|
||||||
|
if not hasattr(listevents, field):
|
||||||
|
continue
|
||||||
|
|
||||||
|
current_value = getattr(listevents, field)
|
||||||
|
|
||||||
|
if isinstance(current_value, Enum):
|
||||||
|
current_value = current_value.value
|
||||||
|
|
||||||
|
if current_value != new_value:
|
||||||
|
changes[field] = new_value
|
||||||
|
|
||||||
|
return changes if changes else None
|
||||||
|
@ -11,3 +11,21 @@ async def db_user_role_validation(connection, current_user):
|
|||||||
if authorize_user.role not in {AccountRole.OWNER, AccountRole.ADMIN}:
|
if authorize_user.role not in {AccountRole.OWNER, AccountRole.ADMIN}:
|
||||||
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="You do not have enough permissions")
|
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="You do not have enough permissions")
|
||||||
return authorize_user
|
return authorize_user
|
||||||
|
|
||||||
|
|
||||||
|
async def db_user_role_validation_for_listevents_by_listevent_id(
|
||||||
|
connection, current_user, current_listevents_creator_id
|
||||||
|
):
|
||||||
|
authorize_user = await get_user_by_login(connection, current_user)
|
||||||
|
if authorize_user.role not in {AccountRole.OWNER, AccountRole.ADMIN}:
|
||||||
|
if authorize_user.id != current_listevents_creator_id:
|
||||||
|
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="You do not have enough permissions")
|
||||||
|
return authorize_user
|
||||||
|
|
||||||
|
|
||||||
|
async def db_user_role_validation_for_listevents(connection, current_user):
|
||||||
|
authorize_user = await get_user_by_login(connection, current_user)
|
||||||
|
if authorize_user.role not in {AccountRole.OWNER, AccountRole.ADMIN}:
|
||||||
|
return authorize_user, False
|
||||||
|
else:
|
||||||
|
return authorize_user, True
|
||||||
|
234
client/package-lock.json
generated
234
client/package-lock.json
generated
@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "client",
|
"name": "client",
|
||||||
"version": "0.0.5",
|
"version": "0.0.3",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "client",
|
"name": "client",
|
||||||
"version": "0.0.5",
|
"version": "0.0.3",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ant-design/icons": "^5.6.1",
|
"@ant-design/icons": "^5.6.1",
|
||||||
"@testing-library/dom": "^10.4.0",
|
"@testing-library/dom": "^10.4.0",
|
||||||
@ -16,7 +16,6 @@
|
|||||||
"@types/jest": "^27.5.2",
|
"@types/jest": "^27.5.2",
|
||||||
"@types/react": "^19.0.11",
|
"@types/react": "^19.0.11",
|
||||||
"@types/react-dom": "^19.0.4",
|
"@types/react-dom": "^19.0.4",
|
||||||
"@xyflow/react": "^12.8.1",
|
|
||||||
"antd": "^5.24.7",
|
"antd": "^5.24.7",
|
||||||
"axios": "^1.9.0",
|
"axios": "^1.9.0",
|
||||||
"axios-retry": "^4.5.0",
|
"axios-retry": "^4.5.0",
|
||||||
@ -1568,55 +1567,6 @@
|
|||||||
"@babel/types": "^7.20.7"
|
"@babel/types": "^7.20.7"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@types/d3-color": {
|
|
||||||
"version": "3.1.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-3.1.3.tgz",
|
|
||||||
"integrity": "sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==",
|
|
||||||
"license": "MIT"
|
|
||||||
},
|
|
||||||
"node_modules/@types/d3-drag": {
|
|
||||||
"version": "3.0.7",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/d3-drag/-/d3-drag-3.0.7.tgz",
|
|
||||||
"integrity": "sha512-HE3jVKlzU9AaMazNufooRJ5ZpWmLIoc90A37WU2JMmeq28w1FQqCZswHZ3xR+SuxYftzHq6WU6KJHvqxKzTxxQ==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"@types/d3-selection": "*"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@types/d3-interpolate": {
|
|
||||||
"version": "3.0.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz",
|
|
||||||
"integrity": "sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"@types/d3-color": "*"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@types/d3-selection": {
|
|
||||||
"version": "3.0.11",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/d3-selection/-/d3-selection-3.0.11.tgz",
|
|
||||||
"integrity": "sha512-bhAXu23DJWsrI45xafYpkQ4NtcKMwWnAC/vKrd2l+nxMFuvOT3XMYTIj2opv8vq8AO5Yh7Qac/nSeP/3zjTK0w==",
|
|
||||||
"license": "MIT"
|
|
||||||
},
|
|
||||||
"node_modules/@types/d3-transition": {
|
|
||||||
"version": "3.0.9",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/d3-transition/-/d3-transition-3.0.9.tgz",
|
|
||||||
"integrity": "sha512-uZS5shfxzO3rGlu0cC3bjmMFKsXv+SmZZcgp0KD22ts4uGXp5EVYGzu/0YdwZeKmddhcAccYtREJKkPfXkZuCg==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"@types/d3-selection": "*"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@types/d3-zoom": {
|
|
||||||
"version": "3.0.8",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/d3-zoom/-/d3-zoom-3.0.8.tgz",
|
|
||||||
"integrity": "sha512-iqMC4/YlFCSlO8+2Ii1GGGliCAY4XdeG748w5vQUbevlbDu0zSjH/+jojorQVBK/se0j6DUFNPBGSqD3YWYnDw==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"@types/d3-interpolate": "*",
|
|
||||||
"@types/d3-selection": "*"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@types/estree": {
|
"node_modules/@types/estree": {
|
||||||
"version": "1.0.8",
|
"version": "1.0.8",
|
||||||
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
|
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
|
||||||
@ -1683,66 +1633,6 @@
|
|||||||
"vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0-beta.0"
|
"vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0-beta.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@xyflow/react": {
|
|
||||||
"version": "12.8.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/@xyflow/react/-/react-12.8.1.tgz",
|
|
||||||
"integrity": "sha512-t5Rame4Gc/540VcOZd28yFe9Xd8lyjKUX+VTiyb1x4ykNXZH5zyDmsu+lj9je2O/jGBVb0pj1Vjcxrxyn+Xk2g==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"@xyflow/system": "0.0.65",
|
|
||||||
"classcat": "^5.0.3",
|
|
||||||
"zustand": "^4.4.0"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"react": ">=17",
|
|
||||||
"react-dom": ">=17"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@xyflow/react/node_modules/zustand": {
|
|
||||||
"version": "4.5.7",
|
|
||||||
"resolved": "https://registry.npmjs.org/zustand/-/zustand-4.5.7.tgz",
|
|
||||||
"integrity": "sha512-CHOUy7mu3lbD6o6LJLfllpjkzhHXSBlX8B9+qPddUsIfeF5S/UZ5q0kmCsnRqT1UHFQZchNFDDzMbQsuesHWlw==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"use-sync-external-store": "^1.2.2"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=12.7.0"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"@types/react": ">=16.8",
|
|
||||||
"immer": ">=9.0.6",
|
|
||||||
"react": ">=16.8"
|
|
||||||
},
|
|
||||||
"peerDependenciesMeta": {
|
|
||||||
"@types/react": {
|
|
||||||
"optional": true
|
|
||||||
},
|
|
||||||
"immer": {
|
|
||||||
"optional": true
|
|
||||||
},
|
|
||||||
"react": {
|
|
||||||
"optional": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@xyflow/system": {
|
|
||||||
"version": "0.0.65",
|
|
||||||
"resolved": "https://registry.npmjs.org/@xyflow/system/-/system-0.0.65.tgz",
|
|
||||||
"integrity": "sha512-AliQPQeurQMoNlOdySnRoDQl9yDSA/1Lqi47Eo0m98lHcfrTdD9jK75H0tiGj+0qRC10SKNUXyMkT0KL0opg4g==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"@types/d3-drag": "^3.0.7",
|
|
||||||
"@types/d3-interpolate": "^3.0.4",
|
|
||||||
"@types/d3-selection": "^3.0.10",
|
|
||||||
"@types/d3-transition": "^3.0.8",
|
|
||||||
"@types/d3-zoom": "^3.0.8",
|
|
||||||
"d3-drag": "^3.0.0",
|
|
||||||
"d3-interpolate": "^3.0.1",
|
|
||||||
"d3-selection": "^3.0.0",
|
|
||||||
"d3-zoom": "^3.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/ansi-regex": {
|
"node_modules/ansi-regex": {
|
||||||
"version": "5.0.1",
|
"version": "5.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
|
||||||
@ -2270,12 +2160,6 @@
|
|||||||
"node": ">= 0.10"
|
"node": ">= 0.10"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/classcat": {
|
|
||||||
"version": "5.0.5",
|
|
||||||
"resolved": "https://registry.npmjs.org/classcat/-/classcat-5.0.5.tgz",
|
|
||||||
"integrity": "sha512-JhZUT7JFcQy/EzW605k/ktHtncoo9vnyW/2GspNYwFlN1C/WmjuV/xtS04e9SOkL2sTdw0VAZ2UGCcQ9lR6p6w==",
|
|
||||||
"license": "MIT"
|
|
||||||
},
|
|
||||||
"node_modules/classnames": {
|
"node_modules/classnames": {
|
||||||
"version": "2.5.1",
|
"version": "2.5.1",
|
||||||
"resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz",
|
"resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz",
|
||||||
@ -2456,111 +2340,6 @@
|
|||||||
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
|
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/d3-color": {
|
|
||||||
"version": "3.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz",
|
|
||||||
"integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==",
|
|
||||||
"license": "ISC",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=12"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/d3-dispatch": {
|
|
||||||
"version": "3.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz",
|
|
||||||
"integrity": "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==",
|
|
||||||
"license": "ISC",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=12"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/d3-drag": {
|
|
||||||
"version": "3.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-3.0.0.tgz",
|
|
||||||
"integrity": "sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==",
|
|
||||||
"license": "ISC",
|
|
||||||
"dependencies": {
|
|
||||||
"d3-dispatch": "1 - 3",
|
|
||||||
"d3-selection": "3"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=12"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/d3-ease": {
|
|
||||||
"version": "3.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz",
|
|
||||||
"integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==",
|
|
||||||
"license": "BSD-3-Clause",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=12"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/d3-interpolate": {
|
|
||||||
"version": "3.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz",
|
|
||||||
"integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==",
|
|
||||||
"license": "ISC",
|
|
||||||
"dependencies": {
|
|
||||||
"d3-color": "1 - 3"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=12"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/d3-selection": {
|
|
||||||
"version": "3.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz",
|
|
||||||
"integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==",
|
|
||||||
"license": "ISC",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=12"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/d3-timer": {
|
|
||||||
"version": "3.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz",
|
|
||||||
"integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==",
|
|
||||||
"license": "ISC",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=12"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/d3-transition": {
|
|
||||||
"version": "3.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-3.0.1.tgz",
|
|
||||||
"integrity": "sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==",
|
|
||||||
"license": "ISC",
|
|
||||||
"dependencies": {
|
|
||||||
"d3-color": "1 - 3",
|
|
||||||
"d3-dispatch": "1 - 3",
|
|
||||||
"d3-ease": "1 - 3",
|
|
||||||
"d3-interpolate": "1 - 3",
|
|
||||||
"d3-timer": "1 - 3"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=12"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"d3-selection": "2 - 3"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/d3-zoom": {
|
|
||||||
"version": "3.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-3.0.0.tgz",
|
|
||||||
"integrity": "sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==",
|
|
||||||
"license": "ISC",
|
|
||||||
"dependencies": {
|
|
||||||
"d3-dispatch": "1 - 3",
|
|
||||||
"d3-drag": "2 - 3",
|
|
||||||
"d3-interpolate": "1 - 3",
|
|
||||||
"d3-selection": "2 - 3",
|
|
||||||
"d3-transition": "2 - 3"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=12"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/dayjs": {
|
"node_modules/dayjs": {
|
||||||
"version": "1.11.13",
|
"version": "1.11.13",
|
||||||
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.13.tgz",
|
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.13.tgz",
|
||||||
@ -5328,15 +5107,6 @@
|
|||||||
"node": ">= 0.4"
|
"node": ">= 0.4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/use-sync-external-store": {
|
|
||||||
"version": "1.5.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.5.0.tgz",
|
|
||||||
"integrity": "sha512-Rb46I4cGGVBmjamjphe8L/UnvJD+uPPtTkNvX5mZgqdbavhI4EbgIWJiIHXJ8bc/i9EQGPRh4DwEURJ552Do0A==",
|
|
||||||
"license": "MIT",
|
|
||||||
"peerDependencies": {
|
|
||||||
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/util": {
|
"node_modules/util": {
|
||||||
"version": "0.12.5",
|
"version": "0.12.5",
|
||||||
"resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz",
|
"resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz",
|
||||||
|
@ -11,7 +11,6 @@
|
|||||||
"@types/jest": "^27.5.2",
|
"@types/jest": "^27.5.2",
|
||||||
"@types/react": "^19.0.11",
|
"@types/react": "^19.0.11",
|
||||||
"@types/react-dom": "^19.0.4",
|
"@types/react-dom": "^19.0.4",
|
||||||
"@xyflow/react": "^12.8.1",
|
|
||||||
"antd": "^5.24.7",
|
"antd": "^5.24.7",
|
||||||
"axios": "^1.9.0",
|
"axios": "^1.9.0",
|
||||||
"axios-retry": "^4.5.0",
|
"axios-retry": "^4.5.0",
|
||||||
|
@ -1,8 +0,0 @@
|
|||||||
<svg width="28" height="31" viewBox="0 0 28 31" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
||||||
<path d="M0 28.6L1.4 30L3 28.425L4.575 30L6 28.6L4.4 27L6 25.425L4.575 24L3 25.6L1.4 24L0 25.425L1.575 27L0 28.6Z" fill="#606060"/>
|
|
||||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M13 0C14.1 0 15.0419 0.391472 15.8252 1.1748C16.6085 1.95814 17 2.9 17 4C17 5.1 16.6085 6.04186 15.8252 6.8252C15.0419 7.60853 14.1 8 13 8C11.9 8 10.9581 7.60853 10.1748 6.8252C9.39147 6.04186 9 5.1 9 4C9 2.9 9.39147 1.95814 10.1748 1.1748C10.9581 0.391471 11.9 0 13 0ZM13 2C12.45 2 11.9796 2.19622 11.5879 2.58789C11.1962 2.97956 11 3.45 11 4C11 4.53333 11.1962 5.00039 11.5879 5.40039C11.9795 5.80013 12.4502 6 13 6C13.5498 6 14.0205 5.80013 14.4121 5.40039C14.8038 5.00039 15 4.53333 15 4C15 3.45 14.8038 2.97956 14.4121 2.58789C14.0204 2.19622 13.55 2 13 2Z" fill="#606060"/>
|
|
||||||
<path d="M11.8 9H13.8V14H11.8V9Z" fill="#606060"/>
|
|
||||||
<path d="M20 27.55L22.825 30.375L27.775 25.425L26.35 24L22.825 27.55L21.4 26.125L20 27.55Z" fill="#606060"/>
|
|
||||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M19.167 18.417L12.75 24.834L7.25005 19.334H4.00005L4 23H2L2.00005 17.5H7.25005L12.75 12L19.167 18.417ZM8.9229 18.417L12.75 22.2441L16.5772 18.417L12.75 14.5898L8.9229 18.417Z" fill="#606060"/>
|
|
||||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M17.5 19.334L22 19.334V23H24V17.5L17.5 17.5V19.334Z" fill="#606060"/>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 1.4 KiB |
@ -1,87 +0,0 @@
|
|||||||
import { Handle, NodeProps, Position, Node } from "@xyflow/react";
|
|
||||||
|
|
||||||
type IfElseNodeData = {
|
|
||||||
condition?: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default function IfElseNode({ data }: NodeProps<Node & IfElseNodeData>) {
|
|
||||||
return (
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
border: "0px solid",
|
|
||||||
borderRadius: 8,
|
|
||||||
backgroundColor: "white",
|
|
||||||
width: "248px",
|
|
||||||
height: "144px",
|
|
||||||
fontFamily: "sans-serif",
|
|
||||||
position: "relative",
|
|
||||||
overflow: "hidden",
|
|
||||||
}}
|
|
||||||
onClick={(e) => {
|
|
||||||
e.stopPropagation();
|
|
||||||
console.log("data", data);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
display: "flex",
|
|
||||||
alignItems: "center",
|
|
||||||
padding: "8px 12px",
|
|
||||||
borderBottom: "1px solid #E2E2E2",
|
|
||||||
backgroundColor: "#fff",
|
|
||||||
height: "48px",
|
|
||||||
fontWeight: 600,
|
|
||||||
fontSize: 16,
|
|
||||||
gap: 8,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<img src="./icons/node/ifElse.svg" /> ЕСЛИ - ТО
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
display: "flex",
|
|
||||||
alignItems: "center",
|
|
||||||
paddingLeft: "12px",
|
|
||||||
borderBottom: "1px solid #E2E2E2",
|
|
||||||
fontSize: 14,
|
|
||||||
height: "48px",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Если {data.condition as string}, то
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
display: "flex",
|
|
||||||
alignItems: "center",
|
|
||||||
paddingLeft: "12px",
|
|
||||||
fontSize: 14,
|
|
||||||
height: "48px",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
Иначе
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<Handle
|
|
||||||
type="target"
|
|
||||||
position={Position.Top}
|
|
||||||
style={{ background: "#555" }}
|
|
||||||
id="input"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<Handle
|
|
||||||
type="source"
|
|
||||||
position={Position.Right}
|
|
||||||
style={{ background: "#555" }}
|
|
||||||
id="true"
|
|
||||||
/>
|
|
||||||
<Handle
|
|
||||||
type="source"
|
|
||||||
position={Position.Bottom}
|
|
||||||
style={{ background: "#555" }}
|
|
||||||
id="false"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
@ -1,12 +1,11 @@
|
|||||||
import React from "react";
|
import React from 'react';
|
||||||
import ReactDOM from "react-dom/client";
|
import ReactDOM from 'react-dom/client';
|
||||||
import "@/index.css";
|
import '@/index.css';
|
||||||
import App from "@/App";
|
import App from '@/App';
|
||||||
import AppWrapper from "@/config/AppWrapper";
|
import AppWrapper from '@/config/AppWrapper';
|
||||||
import "@xyflow/react/dist/style.css";
|
|
||||||
|
|
||||||
const root = ReactDOM.createRoot(
|
const root = ReactDOM.createRoot(
|
||||||
document.getElementById("root") as HTMLElement
|
document.getElementById('root') as HTMLElement
|
||||||
);
|
);
|
||||||
|
|
||||||
root.render(
|
root.render(
|
||||||
|
Loading…
Reference in New Issue
Block a user