mirror of
https://github.com/kjanat/livegraphs-django.git
synced 2026-01-16 11:42:10 +01:00
Refactor HTML templates for improved readability and consistency
- Updated search_results_table.html to enhance formatting and maintain consistent indentation. - Refined search_results.html layout for better structure and clarity. - Improved upload.html for better organization and readability of the upload form and data source table. - Removed unnecessary lines in package.json and streamlined devDependencies section.
This commit is contained in:
@ -18,8 +18,8 @@ indent_size = 4
|
|||||||
|
|
||||||
# HTML and Django/Jinja2 template files
|
# HTML and Django/Jinja2 template files
|
||||||
[*.{html,htm}]
|
[*.{html,htm}]
|
||||||
indent_style = tab
|
indent_size = 2
|
||||||
indent_size = 4
|
|
||||||
# Allow prettier to format Django/Jinja templates properly
|
# Allow prettier to format Django/Jinja templates properly
|
||||||
# The following comment options can be used in individual files if needed:
|
# The following comment options can be used in individual files if needed:
|
||||||
# <!-- prettier-ignore -->
|
# <!-- prettier-ignore -->
|
||||||
|
|||||||
1
.gitignore
vendored
1
.gitignore
vendored
@ -407,6 +407,7 @@ pyrightconfig.json
|
|||||||
*Zone.Identifier
|
*Zone.Identifier
|
||||||
examples/
|
examples/
|
||||||
**/migrations/[0-9]**.py
|
**/migrations/[0-9]**.py
|
||||||
|
package-lock.json
|
||||||
|
|
||||||
# UV specific
|
# UV specific
|
||||||
.uv/
|
.uv/
|
||||||
|
|||||||
@ -3,6 +3,7 @@ default_install_hook_types:
|
|||||||
- post-checkout
|
- post-checkout
|
||||||
- post-merge
|
- post-merge
|
||||||
- post-rewrite
|
- post-rewrite
|
||||||
|
|
||||||
repos:
|
repos:
|
||||||
# uv hooks for dependency management
|
# uv hooks for dependency management
|
||||||
- repo: https://github.com/astral-sh/uv-pre-commit
|
- repo: https://github.com/astral-sh/uv-pre-commit
|
||||||
@ -33,18 +34,18 @@ repos:
|
|||||||
# rev: 3.0.7
|
# rev: 3.0.7
|
||||||
# hooks:
|
# hooks:
|
||||||
# - id: djhtml
|
# - id: djhtml
|
||||||
# entry: djhtml --tabwidth 4 --
|
# entry: djhtml --tabwidth 4
|
||||||
# - id: djcss
|
|
||||||
# - id: djjs
|
|
||||||
|
|
||||||
- repo: https://github.com/pre-commit/mirrors-prettier
|
- repo: https://github.com/pre-commit/mirrors-prettier
|
||||||
rev: v4.0.0-alpha.8
|
rev: v3.1.0
|
||||||
hooks:
|
hooks:
|
||||||
- id: prettier
|
- id: prettier
|
||||||
types_or: [javascript, jsx, ts, tsx, css, scss, html, json, yaml, markdown]
|
types_or: [javascript, jsx, ts, tsx, css, scss, html, json, yaml, markdown]
|
||||||
additional_dependencies:
|
additional_dependencies:
|
||||||
- prettier
|
- prettier
|
||||||
- prettier-plugin-jinja-template
|
- prettier-plugin-jinja-template
|
||||||
|
# types_or: [javascript, jsx, ts, tsx, css, scss, json, yaml, markdown]
|
||||||
|
# exclude: '.*\.html$'
|
||||||
|
|
||||||
# Ruff for linting and formatting
|
# Ruff for linting and formatting
|
||||||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||||
|
|||||||
@ -47,3 +47,6 @@ docker-compose.override.yml
|
|||||||
.vscode/
|
.vscode/
|
||||||
*.swp
|
*.swp
|
||||||
*.swo
|
*.swo
|
||||||
|
|
||||||
|
# Ignore all SQLite3 files:
|
||||||
|
**/*.sqlite3
|
||||||
|
|||||||
@ -11,7 +11,7 @@
|
|||||||
"requirePragma": false,
|
"requirePragma": false,
|
||||||
"semi": true,
|
"semi": true,
|
||||||
"singleQuote": false,
|
"singleQuote": false,
|
||||||
"useTabs": true,
|
"useTabs": false,
|
||||||
"overrides": [
|
"overrides": [
|
||||||
{
|
{
|
||||||
"files": ["*.html"],
|
"files": ["*.html"],
|
||||||
|
|||||||
11
Makefile
11
Makefile
@ -1,4 +1,4 @@
|
|||||||
.PHONY: venv install install-dev lint test format clean run migrate makemigrations superuser setup-node format-js
|
.PHONY: venv install install-dev lint test format clean run migrate makemigrations superuser setup-node
|
||||||
|
|
||||||
# Create a virtual environment
|
# Create a virtual environment
|
||||||
venv:
|
venv:
|
||||||
@ -25,13 +25,9 @@ format:
|
|||||||
uv run -m ruff format dashboard_project
|
uv run -m ruff format dashboard_project
|
||||||
uv run -m black dashboard_project
|
uv run -m black dashboard_project
|
||||||
|
|
||||||
# Format JavaScript/CSS/HTML files with Prettier
|
|
||||||
format-js:
|
|
||||||
npx run format
|
|
||||||
|
|
||||||
# Setup Node.js dependencies
|
# Setup Node.js dependencies
|
||||||
setup-node:
|
setup-node:
|
||||||
npm install
|
npm install --include=dev
|
||||||
|
|
||||||
# Clean Python cache files
|
# Clean Python cache files
|
||||||
clean:
|
clean:
|
||||||
@ -45,6 +41,9 @@ clean:
|
|||||||
find . -type d -name ".coverage" -exec rm -rf {} +
|
find . -type d -name ".coverage" -exec rm -rf {} +
|
||||||
find . -type d -name "htmlcov" -exec rm -rf {} +
|
find . -type d -name "htmlcov" -exec rm -rf {} +
|
||||||
find . -type d -name ".ruff_cache" -exec rm -rf {} +
|
find . -type d -name ".ruff_cache" -exec rm -rf {} +
|
||||||
|
find . -type d -name ".mypy_cache" -exec rm -rf {} +
|
||||||
|
find . -type d -name ".tox" -exec rm -rf {} +
|
||||||
|
find . -type d -name "node_modules" -exec rm -rf {} +
|
||||||
rm -rf build/
|
rm -rf build/
|
||||||
rm -rf dist/
|
rm -rf dist/
|
||||||
|
|
||||||
|
|||||||
86
TODO.md
86
TODO.md
@ -1,31 +1,57 @@
|
|||||||
# TODO List
|
# LiveGraphs Project TODO
|
||||||
|
|
||||||
- When I zoom into the dasboard page, the graphs don't scale/adjust to fit the window until I completely refresh the page, can we solve that?
|
## Dashboard UI Improvements
|
||||||
- Add export functionality to the dashboard:
|
|
||||||
- File formats:
|
### Responsiveness
|
||||||
- CSV
|
|
||||||
- Excel
|
- [ ] Fix dashboard graphs scaling/adjustment when zooming (currently requires page refresh)
|
||||||
- JSON
|
|
||||||
- XML
|
### Theming
|
||||||
- HTML
|
|
||||||
- PDF
|
- [ ] Add dark mode/light mode toggle
|
||||||
- Make the export button a dropdown with the following options:
|
- [ ] Add Notso AI branding elements
|
||||||
- Export as CSV
|
- [ ] Implement responsive table design (reduce rows to fit screen)
|
||||||
- Export as Excel
|
|
||||||
- Export as JSON
|
### Data Export
|
||||||
- Export as XML
|
|
||||||
- Export as HTML
|
- [ ] Implement multi-format export functionality
|
||||||
- Export as PDF
|
- [ ] CSV format
|
||||||
- Make the export data section folded by default and only show the export button.
|
- [ ] Excel format
|
||||||
- Adjust the downloaded file name to include the company name, date and time of the export.
|
- [ ] JSON format
|
||||||
- Add a button to download the CSV file for the selected company.
|
- [ ] XML format
|
||||||
- Make it possible to modify the column names in the CSV file through the admin interface.
|
- [ ] HTML format
|
||||||
- Add possibility to add a company logo in the admin interface.
|
- [ ] PDF format
|
||||||
- Add periodic download from <https://proto.notso.ai/XY/chats> possibility for the XY company.
|
- [ ] Create dropdown menu for export options
|
||||||
- Authentication: Basic Auth
|
- [ ] Make export data section collapsible (folded by default)
|
||||||
- URL: <https://proto.notso.ai/XY/chats>
|
- [ ] Add company name, date and timestamp to exported filenames
|
||||||
- Username: xxxx
|
|
||||||
- Password: xxxx
|
## Admin Interface Enhancements
|
||||||
- Reduce amount of rows in the table to fit the screen.
|
|
||||||
- Add dark mode/theming to the dashboard.
|
### Company Management
|
||||||
- Add Notso AI branding to the dashboard.
|
|
||||||
|
- [ ] Add company logo upload functionality
|
||||||
|
- [ ] Add direct CSV download button for each company (superusers only)
|
||||||
|
- [ ] Include company name, date and timestamp in filename
|
||||||
|
- [ ] Add UI for customizing CSV column names
|
||||||
|
|
||||||
|
## Data Integration
|
||||||
|
|
||||||
|
### External Data Sources
|
||||||
|
|
||||||
|
- [ ] Implement periodic data download from external API
|
||||||
|
- [ ] Source: <https://proto.notso.ai/XY/chats>
|
||||||
|
- [ ] Authentication: Basic Auth
|
||||||
|
- [ ] Credentials: [stored securely]
|
||||||
|
- [ ] Add scheduling options for data refresh
|
||||||
|
|
||||||
|
## Technical Debt
|
||||||
|
|
||||||
|
### Performance Optimization
|
||||||
|
|
||||||
|
- [ ] Profile and optimize dashboard rendering
|
||||||
|
- [ ] Implement lazy loading for dashboard elements
|
||||||
|
|
||||||
|
### Testing
|
||||||
|
|
||||||
|
- [ ] Add unit tests for export functionality
|
||||||
|
- [ ] Add integration tests for data import process
|
||||||
|
|||||||
@ -91,8 +91,8 @@ AUTH_PASSWORD_VALIDATORS = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
# Internationalization
|
# Internationalization
|
||||||
LANGUAGE_CODE = "en-us"
|
LANGUAGE_CODE = "nl"
|
||||||
TIME_ZONE = "UTC"
|
TIME_ZONE = "Europe/Amsterdam"
|
||||||
USE_I18N = True
|
USE_I18N = True
|
||||||
USE_TZ = True
|
USE_TZ = True
|
||||||
|
|
||||||
|
|||||||
@ -1,9 +1,8 @@
|
|||||||
<!-- templates/accounts/login.html -->
|
<!-- templates/accounts/login.html -->
|
||||||
{% extends 'base.html' %}
|
{% extends 'base.html' %} {% load crispy_forms_tags %}
|
||||||
{% load crispy_forms_tags %}
|
{% block title %}
|
||||||
|
Login | Chat Analytics
|
||||||
{% block title %}Login | Chat Analytics{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="row justify-content-center">
|
<div class="row justify-content-center">
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
@ -13,17 +12,14 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<form method="post">
|
<form method="post">
|
||||||
{% csrf_token %}
|
{% csrf_token %} {{ form|crispy }}
|
||||||
{{ form|crispy }}
|
|
||||||
<div class="d-grid gap-2">
|
<div class="d-grid gap-2">
|
||||||
<button type="submit" class="btn btn-primary">Login</button>
|
<button type="submit" class="btn btn-primary">Login</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-footer text-center">
|
<div class="card-footer text-center">
|
||||||
<p class="mb-0">
|
<p class="mb-0">Don't have an account? <a href="{% url 'register' %}">Register</a></p>
|
||||||
Don't have an account? <a href="{% url 'register' %}">Register</a>
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,9 +1,7 @@
|
|||||||
<!-- templates/accounts/password_change.html -->
|
<!-- templates/accounts/password_change.html -->
|
||||||
{% extends 'base.html' %}
|
{% extends 'base.html' %}
|
||||||
{% load crispy_forms_tags %}
|
{% load crispy_forms_tags %}
|
||||||
|
|
||||||
{% block title %}Change Password | Chat Analytics{% endblock %}
|
{% block title %}Change Password | Chat Analytics{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div
|
<div
|
||||||
class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom"
|
class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom"
|
||||||
@ -24,8 +22,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<form method="post">
|
<form method="post">
|
||||||
{% csrf_token %}
|
{% csrf_token %} {{ form|crispy }}
|
||||||
{{ form|crispy }}
|
|
||||||
<div class="d-grid gap-2">
|
<div class="d-grid gap-2">
|
||||||
<button type="submit" class="btn btn-primary">Change Password</button>
|
<button type="submit" class="btn btn-primary">Change Password</button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,8 +1,5 @@
|
|||||||
<!-- templates/accounts/password_change_done.html -->
|
<!-- templates/accounts/password_change_done.html -->
|
||||||
{% extends 'base.html' %}
|
{% extends 'base.html' %} {% block title %}Password Changed | Chat Analytics{% endblock %}
|
||||||
|
|
||||||
{% block title %}Password Changed | Chat Analytics{% endblock %}
|
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div
|
<div
|
||||||
class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom"
|
class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom"
|
||||||
@ -25,10 +22,7 @@
|
|||||||
<div class="mb-4">
|
<div class="mb-4">
|
||||||
<i class="fas fa-check-circle fa-4x text-success mb-3"></i>
|
<i class="fas fa-check-circle fa-4x text-success mb-3"></i>
|
||||||
<h4>Your password has been changed successfully!</h4>
|
<h4>Your password has been changed successfully!</h4>
|
||||||
<p>
|
<p>Your new password is now active. You can use it the next time you log in.</p>
|
||||||
Your new password is now active. You can use it the next time you log
|
|
||||||
in.
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="mt-4">
|
<div class="mt-4">
|
||||||
|
|||||||
@ -1,8 +1,6 @@
|
|||||||
<!-- templates/accounts/profile.html -->
|
<!-- templates/accounts/profile.html -->
|
||||||
{% extends 'base.html' %}
|
{% extends 'base.html' %}
|
||||||
|
|
||||||
{% block title %}My Profile | Chat Analytics{% endblock %}
|
{% block title %}My Profile | Chat Analytics{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div
|
<div
|
||||||
class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom"
|
class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom"
|
||||||
@ -62,9 +60,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-footer">
|
<div class="card-footer">
|
||||||
<a href="{% url 'password_change' %}" class="btn btn-primary"
|
<a href="{% url 'password_change' %}" class="btn btn-primary">Change Password</a>
|
||||||
>Change Password</a
|
|
||||||
>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -118,9 +114,7 @@
|
|||||||
<div class="card h-100">
|
<div class="card h-100">
|
||||||
<div class="card-body text-center">
|
<div class="card-body text-center">
|
||||||
<h5 class="card-title">Manage Users</h5>
|
<h5 class="card-title">Manage Users</h5>
|
||||||
<p class="card-text">
|
<p class="card-text">Manage users and assign them to companies.</p>
|
||||||
Manage users and assign them to companies.
|
|
||||||
</p>
|
|
||||||
<a
|
<a
|
||||||
href="{% url 'admin:accounts_customuser_changelist' %}"
|
href="{% url 'admin:accounts_customuser_changelist' %}"
|
||||||
class="btn btn-primary"
|
class="btn btn-primary"
|
||||||
@ -133,9 +127,7 @@
|
|||||||
<div class="card h-100">
|
<div class="card h-100">
|
||||||
<div class="card-body text-center">
|
<div class="card-body text-center">
|
||||||
<h5 class="card-title">Manage Companies</h5>
|
<h5 class="card-title">Manage Companies</h5>
|
||||||
<p class="card-text">
|
<p class="card-text">Create and edit companies in the system.</p>
|
||||||
Create and edit companies in the system.
|
|
||||||
</p>
|
|
||||||
<a
|
<a
|
||||||
href="{% url 'admin:accounts_company_changelist' %}"
|
href="{% url 'admin:accounts_company_changelist' %}"
|
||||||
class="btn btn-primary"
|
class="btn btn-primary"
|
||||||
@ -149,11 +141,7 @@
|
|||||||
<div class="card-body text-center">
|
<div class="card-body text-center">
|
||||||
<h5 class="card-title">Admin Dashboard</h5>
|
<h5 class="card-title">Admin Dashboard</h5>
|
||||||
<p class="card-text">Go to the full admin dashboard.</p>
|
<p class="card-text">Go to the full admin dashboard.</p>
|
||||||
<a
|
<a href="{% url 'admin:index' %}" class="btn btn-primary">Admin Dashboard</a>
|
||||||
href="{% url 'admin:index' %}"
|
|
||||||
class="btn btn-primary"
|
|
||||||
>Admin Dashboard</a
|
|
||||||
>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -162,12 +150,8 @@
|
|||||||
<div class="card h-100">
|
<div class="card h-100">
|
||||||
<div class="card-body text-center">
|
<div class="card-body text-center">
|
||||||
<h5 class="card-title">Manage Dashboards</h5>
|
<h5 class="card-title">Manage Dashboards</h5>
|
||||||
<p class="card-text">
|
<p class="card-text">Create and edit dashboards for your company.</p>
|
||||||
Create and edit dashboards for your company.
|
<a href="{% url 'create_dashboard' %}" class="btn btn-primary"
|
||||||
</p>
|
|
||||||
<a
|
|
||||||
href="{% url 'create_dashboard' %}"
|
|
||||||
class="btn btn-primary"
|
|
||||||
>Manage Dashboards</a
|
>Manage Dashboards</a
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
@ -177,14 +161,8 @@
|
|||||||
<div class="card h-100">
|
<div class="card h-100">
|
||||||
<div class="card-body text-center">
|
<div class="card-body text-center">
|
||||||
<h5 class="card-title">Upload Data</h5>
|
<h5 class="card-title">Upload Data</h5>
|
||||||
<p class="card-text">
|
<p class="card-text">Upload and manage data sources for analysis.</p>
|
||||||
Upload and manage data sources for analysis.
|
<a href="{% url 'upload_data' %}" class="btn btn-primary">Upload Data</a>
|
||||||
</p>
|
|
||||||
<a
|
|
||||||
href="{% url 'upload_data' %}"
|
|
||||||
class="btn btn-primary"
|
|
||||||
>Upload Data</a
|
|
||||||
>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -192,12 +170,8 @@
|
|||||||
<div class="card h-100">
|
<div class="card h-100">
|
||||||
<div class="card-body text-center">
|
<div class="card-body text-center">
|
||||||
<h5 class="card-title">Search Sessions</h5>
|
<h5 class="card-title">Search Sessions</h5>
|
||||||
<p class="card-text">
|
<p class="card-text">Search and analyze chat sessions.</p>
|
||||||
Search and analyze chat sessions.
|
<a href="{% url 'search_chat_sessions' %}" class="btn btn-primary"
|
||||||
</p>
|
|
||||||
<a
|
|
||||||
href="{% url 'search_chat_sessions' %}"
|
|
||||||
class="btn btn-primary"
|
|
||||||
>Search Sessions</a
|
>Search Sessions</a
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,9 +1,8 @@
|
|||||||
<!-- templates/accounts/register.html -->
|
<!-- templates/accounts/register.html -->
|
||||||
{% extends 'base.html' %}
|
{% extends 'base.html' %} {% load crispy_forms_tags %}
|
||||||
{% load crispy_forms_tags %}
|
{% block title %}
|
||||||
|
Register | Chat Analytics
|
||||||
{% block title %}Register | Chat Analytics{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="row justify-content-center">
|
<div class="row justify-content-center">
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
@ -13,17 +12,14 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<form method="post">
|
<form method="post">
|
||||||
{% csrf_token %}
|
{% csrf_token %} {{ form|crispy }}
|
||||||
{{ form|crispy }}
|
|
||||||
<div class="d-grid gap-2">
|
<div class="d-grid gap-2">
|
||||||
<button type="submit" class="btn btn-primary">Register</button>
|
<button type="submit" class="btn btn-primary">Register</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-footer text-center">
|
<div class="card-footer text-center">
|
||||||
<p class="mb-0">
|
<p class="mb-0">Already have an account? <a href="{% url 'login' %}">Login</a></p>
|
||||||
Already have an account? <a href="{% url 'login' %}">Login</a>
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -81,37 +81,24 @@
|
|||||||
aria-expanded="false"
|
aria-expanded="false"
|
||||||
>
|
>
|
||||||
{% if user.company %}
|
{% if user.company %}
|
||||||
<span class="badge bg-info me-1"
|
<span class="badge bg-info me-1">{{ user.company.name }}</span>
|
||||||
>{{ user.company.name }}</span
|
|
||||||
>
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{{ user.username }}
|
{{ user.username }}
|
||||||
</button>
|
</button>
|
||||||
<ul
|
<ul class="dropdown-menu dropdown-menu-end" aria-labelledby="userDropdown">
|
||||||
class="dropdown-menu dropdown-menu-end"
|
|
||||||
aria-labelledby="userDropdown"
|
|
||||||
>
|
|
||||||
<li>
|
<li>
|
||||||
<a
|
<a class="dropdown-item ajax-nav-link" href="{% url 'profile' %}">Profile</a>
|
||||||
class="dropdown-item ajax-nav-link"
|
|
||||||
href="{% url 'profile' %}"
|
|
||||||
>Profile</a
|
|
||||||
>
|
|
||||||
</li>
|
</li>
|
||||||
{% if user.is_staff %}
|
{% if user.is_staff %}
|
||||||
<li>
|
<li>
|
||||||
<a class="dropdown-item" href="{% url 'admin:index' %}"
|
<a class="dropdown-item" href="{% url 'admin:index' %}">Admin</a>
|
||||||
>Admin</a
|
|
||||||
>
|
|
||||||
</li>
|
</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<li>
|
<li>
|
||||||
<hr class="dropdown-divider" />
|
<hr class="dropdown-divider" />
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a class="dropdown-item" href="{% url 'logout' %}"
|
<a class="dropdown-item" href="{% url 'logout' %}">Logout</a>
|
||||||
>Logout</a
|
|
||||||
>
|
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
@ -195,10 +182,7 @@
|
|||||||
<li class="nav-header"><strong>Data Sources</strong></li>
|
<li class="nav-header"><strong>Data Sources</strong></li>
|
||||||
{% for data_source in data_sources %}
|
{% for data_source in data_sources %}
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a
|
<a class="nav-link" href="{% url 'data_source_detail' data_source.id %}">
|
||||||
class="nav-link"
|
|
||||||
href="{% url 'data_source_detail' data_source.id %}"
|
|
||||||
>
|
|
||||||
<i class="fas fa-database me-2"></i>
|
<i class="fas fa-database me-2"></i>
|
||||||
{{ data_source.name }}
|
{{ data_source.name }}
|
||||||
</a>
|
</a>
|
||||||
@ -224,10 +208,7 @@
|
|||||||
{# </div> #}
|
{# </div> #}
|
||||||
{# {% endif %} #}
|
{# {% endif %} #}
|
||||||
|
|
||||||
<div id="main-content">
|
<div id="main-content">{% block content %}{% endblock %}</div>
|
||||||
{% block content %}
|
|
||||||
{% endblock %}
|
|
||||||
</div>
|
|
||||||
</main>
|
</main>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -276,7 +257,7 @@
|
|||||||
{% block extra_js %}
|
{% block extra_js %}
|
||||||
{{ block.super }}
|
{{ block.super }}
|
||||||
{% if messages %}
|
{% if messages %}
|
||||||
<div class="toast-container position-fixed top-0 end-0 p-3" style="z-index: 1100;">
|
<div class="toast-container position-fixed top-0 end-0 p-3" style="z-index: 1100">
|
||||||
<!-- Toasts will be appended here -->
|
<!-- Toasts will be appended here -->
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -296,9 +277,7 @@
|
|||||||
if (!toastContainer) return;
|
if (!toastContainer) return;
|
||||||
|
|
||||||
// Find all message data elements
|
// Find all message data elements
|
||||||
const messageDataElements = document.querySelectorAll(
|
const messageDataElements = document.querySelectorAll('script[id^="message-data-"]');
|
||||||
'script[id^="message-data-"]',
|
|
||||||
);
|
|
||||||
messageDataElements.forEach(function (dataElement) {
|
messageDataElements.forEach(function (dataElement) {
|
||||||
try {
|
try {
|
||||||
const messageData = JSON.parse(dataElement.textContent);
|
const messageData = JSON.parse(dataElement.textContent);
|
||||||
@ -330,10 +309,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
const toastId =
|
const toastId =
|
||||||
"toast-" +
|
"toast-" + Date.now() + "-" + Math.random().toString(36).substring(2, 11);
|
||||||
Date.now() +
|
|
||||||
"-" +
|
|
||||||
Math.random().toString(36).substring(2, 11);
|
|
||||||
const toastHtml = `
|
const toastHtml = `
|
||||||
<div id="${toastId}" class="toast ${toastClass}" role="alert" aria-live="assertive" aria-atomic="true">
|
<div id="${toastId}" class="toast ${toastClass}" role="alert" aria-live="assertive" aria-atomic="true">
|
||||||
<div class="toast-header">
|
<div class="toast-header">
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
{% extends 'base.html' %}
|
{% extends 'base.html' %}
|
||||||
|
{% block title %}
|
||||||
{% block title %}Chat Session {{ session.session_id }} | Chat Analytics{% endblock %}
|
Chat Session {{ session.session_id }} | Chat Analytics
|
||||||
|
{% endblock %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div
|
<div
|
||||||
class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom"
|
class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom"
|
||||||
@ -31,12 +31,8 @@
|
|||||||
<strong>Start Time:</strong>
|
<strong>Start Time:</strong>
|
||||||
{{ session.start_time|date:"F d, Y H:i" }}
|
{{ session.start_time|date:"F d, Y H:i" }}
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p><strong>End Time:</strong> {{ session.end_time|date:"F d, Y H:i" }}</p>
|
||||||
<strong>End Time:</strong> {{ session.end_time|date:"F d, Y H:i" }}
|
<p><strong>IP Address:</strong> {{ session.ip_address|default:"N/A" }}</p>
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<strong>IP Address:</strong> {{ session.ip_address|default:"N/A" }}
|
|
||||||
</p>
|
|
||||||
<p><strong>Country:</strong> {{ session.country|default:"N/A" }}</p>
|
<p><strong>Country:</strong> {{ session.country|default:"N/A" }}</p>
|
||||||
<p><strong>Language:</strong> {{ session.language|default:"N/A" }}</p>
|
<p><strong>Language:</strong> {{ session.language|default:"N/A" }}</p>
|
||||||
</div>
|
</div>
|
||||||
@ -47,27 +43,19 @@
|
|||||||
{{ session.avg_response_time|floatformat:2 }}s
|
{{ session.avg_response_time|floatformat:2 }}s
|
||||||
</p>
|
</p>
|
||||||
<p><strong>Tokens:</strong> {{ session.tokens }}</p>
|
<p><strong>Tokens:</strong> {{ session.tokens }}</p>
|
||||||
<p>
|
<p><strong>Token Cost:</strong> €{{ session.tokens_eur|floatformat:2 }}</p>
|
||||||
<strong>Token Cost:</strong> €{{ session.tokens_eur|floatformat:2 }}
|
|
||||||
</p>
|
|
||||||
<p><strong>Category:</strong> {{ session.category|default:"N/A" }}</p>
|
<p><strong>Category:</strong> {{ session.category|default:"N/A" }}</p>
|
||||||
<p>
|
<p>
|
||||||
<strong>Sentiment:</strong>
|
<strong>Sentiment:</strong>
|
||||||
{% if session.sentiment %}
|
{% if session.sentiment %}
|
||||||
{% if 'positive' in session.sentiment|lower %}
|
{% if 'positive' in session.sentiment|lower %}
|
||||||
<span class="badge bg-success"
|
<span class="badge bg-success">{{ session.sentiment }}</span>
|
||||||
>{{ session.sentiment }}</span
|
|
||||||
>
|
|
||||||
{% elif 'negative' in session.sentiment|lower %}
|
{% elif 'negative' in session.sentiment|lower %}
|
||||||
<span class="badge bg-danger">{{ session.sentiment }}</span>
|
<span class="badge bg-danger">{{ session.sentiment }}</span>
|
||||||
{% elif 'neutral' in session.sentiment|lower %}
|
{% elif 'neutral' in session.sentiment|lower %}
|
||||||
<span class="badge bg-warning"
|
<span class="badge bg-warning">{{ session.sentiment }}</span>
|
||||||
>{{ session.sentiment }}</span
|
|
||||||
>
|
|
||||||
{% else %}
|
{% else %}
|
||||||
<span class="badge bg-secondary"
|
<span class="badge bg-secondary">{{ session.sentiment }}</span>
|
||||||
>{{ session.sentiment }}</span
|
|
||||||
>
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% else %}
|
{% else %}
|
||||||
<span class="text-muted">N/A</span>
|
<span class="text-muted">N/A</span>
|
||||||
@ -130,8 +118,8 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
{% if session.full_transcript %}
|
{% if session.full_transcript %}
|
||||||
<div class="chat-transcript" style="max-height: 500px; overflow-y: auto;">
|
<div class="chat-transcript" style="max-height: 500px; overflow-y: auto">
|
||||||
<pre style="white-space: pre-wrap; font-family: inherit;">
|
<pre style="white-space: pre-wrap; font-family: inherit">
|
||||||
{{ session.full_transcript }}</pre
|
{{ session.full_transcript }}</pre
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,9 +1,8 @@
|
|||||||
<!-- templates/dashboard/dashboard.html -->
|
<!-- templates/dashboard/dashboard.html -->
|
||||||
{% extends 'base.html' %}
|
{% extends 'base.html' %} {% load static %}
|
||||||
{% load static %}
|
{% block title %}
|
||||||
|
Dashboard | Chat Analytics
|
||||||
{% block title %}Dashboard | Chat Analytics{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div
|
<div
|
||||||
class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom"
|
class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom"
|
||||||
@ -42,30 +41,22 @@
|
|||||||
</button>
|
</button>
|
||||||
<ul class="dropdown-menu" aria-labelledby="timeRangeDropdown">
|
<ul class="dropdown-menu" aria-labelledby="timeRangeDropdown">
|
||||||
<li>
|
<li>
|
||||||
<a
|
<a class="dropdown-item" href="?dashboard_id={{ selected_dashboard.id }}&time_range=7"
|
||||||
class="dropdown-item"
|
|
||||||
href="?dashboard_id={{ selected_dashboard.id }}&time_range=7"
|
|
||||||
>Last 7 days</a
|
>Last 7 days</a
|
||||||
>
|
>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a
|
<a class="dropdown-item" href="?dashboard_id={{ selected_dashboard.id }}&time_range=30"
|
||||||
class="dropdown-item"
|
|
||||||
href="?dashboard_id={{ selected_dashboard.id }}&time_range=30"
|
|
||||||
>Last 30 days</a
|
>Last 30 days</a
|
||||||
>
|
>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a
|
<a class="dropdown-item" href="?dashboard_id={{ selected_dashboard.id }}&time_range=90"
|
||||||
class="dropdown-item"
|
|
||||||
href="?dashboard_id={{ selected_dashboard.id }}&time_range=90"
|
|
||||||
>Last 90 days</a
|
>Last 90 days</a
|
||||||
>
|
>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a
|
<a class="dropdown-item" href="?dashboard_id={{ selected_dashboard.id }}&time_range=all"
|
||||||
class="dropdown-item"
|
|
||||||
href="?dashboard_id={{ selected_dashboard.id }}&time_range=all"
|
|
||||||
>All time</a
|
>All time</a
|
||||||
>
|
>
|
||||||
</li>
|
</li>
|
||||||
@ -159,30 +150,31 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block extra_js %}
|
{% block extra_js %}
|
||||||
<!-- prettier-ignore-start -->
|
<!-- prettier-ignore-start -->
|
||||||
<!-- Store the JSON data in script tags to avoid parsing issues -->
|
<!-- Store the JSON data in script tags to avoid parsing issues -->
|
||||||
<script type="application/json" id="time-series-data">{{ time_series_data_json|safe }}</script>
|
<script type="application/json" id="time-series-data">
|
||||||
<script type="application/json" id="sentiment-data">{{ sentiment_data_json|safe }}</script>
|
{{ time_series_data_json|safe }}
|
||||||
<script type="application/json" id="country-data">{{ country_data_json|safe }}</script>
|
</script>
|
||||||
<script type="application/json" id="category-data">{{ category_data_json|safe }}</script>
|
<script type="application/json" id="sentiment-data">
|
||||||
|
{{ sentiment_data_json|safe }}
|
||||||
|
</script>
|
||||||
|
<script type="application/json" id="country-data">
|
||||||
|
{{ country_data_json|safe }}
|
||||||
|
</script>
|
||||||
|
<script type="application/json" id="category-data">
|
||||||
|
{{ category_data_json|safe }}
|
||||||
|
</script>
|
||||||
<!-- prettier-ignore-end -->
|
<!-- prettier-ignore-end -->
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
document.addEventListener("DOMContentLoaded", function () {
|
document.addEventListener("DOMContentLoaded", function () {
|
||||||
try {
|
try {
|
||||||
// Parse the dashboard data components from script tags
|
// Parse the dashboard data components from script tags
|
||||||
const timeSeriesData = JSON.parse(
|
const timeSeriesData = JSON.parse(document.getElementById("time-series-data").textContent);
|
||||||
document.getElementById("time-series-data").textContent,
|
const sentimentData = JSON.parse(document.getElementById("sentiment-data").textContent);
|
||||||
);
|
|
||||||
const sentimentData = JSON.parse(
|
|
||||||
document.getElementById("sentiment-data").textContent,
|
|
||||||
);
|
|
||||||
const countryData = JSON.parse(document.getElementById("country-data").textContent);
|
const countryData = JSON.parse(document.getElementById("country-data").textContent);
|
||||||
const categoryData = JSON.parse(
|
const categoryData = JSON.parse(document.getElementById("category-data").textContent);
|
||||||
document.getElementById("category-data").textContent,
|
|
||||||
);
|
|
||||||
|
|
||||||
console.log("Time series data loaded:", timeSeriesData);
|
console.log("Time series data loaded:", timeSeriesData);
|
||||||
console.log("Sentiment data loaded:", sentimentData);
|
console.log("Sentiment data loaded:", sentimentData);
|
||||||
@ -233,8 +225,7 @@
|
|||||||
const sentimentValues = sentimentData.map((item) => item.count);
|
const sentimentValues = sentimentData.map((item) => item.count);
|
||||||
const sentimentColors = sentimentLabels.map((sentiment) => {
|
const sentimentColors = sentimentLabels.map((sentiment) => {
|
||||||
if (sentiment.toLowerCase().includes("positive")) return "rgb(75, 192, 92)";
|
if (sentiment.toLowerCase().includes("positive")) return "rgb(75, 192, 92)";
|
||||||
if (sentiment.toLowerCase().includes("negative"))
|
if (sentiment.toLowerCase().includes("negative")) return "rgb(255, 99, 132)";
|
||||||
return "rgb(255, 99, 132)";
|
|
||||||
if (sentiment.toLowerCase().includes("neutral")) return "rgb(255, 205, 86)";
|
if (sentiment.toLowerCase().includes("neutral")) return "rgb(255, 205, 86)";
|
||||||
return "rgb(201, 203, 207)";
|
return "rgb(201, 203, 207)";
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,7 +1,4 @@
|
|||||||
{% extends 'base.html' %}
|
{% extends 'base.html' %} {% block title %}Delete Dashboard | Chat Analytics{% endblock %}
|
||||||
|
|
||||||
{% block title %}Delete Dashboard | Chat Analytics{% endblock %}
|
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div
|
<div
|
||||||
class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom"
|
class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom"
|
||||||
@ -22,12 +19,11 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<p class="lead">
|
<p class="lead">
|
||||||
Are you sure you want to delete the dashboard
|
Are you sure you want to delete the dashboard "<strong>{{ dashboard.name }}</strong>"?
|
||||||
"<strong>{{ dashboard.name }}</strong>"?
|
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
This action cannot be undone. The dashboard will be permanently deleted, but
|
This action cannot be undone. The dashboard will be permanently deleted, but the
|
||||||
the underlying data sources will remain intact.
|
underlying data sources will remain intact.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<form method="post">
|
<form method="post">
|
||||||
|
|||||||
@ -1,11 +1,12 @@
|
|||||||
{% extends 'base.html' %}
|
{% extends 'base.html' %} {% load crispy_forms_tags %}
|
||||||
{% load crispy_forms_tags %}
|
|
||||||
|
|
||||||
{% block title %}
|
{% block title %}
|
||||||
{% if is_create %}Create Dashboard{% else %}Edit Dashboard{% endif %}
|
{% if is_create %}
|
||||||
|
Create Dashboard
|
||||||
|
{% else %}
|
||||||
|
Edit Dashboard
|
||||||
|
{% endif %}
|
||||||
| Chat Analytics
|
| Chat Analytics
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div
|
<div
|
||||||
class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom"
|
class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom"
|
||||||
@ -28,8 +29,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<form method="post">
|
<form method="post">
|
||||||
{% csrf_token %}
|
{% csrf_token %} {{ form|crispy }}
|
||||||
{{ form|crispy }}
|
|
||||||
<div class="d-grid gap-2">
|
<div class="d-grid gap-2">
|
||||||
<button type="submit" class="btn btn-primary">
|
<button type="submit" class="btn btn-primary">
|
||||||
{% if is_create %}Create Dashboard{% else %}Update Dashboard{% endif %}
|
{% if is_create %}Create Dashboard{% else %}Update Dashboard{% endif %}
|
||||||
|
|||||||
@ -1,8 +1,5 @@
|
|||||||
<!-- templates/dashboard/data_source_confirm_delete.html -->
|
<!-- templates/dashboard/data_source_confirm_delete.html -->
|
||||||
{% extends 'base.html' %}
|
{% extends 'base.html' %} {% block title %}Delete Data Source | Chat Analytics{% endblock %}
|
||||||
|
|
||||||
{% block title %}Delete Data Source | Chat Analytics{% endblock %}
|
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div
|
<div
|
||||||
class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom"
|
class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom"
|
||||||
@ -30,17 +27,14 @@
|
|||||||
"<strong>{{ data_source.name }}</strong>"?
|
"<strong>{{ data_source.name }}</strong>"?
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
This action cannot be undone. The data source and all associated chat
|
This action cannot be undone. The data source and all associated chat sessions
|
||||||
sessions ({{ data_source.chat_sessions.count }} sessions) will be
|
({{ data_source.chat_sessions.count }} sessions) will be permanently deleted.
|
||||||
permanently deleted.
|
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<form method="post">
|
<form method="post">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
<div class="d-flex justify-content-between mt-4">
|
<div class="d-flex justify-content-between mt-4">
|
||||||
<a
|
<a href="{% url 'data_source_detail' data_source.id %}" class="btn btn-secondary"
|
||||||
href="{% url 'data_source_detail' data_source.id %}"
|
|
||||||
class="btn btn-secondary"
|
|
||||||
>Cancel</a
|
>Cancel</a
|
||||||
>
|
>
|
||||||
<button type="submit" class="btn btn-danger">Delete Data Source</button>
|
<button type="submit" class="btn btn-danger">Delete Data Source</button>
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
<!-- templates/dashboard/data_source_detail.html -->
|
<!-- templates/dashboard/data_source_detail.html -->
|
||||||
{% extends 'base.html' %}
|
{% extends 'base.html' %} {% load dashboard_extras %}
|
||||||
{% load dashboard_extras %}
|
{% block title %}
|
||||||
|
{{ data_source.name }}
|
||||||
{% block title %}{{ data_source.name }} | Chat Analytics{% endblock %}
|
| Chat Analytics
|
||||||
|
{% endblock %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div
|
<div
|
||||||
class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom"
|
class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom"
|
||||||
@ -19,10 +19,7 @@
|
|||||||
>
|
>
|
||||||
<i class="fas fa-file-csv"></i> Export CSV
|
<i class="fas fa-file-csv"></i> Export CSV
|
||||||
</a>
|
</a>
|
||||||
<a
|
<a href="{% url 'delete_data_source' data_source.id %}" class="btn btn-sm btn-outline-danger">
|
||||||
href="{% url 'delete_data_source' data_source.id %}"
|
|
||||||
class="btn btn-sm btn-outline-danger"
|
|
||||||
>
|
|
||||||
<i class="fas fa-trash"></i> Delete
|
<i class="fas fa-trash"></i> Delete
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
@ -68,11 +65,7 @@
|
|||||||
placeholder="Search sessions..."
|
placeholder="Search sessions..."
|
||||||
aria-label="Search sessions"
|
aria-label="Search sessions"
|
||||||
/>
|
/>
|
||||||
<input
|
<input type="hidden" name="data_source_id" value="{{ data_source.id }}" />
|
||||||
type="hidden"
|
|
||||||
name="data_source_id"
|
|
||||||
value="{{ data_source.id }}"
|
|
||||||
/>
|
|
||||||
<button class="btn btn-outline-primary" type="submit">
|
<button class="btn btn-outline-primary" type="submit">
|
||||||
<i class="fas fa-search"></i>
|
<i class="fas fa-search"></i>
|
||||||
</button>
|
</button>
|
||||||
@ -115,21 +108,13 @@
|
|||||||
<td>
|
<td>
|
||||||
{% if session.sentiment %}
|
{% if session.sentiment %}
|
||||||
{% if 'positive' in session.sentiment|lower %}
|
{% if 'positive' in session.sentiment|lower %}
|
||||||
<span class="badge bg-success"
|
<span class="badge bg-success">{{ session.sentiment }}</span>
|
||||||
>{{ session.sentiment }}</span
|
|
||||||
>
|
|
||||||
{% elif 'negative' in session.sentiment|lower %}
|
{% elif 'negative' in session.sentiment|lower %}
|
||||||
<span class="badge bg-danger"
|
<span class="badge bg-danger">{{ session.sentiment }}</span>
|
||||||
>{{ session.sentiment }}</span
|
|
||||||
>
|
|
||||||
{% elif 'neutral' in session.sentiment|lower %}
|
{% elif 'neutral' in session.sentiment|lower %}
|
||||||
<span class="badge bg-warning"
|
<span class="badge bg-warning">{{ session.sentiment }}</span>
|
||||||
>{{ session.sentiment }}</span
|
|
||||||
>
|
|
||||||
{% else %}
|
{% else %}
|
||||||
<span class="badge bg-secondary"
|
<span class="badge bg-secondary">{{ session.sentiment }}</span>
|
||||||
>{{ session.sentiment }}</span
|
|
||||||
>
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% else %}
|
{% else %}
|
||||||
<span class="text-muted">N/A</span>
|
<span class="text-muted">N/A</span>
|
||||||
@ -147,10 +132,7 @@
|
|||||||
<i class="fas fa-eye"></i>
|
<i class="fas fa-eye"></i>
|
||||||
</a>
|
</a>
|
||||||
{% else %}
|
{% else %}
|
||||||
<button
|
<button class="btn btn-sm btn-outline-secondary" disabled>
|
||||||
class="btn btn-sm btn-outline-secondary"
|
|
||||||
disabled
|
|
||||||
>
|
|
||||||
<i class="fas fa-eye-slash"></i>
|
<i class="fas fa-eye-slash"></i>
|
||||||
</button>
|
</button>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
@ -158,9 +140,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
{% empty %}
|
{% empty %}
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="9" class="text-center">
|
<td colspan="9" class="text-center">No chat sessions found.</td>
|
||||||
No chat sessions found.
|
|
||||||
</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
@ -197,23 +177,17 @@
|
|||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% for num in page_obj.paginator.page_range %}
|
{% for num in page_obj.paginator.page_range %}
|
||||||
{% if page_obj.number == num %}
|
{% if page_obj.number == num %}
|
||||||
<li class="page-item active">
|
<li class="page-item active">
|
||||||
<a class="page-link" href="?page={{ num }}"
|
<a class="page-link" href="?page={{ num }}">{{ num }}</a>
|
||||||
>{{ num }}</a
|
|
||||||
>
|
|
||||||
</li>
|
</li>
|
||||||
{% elif num > page_obj.number|add:'-3' and num < page_obj.number|add:'3' %}
|
{% elif num > page_obj.number|add:'-3' and num < page_obj.number|add:'3' %}
|
||||||
<li class="page-item">
|
<li class="page-item">
|
||||||
<a class="page-link" href="?page={{ num }}"
|
<a class="page-link" href="?page={{ num }}">{{ num }}</a>
|
||||||
>{{ num }}</a
|
|
||||||
>
|
|
||||||
</li>
|
</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|
||||||
{% if page_obj.has_next %}
|
{% if page_obj.has_next %}
|
||||||
<li class="page-item">
|
<li class="page-item">
|
||||||
<a
|
<a
|
||||||
|
|||||||
@ -1,9 +1,8 @@
|
|||||||
<!-- templates/dashboard/data_view.html -->
|
<!-- templates/dashboard/data_view.html -->
|
||||||
{% extends 'base.html' %}
|
{% extends 'base.html' %} {% load dashboard_extras %}
|
||||||
{% load dashboard_extras %}
|
{% block title %}
|
||||||
|
Data View | Chat Analytics
|
||||||
{% block title %}Data View | Chat Analytics{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div
|
<div
|
||||||
class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom"
|
class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom"
|
||||||
@ -11,10 +10,7 @@
|
|||||||
<h1 class="h2">Data View</h1>
|
<h1 class="h2">Data View</h1>
|
||||||
<div class="btn-toolbar mb-2 mb-md-0">
|
<div class="btn-toolbar mb-2 mb-md-0">
|
||||||
<div class="btn-group me-2">
|
<div class="btn-group me-2">
|
||||||
<a
|
<a href="{% url 'dashboard' %}" class="btn btn-sm btn-outline-secondary ajax-nav-link">
|
||||||
href="{% url 'dashboard' %}"
|
|
||||||
class="btn btn-sm btn-outline-secondary ajax-nav-link"
|
|
||||||
>
|
|
||||||
<i class="fas fa-arrow-left"></i> Back to Dashboard
|
<i class="fas fa-arrow-left"></i> Back to Dashboard
|
||||||
</a>
|
</a>
|
||||||
{% if selected_data_source %}
|
{% if selected_data_source %}
|
||||||
@ -41,24 +37,16 @@
|
|||||||
<a class="dropdown-item ajax-nav-link" href="?view=all">All Sessions</a>
|
<a class="dropdown-item ajax-nav-link" href="?view=all">All Sessions</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a class="dropdown-item ajax-nav-link" href="?view=recent"
|
<a class="dropdown-item ajax-nav-link" href="?view=recent">Recent Sessions</a>
|
||||||
>Recent Sessions</a
|
|
||||||
>
|
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a class="dropdown-item ajax-nav-link" href="?view=positive"
|
<a class="dropdown-item ajax-nav-link" href="?view=positive">Positive Sentiment</a>
|
||||||
>Positive Sentiment</a
|
|
||||||
>
|
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a class="dropdown-item ajax-nav-link" href="?view=negative"
|
<a class="dropdown-item ajax-nav-link" href="?view=negative">Negative Sentiment</a>
|
||||||
>Negative Sentiment</a
|
|
||||||
>
|
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a class="dropdown-item ajax-nav-link" href="?view=escalated"
|
<a class="dropdown-item ajax-nav-link" href="?view=escalated">Escalated Sessions</a>
|
||||||
>Escalated Sessions</a
|
|
||||||
>
|
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
@ -75,16 +63,14 @@
|
|||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<form method="get" class="row g-3 align-items-center filter-form">
|
<form method="get" class="row g-3 align-items-center filter-form">
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<select
|
<select name="data_source_id" class="form-select" aria-label="Select Data Source">
|
||||||
name="data_source_id"
|
|
||||||
class="form-select"
|
|
||||||
aria-label="Select Data Source"
|
|
||||||
>
|
|
||||||
<option value="">All Data Sources</option>
|
<option value="">All Data Sources</option>
|
||||||
{% for ds in data_sources %}
|
{% for ds in data_sources %}
|
||||||
<option
|
<option
|
||||||
value="{{ ds.id }}"
|
value="{{ ds.id }}"
|
||||||
{% if selected_data_source.id == ds.id %}selected{% endif %}
|
{% if selected_data_source.id == ds.id %}
|
||||||
|
selected
|
||||||
|
{% endif %}
|
||||||
>
|
>
|
||||||
{{ ds.name }}
|
{{ ds.name }}
|
||||||
</option>
|
</option>
|
||||||
@ -93,28 +79,17 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="col-md-4">
|
<div class="col-md-4">
|
||||||
<select name="view" class="form-select" aria-label="Select View">
|
<select name="view" class="form-select" aria-label="Select View">
|
||||||
<option value="all" {% if view == 'all' %}selected{% endif %}>
|
<option value="all" {% if view == 'all' %}selected{% endif %}>All Sessions</option>
|
||||||
All Sessions
|
|
||||||
</option>
|
|
||||||
<option value="recent" {% if view == 'recent' %}selected{% endif %}>
|
<option value="recent" {% if view == 'recent' %}selected{% endif %}>
|
||||||
Recent Sessions
|
Recent Sessions
|
||||||
</option>
|
</option>
|
||||||
<option
|
<option value="positive" {% if view == 'positive' %}selected{% endif %}>
|
||||||
value="positive"
|
|
||||||
{% if view == 'positive' %}selected{% endif %}
|
|
||||||
>
|
|
||||||
Positive Sentiment
|
Positive Sentiment
|
||||||
</option>
|
</option>
|
||||||
<option
|
<option value="negative" {% if view == 'negative' %}selected{% endif %}>
|
||||||
value="negative"
|
|
||||||
{% if view == 'negative' %}selected{% endif %}
|
|
||||||
>
|
|
||||||
Negative Sentiment
|
Negative Sentiment
|
||||||
</option>
|
</option>
|
||||||
<option
|
<option value="escalated" {% if view == 'escalated' %}selected{% endif %}>
|
||||||
value="escalated"
|
|
||||||
{% if view == 'escalated' %}selected{% endif %}
|
|
||||||
>
|
|
||||||
Escalated Sessions
|
Escalated Sessions
|
||||||
</option>
|
</option>
|
||||||
</select>
|
</select>
|
||||||
@ -136,28 +111,14 @@
|
|||||||
<h5 class="card-title mb-0">Export Data</h5>
|
<h5 class="card-title mb-0">Export Data</h5>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<form
|
<form id="export-form" method="get" action="{% url 'export_chats_csv' %}" class="row g-3">
|
||||||
id="export-form"
|
|
||||||
method="get"
|
|
||||||
action="{% url 'export_chats_csv' %}"
|
|
||||||
class="row g-3"
|
|
||||||
>
|
|
||||||
<!-- Pass current filters to export -->
|
<!-- Pass current filters to export -->
|
||||||
<input
|
<input type="hidden" name="data_source_id" value="{{ selected_data_source.id }}" />
|
||||||
type="hidden"
|
|
||||||
name="data_source_id"
|
|
||||||
value="{{ selected_data_source.id }}"
|
|
||||||
/>
|
|
||||||
<input type="hidden" name="view" value="{{ view }}" />
|
<input type="hidden" name="view" value="{{ view }}" />
|
||||||
|
|
||||||
<div class="col-md-3">
|
<div class="col-md-3">
|
||||||
<label for="start_date" class="form-label">Start Date</label>
|
<label for="start_date" class="form-label">Start Date</label>
|
||||||
<input
|
<input type="date" name="start_date" id="start_date" class="form-control" />
|
||||||
type="date"
|
|
||||||
name="start_date"
|
|
||||||
id="start_date"
|
|
||||||
class="form-control"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-3">
|
<div class="col-md-3">
|
||||||
<label for="end_date" class="form-label">End Date</label>
|
<label for="end_date" class="form-label">End Date</label>
|
||||||
@ -211,9 +172,7 @@
|
|||||||
{% if selected_data_source %}
|
{% if selected_data_source %}
|
||||||
for {{ selected_data_source.name }}
|
for {{ selected_data_source.name }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if view != 'all' %}
|
{% if view != 'all' %}({{ view|title }}){% endif %}
|
||||||
({{ view|title }})
|
|
||||||
{% endif %}
|
|
||||||
</h5>
|
</h5>
|
||||||
<span class="badge bg-primary">{{ page_obj.paginator.count }} sessions</span>
|
<span class="badge bg-primary">{{ page_obj.paginator.count }} sessions</span>
|
||||||
</div>
|
</div>
|
||||||
@ -227,9 +186,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Data table container that will be updated via AJAX -->
|
<!-- Data table container that will be updated via AJAX -->
|
||||||
<div id="ajax-content-container">
|
<div id="ajax-content-container">{% include "dashboard/partials/data_table.html" %}</div>
|
||||||
{% include "dashboard/partials/data_table.html" %}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -288,7 +245,6 @@
|
|||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block extra_js %}
|
{% block extra_js %}
|
||||||
<script>
|
<script>
|
||||||
// Function to update the summary section with new data
|
// Function to update the summary section with new data
|
||||||
|
|||||||
@ -1,8 +1,5 @@
|
|||||||
<!-- templates/dashboard/no_company.html -->
|
<!-- templates/dashboard/no_company.html -->
|
||||||
{% extends 'base.html' %}
|
{% extends 'base.html' %} {% block title %}No Company | Chat Analytics{% endblock %}
|
||||||
|
|
||||||
{% block title %}No Company | Chat Analytics{% endblock %}
|
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div
|
<div
|
||||||
class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom"
|
class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom"
|
||||||
@ -20,22 +17,18 @@
|
|||||||
<div class="mb-4">
|
<div class="mb-4">
|
||||||
<i class="fas fa-building fa-4x text-warning mb-3"></i>
|
<i class="fas fa-building fa-4x text-warning mb-3"></i>
|
||||||
<h4>You are not currently associated with any company</h4>
|
<h4>You are not currently associated with any company</h4>
|
||||||
<p class="lead">
|
<p class="lead">You need to be associated with a company to access the dashboard.</p>
|
||||||
You need to be associated with a company to access the dashboard.
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
Please contact an administrator to have your account assigned to a company.
|
Please contact an administrator to have your account assigned to a company. Once your
|
||||||
Once your account is associated with a company, you'll be able to access the
|
account is associated with a company, you'll be able to access the dashboard and its
|
||||||
dashboard and its features.
|
features.
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div class="mt-4">
|
<div class="mt-4">
|
||||||
<a href="{% url 'profile' %}" class="btn btn-primary">View Your Profile</a>
|
<a href="{% url 'profile' %}" class="btn btn-primary">View Your Profile</a>
|
||||||
<a href="{% url 'logout' %}" class="btn btn-outline-secondary ms-2"
|
<a href="{% url 'logout' %}" class="btn btn-outline-secondary ms-2">Logout</a>
|
||||||
>Logout</a
|
|
||||||
>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -99,9 +99,7 @@
|
|||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% for num in page_obj.paginator.page_range %}{% if page_obj.number == num %}
|
||||||
{% for num in page_obj.paginator.page_range %}
|
|
||||||
{% if page_obj.number == num %}
|
|
||||||
<li class="page-item active">
|
<li class="page-item active">
|
||||||
<a
|
<a
|
||||||
class="page-link pagination-link"
|
class="page-link pagination-link"
|
||||||
@ -119,9 +117,7 @@
|
|||||||
>{{ num }}</a
|
>{{ num }}</a
|
||||||
>
|
>
|
||||||
</li>
|
</li>
|
||||||
{% endif %}
|
{% endif %}{% endfor %}
|
||||||
{% endfor %}
|
|
||||||
|
|
||||||
{% if page_obj.has_next %}
|
{% if page_obj.has_next %}
|
||||||
<li class="page-item">
|
<li class="page-item">
|
||||||
<a
|
<a
|
||||||
|
|||||||
@ -20,9 +20,7 @@
|
|||||||
<td>{{ session.session_id|truncatechars:10 }}</td>
|
<td>{{ session.session_id|truncatechars:10 }}</td>
|
||||||
<td>{{ session.start_time|date:"M d, Y H:i" }}</td>
|
<td>{{ session.start_time|date:"M d, Y H:i" }}</td>
|
||||||
<td>
|
<td>
|
||||||
<a
|
<a href="{% url 'data_source_detail' session.data_source.id %}" class="ajax-nav-link"
|
||||||
href="{% url 'data_source_detail' session.data_source.id %}"
|
|
||||||
class="ajax-nav-link"
|
|
||||||
>{{ session.data_source.name|truncatechars:15 }}</a
|
>{{ session.data_source.name|truncatechars:15 }}</a
|
||||||
>
|
>
|
||||||
</td>
|
</td>
|
||||||
@ -62,9 +60,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
{% empty %}
|
{% empty %}
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="9" class="text-center">
|
<td colspan="9" class="text-center">No chat sessions found matching your criteria.</td>
|
||||||
No chat sessions found matching your criteria.
|
|
||||||
</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
@ -107,9 +103,7 @@
|
|||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% for num in page_obj.paginator.page_range %}{% if page_obj.number == num %}
|
||||||
{% for num in page_obj.paginator.page_range %}
|
|
||||||
{% if page_obj.number == num %}
|
|
||||||
<li class="page-item active">
|
<li class="page-item active">
|
||||||
<a
|
<a
|
||||||
class="page-link pagination-link"
|
class="page-link pagination-link"
|
||||||
@ -127,9 +121,7 @@
|
|||||||
>{{ num }}</a
|
>{{ num }}</a
|
||||||
>
|
>
|
||||||
</li>
|
</li>
|
||||||
{% endif %}
|
{% endif %}{% endfor %}
|
||||||
{% endfor %}
|
|
||||||
|
|
||||||
{% if page_obj.has_next %}
|
{% if page_obj.has_next %}
|
||||||
<li class="page-item">
|
<li class="page-item">
|
||||||
<a
|
<a
|
||||||
|
|||||||
@ -1,8 +1,5 @@
|
|||||||
<!-- templates/dashboard/search_results.html -->
|
<!-- templates/dashboard/search_results.html -->
|
||||||
{% extends 'base.html' %}
|
{% extends 'base.html' %} {% block title %}Search Results | Chat Analytics{% endblock %}
|
||||||
|
|
||||||
{% block title %}Search Results | Chat Analytics{% endblock %}
|
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div
|
<div
|
||||||
class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom"
|
class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom"
|
||||||
@ -22,11 +19,7 @@
|
|||||||
<h5 class="card-title mb-0">Search Chat Sessions</h5>
|
<h5 class="card-title mb-0">Search Chat Sessions</h5>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<form
|
<form method="get" action="{% url 'search_chat_sessions' %}" class="search-form">
|
||||||
method="get"
|
|
||||||
action="{% url 'search_chat_sessions' %}"
|
|
||||||
class="search-form"
|
|
||||||
>
|
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
@ -37,11 +30,7 @@
|
|||||||
aria-label="Search sessions"
|
aria-label="Search sessions"
|
||||||
/>
|
/>
|
||||||
{% if data_source %}
|
{% if data_source %}
|
||||||
<input
|
<input type="hidden" name="data_source_id" value="{{ data_source.id }}" />
|
||||||
type="hidden"
|
|
||||||
name="data_source_id"
|
|
||||||
value="{{ data_source.id }}"
|
|
||||||
/>
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<button class="btn btn-outline-primary" type="submit">
|
<button class="btn btn-outline-primary" type="submit">
|
||||||
<i class="fas fa-search"></i> Search
|
<i class="fas fa-search"></i> Search
|
||||||
@ -49,8 +38,8 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="mt-2 text-muted">
|
<div class="mt-2 text-muted">
|
||||||
<small
|
<small
|
||||||
>Search by session ID, country, language, sentiment, category, or
|
>Search by session ID, country, language, sentiment, category, or message
|
||||||
message content.</small
|
content.</small
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
@ -87,7 +76,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block extra_js %}
|
{% block extra_js %}
|
||||||
<!-- No need for extra JavaScript here, using common ajax-pagination.js -->
|
<!-- No need for extra JavaScript here, using common ajax-pagination.js -->
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|||||||
@ -1,10 +1,8 @@
|
|||||||
<!-- templates/dashboard/upload.html -->
|
<!-- templates/dashboard/upload.html -->
|
||||||
{% extends 'base.html' %}
|
{% extends 'base.html' %} {% load crispy_forms_tags %} {% load dashboard_extras %}
|
||||||
{% load crispy_forms_tags %}
|
{% block title %}
|
||||||
{% load dashboard_extras %}
|
Upload Data | Chat Analytics
|
||||||
|
{% endblock %}
|
||||||
{% block title %}Upload Data | Chat Analytics{% endblock %}
|
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div
|
<div
|
||||||
class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom"
|
class="d-flex justify-content-between flex-wrap flex-md-nowrap align-items-center pt-3 pb-2 mb-3 border-bottom"
|
||||||
|
|||||||
11
package.json
11
package.json
@ -1,15 +1,4 @@
|
|||||||
{
|
{
|
||||||
"name": "livegraphsdjango",
|
|
||||||
"version": "0.1.0",
|
|
||||||
"description": "Live Graphs Django Dashboard",
|
|
||||||
"private": true,
|
|
||||||
"scripts": {
|
|
||||||
"lint": "eslint dashboard_project/static/js/",
|
|
||||||
"format": "prettier --write \"dashboard_project/static/**/*.{js,css,html}\"",
|
|
||||||
"format:check": "prettier --check \"dashboard_project/static/**/*.{js,css,html}\"",
|
|
||||||
"stylelint": "stylelint \"dashboard_project/static/css/**/*.css\" --fix",
|
|
||||||
"stylelint:check": "stylelint \"dashboard_project/static/css/**/*.css\""
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"prettier": "^3.5.3",
|
"prettier": "^3.5.3",
|
||||||
"prettier-plugin-jinja-template": "^2.1.0"
|
"prettier-plugin-jinja-template": "^2.1.0"
|
||||||
|
|||||||
Reference in New Issue
Block a user