mirror of
https://github.com/open-webui/open-webui.git
synced 2026-08-28 00:14:53 -06:00
refac
This commit is contained in:
@@ -24,7 +24,7 @@ def upgrade() -> None:
|
||||
sa.Column('user_id', sa.Text(), nullable=False),
|
||||
sa.Column('name', sa.Text(), nullable=False),
|
||||
sa.Column('color', sa.Text(), nullable=True),
|
||||
sa.Column('is_system', sa.Boolean(), nullable=False),
|
||||
sa.Column('is_default', sa.Boolean(), nullable=False),
|
||||
sa.Column('data', sa.JSON(), nullable=True),
|
||||
sa.Column('meta', sa.JSON(), nullable=True),
|
||||
sa.Column('created_at', sa.BigInteger(), nullable=False),
|
||||
|
||||
@@ -17,6 +17,7 @@ from sqlalchemy import (
|
||||
exists,
|
||||
func,
|
||||
delete,
|
||||
update,
|
||||
)
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
|
||||
@@ -40,7 +41,7 @@ class Calendar(Base):
|
||||
user_id = Column(Text, nullable=False)
|
||||
name = Column(Text, nullable=False)
|
||||
color = Column(Text, nullable=True)
|
||||
is_system = Column(Boolean, nullable=False, default=False)
|
||||
is_default = Column(Boolean, nullable=False, default=False)
|
||||
data = Column(JSON, nullable=True)
|
||||
meta = Column(JSON, nullable=True)
|
||||
|
||||
@@ -107,7 +108,8 @@ class CalendarModel(BaseModel):
|
||||
user_id: str
|
||||
name: str
|
||||
color: Optional[str] = None
|
||||
is_system: bool = False
|
||||
is_default: bool = False
|
||||
|
||||
data: Optional[dict] = None
|
||||
meta: Optional[dict] = None
|
||||
|
||||
@@ -269,7 +271,7 @@ class CalendarTable:
|
||||
user_id=user_id,
|
||||
name='Personal',
|
||||
color='#3b82f6',
|
||||
is_system=True,
|
||||
is_default=True,
|
||||
created_at=now,
|
||||
updated_at=now,
|
||||
),
|
||||
@@ -278,7 +280,6 @@ class CalendarTable:
|
||||
user_id=user_id,
|
||||
name='Scheduled Tasks',
|
||||
color='#8b5cf6',
|
||||
is_system=True,
|
||||
created_at=now + 1,
|
||||
updated_at=now + 1,
|
||||
),
|
||||
@@ -338,7 +339,6 @@ class CalendarTable:
|
||||
select(Calendar).filter(
|
||||
Calendar.user_id == user_id,
|
||||
Calendar.name == 'Scheduled Tasks',
|
||||
Calendar.is_system == True,
|
||||
)
|
||||
)
|
||||
cal = result.scalars().first()
|
||||
@@ -349,7 +349,6 @@ class CalendarTable:
|
||||
select(Calendar).filter(
|
||||
Calendar.user_id == user_id,
|
||||
Calendar.name == 'Scheduled Tasks',
|
||||
Calendar.is_system == True,
|
||||
)
|
||||
)
|
||||
cal = result.scalars().first()
|
||||
@@ -366,7 +365,7 @@ class CalendarTable:
|
||||
user_id=user_id,
|
||||
name=form_data.name,
|
||||
color=form_data.color,
|
||||
is_system=False,
|
||||
is_default=False,
|
||||
data=form_data.data,
|
||||
meta=form_data.meta,
|
||||
created_at=now,
|
||||
@@ -403,13 +402,36 @@ class CalendarTable:
|
||||
await db.commit()
|
||||
return await self._to_calendar_model(cal, db=db)
|
||||
|
||||
async def set_default_calendar(
|
||||
self, user_id: str, calendar_id: str, db: Optional[AsyncSession] = None
|
||||
) -> Optional[CalendarModel]:
|
||||
"""Set a calendar as the user's default, clearing all others."""
|
||||
async with get_async_db_context(db) as db:
|
||||
# Clear all defaults for this user
|
||||
await db.execute(
|
||||
update(Calendar)
|
||||
.where(Calendar.user_id == user_id, Calendar.is_default == True)
|
||||
.values(is_default=False)
|
||||
)
|
||||
# Set the new default
|
||||
result = await db.execute(
|
||||
select(Calendar).filter(Calendar.id == calendar_id, Calendar.user_id == user_id)
|
||||
)
|
||||
cal = result.scalars().first()
|
||||
if not cal:
|
||||
return None
|
||||
cal.is_default = True
|
||||
cal.updated_at = int(time.time_ns())
|
||||
await db.commit()
|
||||
return await self._to_calendar_model(cal, db=db)
|
||||
|
||||
async def delete_calendar_by_id(self, id: str, db: Optional[AsyncSession] = None) -> bool:
|
||||
"""Delete a non-system calendar. Cascades to events, attendees, and grants."""
|
||||
"""Delete a non-default calendar. Cascades to events, attendees, and grants."""
|
||||
try:
|
||||
async with get_async_db_context(db) as db:
|
||||
result = await db.execute(select(Calendar).filter(Calendar.id == id))
|
||||
cal = result.scalars().first()
|
||||
if not cal or cal.is_system:
|
||||
if not cal or cal.is_default:
|
||||
return False
|
||||
|
||||
# Delete attendees for all events in this calendar
|
||||
|
||||
@@ -310,10 +310,16 @@ async def delete_calendar(calendar_id: str, user: UserModel = Depends(get_verifi
|
||||
if cal.user_id != user.id and user.role != 'admin':
|
||||
raise HTTPException(status_code=403, detail='Only owner can delete calendar')
|
||||
|
||||
if cal.is_system:
|
||||
raise HTTPException(status_code=400, detail='Cannot delete system calendar')
|
||||
|
||||
result = await Calendars.delete_calendar_by_id(calendar_id)
|
||||
if not result:
|
||||
raise HTTPException(status_code=500, detail='Failed to delete')
|
||||
return {'status': True}
|
||||
|
||||
|
||||
@router.post('/{calendar_id}/default')
|
||||
async def set_default_calendar(calendar_id: str, user: UserModel = Depends(get_verified_user)):
|
||||
cal = await Calendars.set_default_calendar(user.id, calendar_id)
|
||||
if not cal:
|
||||
raise HTTPException(status_code=404, detail='Calendar not found')
|
||||
return cal
|
||||
|
||||
@@ -5,7 +5,7 @@ export type CalendarModel = {
|
||||
user_id: string;
|
||||
name: string;
|
||||
color: string | null;
|
||||
is_system: boolean;
|
||||
is_default: boolean;
|
||||
data: Record<string, any> | null;
|
||||
meta: Record<string, any> | null;
|
||||
access_grants: any[];
|
||||
@@ -188,6 +188,37 @@ export const deleteCalendar = async (token: string, calendarId: string): Promise
|
||||
return res?.status ?? false;
|
||||
};
|
||||
|
||||
export const setDefaultCalendar = async (
|
||||
token: string,
|
||||
calendarId: string
|
||||
): Promise<CalendarModel> => {
|
||||
let error = null;
|
||||
|
||||
const res = await fetch(`${WEBUI_API_BASE_URL}/calendars/${calendarId}/default`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
Accept: 'application/json',
|
||||
'Content-Type': 'application/json',
|
||||
authorization: `Bearer ${token}`
|
||||
}
|
||||
})
|
||||
.then(async (res) => {
|
||||
if (!res.ok) throw await res.json();
|
||||
return res.json();
|
||||
})
|
||||
.catch((err) => {
|
||||
error = err.detail;
|
||||
console.error(err);
|
||||
return null;
|
||||
});
|
||||
|
||||
if (error) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
return res;
|
||||
};
|
||||
|
||||
// ── Events ─────────────────────────────────
|
||||
|
||||
export const getCalendarEvents = async (
|
||||
|
||||
@@ -128,7 +128,7 @@
|
||||
showEventModal = true;
|
||||
}
|
||||
|
||||
$: defaultCalendarId = calendars.find((c) => !c.is_system || c.name === 'Personal')?.id || calendars[0]?.id || '';
|
||||
$: defaultCalendarId = calendars.find((c) => c.is_default)?.id || calendars[0]?.id || '';
|
||||
|
||||
onMount(async () => {
|
||||
await loadCalendars();
|
||||
|
||||
Reference in New Issue
Block a user