Skip to content

Commit

Permalink
Merge pull request #26 from PhoenixNazarov/dev-notifications
Browse files Browse the repository at this point in the history
Display notifications
  • Loading branch information
PhoenixNazarov authored Oct 21, 2024
2 parents 8e96b9d + 0572b51 commit 3b40db5
Show file tree
Hide file tree
Showing 17 changed files with 164 additions and 98 deletions.
29 changes: 29 additions & 0 deletions .github/workflows/ci-dev.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
name: ci

on:
push:
branches:
- 'dev'

jobs:
docker:
runs-on: ubuntu-latest
steps:
-
name: Set up QEMU
uses: docker/setup-qemu-action@v3
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
-
name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
-
name: Build and push
uses: docker/build-push-action@v5
with:
push: true
tags: phoenixnazarov/prompt-admin:dev
File renamed without changes.
19 changes: 10 additions & 9 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,31 +16,32 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Add fetch columns, upgrade filters, and select columns in a list component
- Add joins for tables in a list component
- Add save and update images in an item component
- Add information notifications
- Add widget for view self-permissions
- Add widget for moderate users permissions
- [Add information notifications](https://github.com/PhoenixNazarov/prompt-admin/compare/dev...dev-notifications)
- [Add widget for view self-permissions](https://github.com/PhoenixNazarov/prompt-admin/pull/25)
- [Add widget for moderate users permissions](https://github.com/PhoenixNazarov/prompt-admin/pull/25)

### Changed

- Change update parameters watcher for a list table component
- Union requests dto in base dto request with project field
- Change Vars, Prompts, Projects, Config endpoints with permissions
- [Change Vars, Prompts, Projects, Config endpoints with permissions](https://github.com/PhoenixNazarov/prompt-admin/pull/25)
- Unit test no need test complete unit tests
- Update filtered menu prompts with search
- Move business logic from tables endpoints to tables services
- Move all get connections to ConnectionMixin
- [Move business logic from tables endpoints to tables services](https://github.com/PhoenixNazarov/prompt-admin/pull/25)
- [Move all get connections to ConnectionMixin](https://github.com/PhoenixNazarov/prompt-admin/pull/25)
- [Change Github actions for development and production](https://github.com/PhoenixNazarov/prompt-admin/compare/dev...dev-notifications)

### Deprecated

- Format module

### Removed

- Remove entity_data from abstract def bind_view
- Remove bind_view and create BaseConfigService
- [Remove entity_data from abstract def bind_view](https://github.com/PhoenixNazarov/prompt-admin/pull/25)
- [Remove bind_view and create BaseConfigService](https://github.com/PhoenixNazarov/prompt-admin/pull/25)

### Fixed

- Fix start loading a list table component without a filter
- Bugfix load popup tables, back home, ident for test_case
- Fix /auth/me return user password, now return password: null
- [Fix /auth/me return user password, now return password: null](https://github.com/PhoenixNazarov/prompt-admin/pull/25)
3 changes: 1 addition & 2 deletions client/src/App.vue
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
<script lang="ts">
import {defineComponent} from 'vue'
import {RouterView} from 'vue-router'
import SchemaJsonView from "./views/SchemaJsonView.vue";
import NotificationView from "./views/Notifications/NotificationView.vue";
export default defineComponent({
name: "App",
components: {NotificationView, SchemaJsonView, RouterView}
components: {NotificationView, RouterView}
})
</script>

Expand Down
22 changes: 18 additions & 4 deletions client/src/api/ApiService.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,22 @@
import axios, {AxiosRequestConfig} from "axios";
import NotificationService from "../views/Notifications/NotificationService.ts";

function onError(error: any, method: 'get' | 'post', url: string) {
let status: number | undefined = error.response?.status
let code: string | undefined = error.code
let detail: string | undefined = error.response?.data?.detail
let message: string | undefined = error.message
let errorMessage: string | undefined = error.response?.headers?.['error-message']

if (!status) status = -1
if (!code) code = 'UNDEFINED'
if (!detail) detail = ''
if (!message) message = 'Undefined error'
if (!errorMessage) errorMessage = ''
NotificationService.onError(`[API] ${method} ${url} - ${status} [${errorMessage}] ${detail}: ${message} (${code})`)
throw error
}

export class ApiService {
private static AXIOS_CONFIG: AxiosRequestConfig = {
withCredentials: true,
Expand All @@ -10,8 +26,7 @@ export class ApiService {
try {
return (await axios.get<R>(url, this.AXIOS_CONFIG)).data
} catch (e) {
NotificationService.onError(`[API] get ${url}: Undefined error`)
throw e
onError(e, 'get', url);
}
}

Expand All @@ -20,8 +35,7 @@ export class ApiService {
try {
return (await axios.post<R>(url, data, this.AXIOS_CONFIG)).data
} catch (e) {
NotificationService.onError(`[API] post ${url}: Undefined error`)
throw e
onError(e, 'post', url);
}
}
}
4 changes: 3 additions & 1 deletion client/src/views/Notifications/NotificationService.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import {reactive} from "vue";

type NotificationLevel = 'info' | 'debug' | 'error' | 'warning'

const DEFAULT_TIMEOUT = 10000
Expand All @@ -10,7 +12,7 @@ interface Notification {
}


export const notifications = [] as Notification[]
export const notifications = reactive([] as Notification[])


class NotificationService {
Expand Down
10 changes: 6 additions & 4 deletions client/src/views/Notifications/NotificationView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ export default defineComponent({
return {
queue: notifications,
snackbar: true,
text: 'test',
timeout: 2000 as number | undefined
snackbar: false,
text: '',
timeout: 0 as number | undefined,
level: ''
}
},
methods: {
Expand All @@ -25,6 +26,7 @@ export default defineComponent({
this.snackbar = true
this.text = notifications.message
this.timeout = notifications.timeout
this.level = notifications.level
}
},
watch: {
Expand All @@ -45,12 +47,12 @@ export default defineComponent({
<VSnackbar
v-model="snackbar"
:timeout="timeout"
:color="level"
>
{{ text }}

<template v-slot:actions>
<v-btn
color="pink"
variant="text"
@click="snackbar = false"
>
Expand Down
26 changes: 7 additions & 19 deletions client/src/views/Project/Tables/EventDispatcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,10 @@ class EventDispatcher {
async onRequestProjectEvent(requestProjectEvent: RequestProjectEvent, componentContext: ComponentContextSchema) {
const tableStore = useTableStore()
const project = UtilSchema.getProject(componentContext)
try {
if (requestProjectEvent.method == 'get') {
await tableStore.executeGet(project, requestProjectEvent.url)
} else {
await tableStore.executePost(project, requestProjectEvent.url, UtilSchema.renderObject(requestProjectEvent.data, componentContext))
}
} catch (e) {
alert('Error on execute: ' + String(requestProjectEvent))
if (requestProjectEvent.method == 'get') {
await tableStore.executeGet(project, requestProjectEvent.url)
} else {
await tableStore.executePost(project, requestProjectEvent.url, UtilSchema.renderObject(requestProjectEvent.data, componentContext))
}
}

Expand All @@ -57,11 +53,8 @@ class EventDispatcher {
}
})
const project = UtilSchema.getProject(componentContext)
try {
await tableStore.updateItem(project, table, id, keys)
} catch (e) {
alert('Error, when update item')
}
await tableStore.updateItem(project, table, id, keys)

}

async onCreateItemEvent(
Expand All @@ -79,12 +72,7 @@ class EventDispatcher {
}
})

try {
return await tableStore.createItem(project, table, items)
} catch (e) {
alert('Error, when create item')
throw new Error('Error, when create item')
}
return await tableStore.createItem(project, table, items)
}

async onDeleteItemEvent(
Expand Down
24 changes: 0 additions & 24 deletions client/src/views/SchemaJsonView.vue

This file was deleted.

15 changes: 7 additions & 8 deletions server/promptadmin_server/api/app.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
from promptadmin_server.api.job.monitor_status_job import MonitorStatusJob
from promptadmin_server.api.job.sync_job import SyncJob
from promptadmin_server.api.job.unit_test_job import UnitTestJob
from promptadmin_server.api.exceptions_handlers import bind_exception_handlers
from promptadmin_server.api.routers import router
from promptadmin_server.api.session_middleware import SessionMiddleware
from promptadmin_server.commons.fastapi.app import create_app
Expand All @@ -11,12 +9,13 @@
# SyncJob(),
# MonitorStatusJob()
],
redoc_url='/api/redoc',
docs_url='/api/docs',
openapi_url='/api/openapi.json',
redoc_url="/api/redoc",
docs_url="/api/docs",
openapi_url="/api/openapi.json",
)

app.add_middleware(SessionMiddleware,
secret_key='asdasdasdasd')
app.add_middleware(SessionMiddleware, secret_key="asdasdasdasd")

app.include_router(router)

bind_exception_handlers(app)
5 changes: 5 additions & 0 deletions server/promptadmin_server/api/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,8 @@ class ProjectConnectionException(ApiException):
class TypeCheckException(ApiException):
STATUS_CODE = 502
DETAIL = "Received an object that was not expected"


class SQLDBException(ApiException):
STATUS_CODE = 503
DETAIL = "SQL request throw exception"
37 changes: 37 additions & 0 deletions server/promptadmin_server/api/exceptions_handlers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import logging

from asyncpg import ForeignKeyViolationError
from fastapi import FastAPI, Request

from promptadmin_server.api.exceptions import SQLDBException

logger = logging.getLogger(__name__)


async def log_request(request: Request, exc: Exception):
request_json = ""
try:
request_json = await request.json()
request_json = str(request_json)
except Exception:
request_json = ""

logger.error(
"ForeignKeyViolationError",
exc_info=exc,
extra={
"request-url": request.url,
"request-query-params": request.query_params,
"request-data": request_json,
},
)


def bind_exception_handlers(app: FastAPI):

@app.exception_handler(ForeignKeyViolationError)
async def unicorn_exception_handler(
request: Request, exc: ForeignKeyViolationError
):
await log_request(request, exc)
raise SQLDBException(headers={"Error-Message": exc.detail})
2 changes: 1 addition & 1 deletion server/promptadmin_server/api/routers/auth.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from fastapi import APIRouter, Request
from pydantic import BaseModel

from promptadmin_server.api.exceptions import TypeCheckException
from promptadmin_server.api.exceptions import TypeCheckException, ApiException
from promptadmin_server.api.routers.dependency import UserDependsAnnotated
from promptadmin_server.api.service.user_data import UserData
from promptadmin_server.api.service.user_manager_service import UserManagerService
Expand Down
2 changes: 1 addition & 1 deletion server/promptadmin_server/api/routers/prompts.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
from pydantic import BaseModel

from promptadmin_server.api.dto.prompt import Prompt
from promptadmin_server.api.exceptions import TypeCheckException
from promptadmin_server.api.exceptions import TypeCheckException, ApiException
from promptadmin_server.api.routers.dependency import UserDependsAnnotated
from promptadmin_server.api.service.permission.permission_prompt_service import (
PermissionPromptService,
Expand Down
28 changes: 19 additions & 9 deletions server/promptadmin_server/api/routers/vars.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,12 @@

from promptadmin_server.api.dto.project_request import ProjectRequest
from promptadmin_server.api.routers.dependency import UserDependsAnnotated
from promptadmin_server.api.service.access_permission_service import AccessPermissionService
from promptadmin_server.api.service.permission.permission_var_service import PermissionVarService
from promptadmin_server.api.service.access_permission_service import (
AccessPermissionService,
)
from promptadmin_server.api.service.permission.permission_var_service import (
PermissionVarService,
)

router = APIRouter()

Expand All @@ -25,21 +29,27 @@ class VarCreateDto(VarDto):
template: bool


@router.post('/load')
@router.post("/load")
async def load(project_request: ProjectRequest, user_data: UserDependsAnnotated):
return await permission_var_service.collect(project_request.project, user_data)


@router.post('/create')
@router.post("/create")
async def create(var_dto: VarCreateDto, user_data: UserDependsAnnotated):
return await permission_var_service.create(var_dto.project, var_dto.key, var_dto.value, var_dto.template, user_data)
return await permission_var_service.create(
var_dto.project, var_dto.key, var_dto.value, var_dto.template, user_data
)


@router.post('/remove')
@router.post("/remove")
async def remove(var_key_dto: VarKeyDto, user_data: UserDependsAnnotated):
return await permission_var_service.remove(var_key_dto.project, var_key_dto.key, user_data)
return await permission_var_service.remove(
var_key_dto.project, var_key_dto.key, user_data
)


@router.post('/change')
@router.post("/change")
async def change(var_dto: VarDto, user_data: UserDependsAnnotated):
return await permission_var_service.change(var_dto.project, var_dto.key, var_dto.project, user_data)
return await permission_var_service.change(
var_dto.project, var_dto.key, var_dto.project, user_data
)
Loading

0 comments on commit 3b40db5

Please sign in to comment.