Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature: creating dashboards, widgets and reports when a project its … #7

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
253 changes: 253 additions & 0 deletions insights/dashboards/usecases/dashboard_creation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,253 @@
from insights.dashboards.models import Dashboard
from insights.widgets.models import Widget, Report
from django.db import transaction
from insights.dashboards.usecases.exceptions import (
InvalidDashboardObject,
InvalidWidgetsObject,
InvalidReportsObject,
)


class create_atendimento_humano:
def create_dashboard(self, project):
try:
with transaction.atomic():
atendimento_humano = Dashboard.objects.create(
project=project,
name="Atendimento Humano",
description="Dashboard de atendimento humano",
is_default=False,
)
self.create_widgets(atendimento_humano)

except Exception as exception:
raise InvalidDashboardObject(f"Error creating dashboard: {exception}")

def create_widgets(self, dashboard_atendimento_humano):
try:
with transaction.atomic():
pico_de_atendimento = Widget.objects.create(
name="Picos de atendimentos abertos",
w_type="graph_column",
source="chats",
config={
"end_time": "18:00",
"interval": "60",
"start_time": "07:00",
},
dashboard=dashboard_atendimento_humano,
position={"rows": [1, 1], "columns": [1, 12]},
)
em_andamento = Widget.objects.create(
name="Em andamento",
w_type="card",
source="chats",
config={"operation": "count", "type_result": "executions"},
dash=dashboard_atendimento_humano,
position={"rows": [2, 2], "columns": [1, 4]},
)
Widget.objects.create(
name="Tempo de espera",
w_type="card",
source="chats",
config={"operation": "AVG", "type_result": "executions"},
dash=dashboard_atendimento_humano,
position={"rows": [2, 2], "columns": [5, 8]},
)
encerrados = Widget.objects.create(
name="Encerrados",
w_type="card",
source="chats",
config={"operation": "AVG", "type_result": "executions"},
dash=dashboard_atendimento_humano,
position={"rows": [2, 2], "columns": [9, 12]},
)
Widget.objects.create(
name="Tempo de resposta",
w_type="card",
source="chats",
config={"operation": "count", "type_result": "executions"},
dash=dashboard_atendimento_humano,
position={"rows": [3, 3], "columns": [1, 4]},
)
aguardando_atendimento = Widget.objects.create(
name="Aguardando atendimento",
w_type="card",
source="chats",
config={"operation": "count", "type_result": "executions"},
dash=dashboard_atendimento_humano,
position={"rows": [3, 3], "columns": [5, 8]},
)
Widget.objects.create(
name="Tempo de interação",
w_type="card",
source="chats",
config={"operation": "count", "type_result": "executions"},
dash=dashboard_atendimento_humano,
position={"rows": [3, 3], "columns": [9, 12]},
)
Widget.objects.create(
name="Chats por agente",
w_type="table_dynamic_by_filter",
source="chats",
config={
"default": {
"icon": "forum:weni-600",
"fields": [
{
"name": "Agente",
"value": "agent",
"display": True,
"hidden_name": False,
},
{
"name": "Em andamento",
"value": "open",
"display": True,
"hidden_name": False,
},
{
"name": "Encerrados",
"value": "close",
"display": True,
"hidden_name": False,
},
{
"name": "Status",
"value": "status",
"display": True,
"hidden_name": False,
},
],
"name_overwrite": "Agentes online",
}
},
dash=dashboard_atendimento_humano,
position={"rows": [1, 3], "columns": [13, 18]},
)

self.create_reports(
pico_de_atendimento,
em_andamento,
encerrados,
aguardando_atendimento,
)
except Exception as exception:
raise InvalidWidgetsObject(f"Error creating widgets: {exception}")

def create_reports(
self, pico_de_atendimento, em_andamento, encerrados, aguardando_atendimento
):
try:
with transaction.atomic():
Report.objects.create(
name="Pico de chats abertos por hora",
w_type="graph_column",
source="chats",
config={},
widget=pico_de_atendimento,
)
Report.objects.create(
name="Em andamento",
w_type="table_group",
source="chats",
config={},
widget=em_andamento,
)
Report.objects.create(
name="Encerrados",
w_type="table_group",
source="chats",
config={},
widget=encerrados,
)
Report.objects.create(
name="Aguardando atendimento",
w_type="table_group",
source="chats",
config={},
widget=aguardando_atendimento,
)
except Exception as exception:
raise InvalidReportsObject(f"Error creating dashboard: {exception}")


class create_resultado_de_fluxo:
def create_dashboard(self, project):
try:
with transaction.atomic():
dashboard_resultado_de_fluxo = Dashboard.objects.create(
project=project,
name="Resultado de fluxo",
description="Dashboard de resultado de fluxo",
is_default=False,
)
self.create_widgets(dashboard_resultado_de_fluxo)

except Exception as exception:
raise InvalidDashboardObject(f"Error creating dashboard: {exception}")

def create_widgets(self, dashboard_resultado_de_fluxo):
try:
with transaction.atomic():
Widget.objects.create(
name="Métrica vazia",
w_type="card",
source="",
config={},
dash=dashboard_resultado_de_fluxo,
position={"rows": [1, 1], "columns": [1, 4]},
)
Widget.objects.create(
name="Métrica vazia",
w_type="card",
source="",
config={},
dash=dashboard_resultado_de_fluxo,
position={"rows": [2, 2], "columns": [1, 4]},
)
Widget.objects.create(
name="Métrica vazia",
w_type="card",
source="",
config={},
dash=dashboard_resultado_de_fluxo,
position={"rows": [3, 3], "columns": [1, 4]},
)
Widget.objects.create(
name="Métrica vazia",
w_type="card",
source="",
config={},
dash=dashboard_resultado_de_fluxo,
position={"rows": [1, 1], "columns": [5, 8]},
)
Widget.objects.create(
name="Métrica vazia",
w_type="card",
source="",
config={},
dash=dashboard_resultado_de_fluxo,
position={"rows": [2, 2], "columns": [5, 8]},
)
Widget.objects.create(
name="Métrica vazia",
w_type="card",
source="",
config={},
dash=dashboard_resultado_de_fluxo,
position={"rows": [3, 3], "columns": [5, 8]},
)
Widget.objects.create(
name="Métrica vazia",
w_type="graph_funnel",
source="",
config={},
dash=dashboard_resultado_de_fluxo,
position={"rows": [1, 3], "columns": [9, 12]},
)
except Exception as exception:
raise InvalidWidgetsObject(f"Error creating widgets: {exception}")

def create_reports():
pass
10 changes: 10 additions & 0 deletions insights/dashboards/usecases/exceptions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
class InvalidDashboardObject(Exception):
pass


class InvalidWidgetsObject(Exception):
pass


class InvalidReportsObject(Exception):
pass
Empty file added insights/dashboards/utils.py
Empty file.
8 changes: 7 additions & 1 deletion insights/projects/usecases/create.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

from .project_dto import ProjectCreationDTO

from insights.dashboards.usecases.dashboard_creation import (
create_atendimento_humano,
create_resultado_de_fluxo,
)


class ProjectsUseCase:

Expand All @@ -23,5 +28,6 @@ def create_project(self, project_dto: ProjectCreationDTO) -> Project:
timezone=project_dto.timezone,
date_format=project_dto.date_format,
)

create_atendimento_humano.create_dashboard(project)
create_resultado_de_fluxo.create_dashboard(project)
return project
66 changes: 66 additions & 0 deletions insights/widgets/migrations/0002_remove_widget_report_report.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# Generated by Django 5.0.4 on 2024-05-28 18:55

import django.db.models.deletion
import uuid
from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
("widgets", "0001_initial"),
]

operations = [
migrations.RemoveField(
model_name="widget",
name="report",
),
migrations.CreateModel(
name="Report",
fields=[
(
"uuid",
models.UUIDField(
default=uuid.uuid4, primary_key=True, serialize=False
),
),
(
"created_on",
models.DateTimeField(auto_now_add=True, verbose_name="Created on"),
),
(
"modified_on",
models.DateTimeField(auto_now=True, verbose_name="Modified on"),
),
(
"name",
models.CharField(default=None, max_length=255, verbose_name="Name"),
),
(
"w_type",
models.CharField(
default=None, max_length=50, verbose_name="Widget Type"
),
),
(
"source",
models.CharField(
default=None, max_length=50, verbose_name="Data Source"
),
),
("config", models.JSONField(verbose_name="Widget Configuration")),
(
"widget",
models.OneToOneField(
on_delete=django.db.models.deletion.CASCADE,
related_name="report",
to="widgets.widget",
),
),
],
options={
"abstract": False,
},
),
]
29 changes: 22 additions & 7 deletions insights/widgets/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,7 @@
from insights.shared.models import BaseModel, ConfigurableModel


class Widget(BaseModel, ConfigurableModel):
dashboard = models.ForeignKey(
"dashboards.Dashboard", related_name="widgets", on_delete=models.CASCADE
)
class BaseWidget(BaseModel, ConfigurableModel):
name = models.CharField(
"Name", max_length=255, null=False, blank=False, default=None
)
Expand All @@ -16,9 +13,27 @@ class Widget(BaseModel, ConfigurableModel):
source = models.CharField(
"Data Source", max_length=50, null=False, blank=False, default=None
)
position = models.JSONField("Widget position")
# config needs to be required in widget
config = models.JSONField("Widget Configuration")
report = models.JSONField("Widget Report")

class Meta:
abstract = True


class Widget(BaseWidget):
dashboard = models.ForeignKey(
"dashboards.Dashboard", related_name="widgets", on_delete=models.CASCADE
)
position = models.JSONField("Widget position")

def __str__(self):
return self.name


class Report(BaseWidget):
widget = models.OneToOneField(
Widget, related_name="report", on_delete=models.CASCADE
)

def __str__(self):
return self.description
return self.name