Merge pull request 'master' (#14) from master into prod

Reviewed-on: #14
This commit is contained in:
emmatveev 2024-12-08 15:17:34 +03:00
commit d756179afc
17 changed files with 251 additions and 4 deletions

View File

@ -48,7 +48,8 @@ INSTALLED_APPS = [
'web.apps.WebConfig',
'configs.apps.ConfigsConfig',
'experiments.apps.ExperimentsConfig',
'stats.apps.StatsConfig'
'stats.apps.StatsConfig',
'schemas.apps.SchemasConfig',
]
MIDDLEWARE = [

View File

@ -21,5 +21,6 @@ urlpatterns = [
path('configs/', include('configs.urls')),
path('experiments/', include('experiments.urls')),
path('stats/', include('stats.urls')),
path('schemas/', include('schemas.urls')),
path('', include('web.urls'))
]

0
schemas/__init__.py Normal file
View File

6
schemas/admin.py Normal file
View File

@ -0,0 +1,6 @@
from django.contrib import admin
# Register your models here.
from .models import Schema
admin.site.register(Schema)

6
schemas/apps.py Normal file
View File

@ -0,0 +1,6 @@
from django.apps import AppConfig
class SchemasConfig(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'schemas'

View File

@ -0,0 +1,28 @@
# Generated by Django 5.1.4 on 2024-12-08 11:56
import django.db.models.deletion
from django.db import migrations, models
class Migration(migrations.Migration):
initial = True
dependencies = [
('web', '0007_customuser_telegram_id_customuser_telegram_username'),
]
operations = [
migrations.CreateModel(
name='Schema',
fields=[
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.TextField()),
('data', models.BinaryField(blank=True, null=True)),
('project', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='web.project')),
],
options={
'indexes': [models.Index(fields=['project'], name='schemas_sch_project_18fee8_idx')],
},
),
]

View File

@ -0,0 +1,18 @@
# Generated by Django 5.1.4 on 2024-12-08 12:05
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('schemas', '0001_initial'),
]
operations = [
migrations.AlterField(
model_name='schema',
name='data',
field=models.TextField(blank=True, null=True),
),
]

View File

@ -0,0 +1,18 @@
# Generated by Django 5.1.4 on 2024-12-08 12:15
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('schemas', '0002_alter_schema_data'),
]
operations = [
migrations.AlterField(
model_name='schema',
name='data',
field=models.TextField(blank=True, default=''),
),
]

View File

14
schemas/models.py Normal file
View File

@ -0,0 +1,14 @@
from django.db import models
# Create your models here.
class Schema(models.Model):
project = models.ForeignKey('web.Project', on_delete=models.CASCADE)
name = models.TextField()
data = models.TextField(default='', blank=True)
class Meta:
indexes = [
models.Index(fields=['project'])
]

3
schemas/tests.py Normal file
View File

@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.

9
schemas/urls.py Normal file
View File

@ -0,0 +1,9 @@
from django.contrib import admin
from django.urls import path
from .views import *
urlpatterns = [
path(*SchemasView.as_path()),
path('get', get_schemas)
]

46
schemas/views.py Normal file
View File

@ -0,0 +1,46 @@
from json import loads
from django.http import HttpResponse, JsonResponse
from BaseLib.BaseView import BaseView
from BaseLib.configurator import *
from Platform import settings
from schemas.models import Schema
# Create your views here.
class SchemasView(BaseView):
required_login = True
endpoint = ''
view_file = 'schemas.html'
def pre_handle(self):
self.context['schemas'] = Schema.objects.filter(project=self.request.user.selected_project)
def post_create_schema(self):
Schema.objects.create(project=self.request.user.selected_project, name=self.request.POST['name'])
return '/schemas'
def post_delete(self):
Schema.objects.get(id=self.request.POST['schema']).delete()
return '/schemas'
def post_save(self):
schema = Schema.objects.get(id=self.request.POST['schema'])
schema.data = self.request.POST['data']
schema.save()
return '/schemas'
def get_schemas(request):
project = request.GET.get('project')
if project is None:
return HttpResponse('', status=400)
data = {
schema.name: schema.data
for schema in Schema.objects.filter(project__name=project)
}
return JsonResponse(data, safe=False)

View File

@ -98,6 +98,14 @@
<span class="sidebar-text">Статистика</span>
</a>
</li>
<li class="nav-item">
<a href="/schemas" class="nav-link">
<span class="sidebar-icon">
<i class="fa fa-file-code-o"></i>
</span>
<span class="sidebar-text">Схемы</span>
</a>
</li>
<li class="nav-item">
<button class="btn btn-secondary d-flex align-items-center justify-content-center btn-upgrade-pro">
{{ user.selected_project.name }}

61
templates/schemas.html Normal file
View File

@ -0,0 +1,61 @@
{% extends 'layouts/base.html' %}
{% block content %}
<h1>Схемы <button class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#create_config">+</button></h1>
<div class="modal fade" id="create_config" tabindex="-1" aria-labelledby="modal-default" style="display: none;" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<form method="POST">
{% csrf_token %}
<div class="modal-header">
<h2 class="h6 modal-title">Создать схему</h2>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<input type="text" name="name" placeholder="Имя файла" style="width: 100%;" />
</div>
<div class="modal-footer">
<button type="submit" name="action" value="create_schema" class="btn btn-secondary">Создать</button>
<button type="button" class="btn btn-link text-gray-600 ms-auto" data-bs-dismiss="modal">Закрыть</button>
</div>
</form>
</div>
</div>
</div>
<table class="table">
<thead>
<th>Название</th>
<th>Действие</th>
</thead>
<tbody>
{% for schema in schemas %}
<tr>
<td>{{ schema.name }}</td>
<td><button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#edit_{{ schema.id }}">Редактировать</button></td>
<div class="modal fade" id="edit_{{ schema.id }}" tabindex="-1" aria-labelledby="modal-default" style="display: none;" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<form method="POST">
{% csrf_token %}
<input type="hidden" name="schema" value="{{ schema.id }}" />
<div class="modal-header">
<h2 class="h6 modal-title">Редактировать схему {{ config.name }}</h2>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<textarea style="width: 100%; height: 800px;" name="data">{{ schema.data }}</textarea>
</div>
<div class="modal-footer">
<button type="submit" name="action" value="save" class="btn btn-secondary">Сохранить</button>
<button type="submit" name="action" value="delete" class="btn btn-danger" onclick="return confirm('Подтверди удаление. Это действие необратимо.');">Удалить</button>
<button type="button" class="btn btn-link text-gray-600 ms-auto" data-bs-dismiss="modal">Закрыть</button>
</div>
</form>
</div>
</div>
</div>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}

View File

@ -0,0 +1,28 @@
# Generated by Django 5.1.4 on 2024-12-08 12:05
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('web', '0007_customuser_telegram_id_customuser_telegram_username'),
]
operations = [
migrations.AlterField(
model_name='project',
name='next_stats_fetch_time',
field=models.DateTimeField(blank=True, null=True),
),
migrations.AlterField(
model_name='project',
name='stats_cron',
field=models.TextField(blank=True, null=True),
),
migrations.AlterField(
model_name='project',
name='stats_link',
field=models.TextField(blank=True, null=True),
),
]

View File

@ -3,10 +3,10 @@ from django.db import models
class Project(models.Model):
name = models.TextField()
stats_link = models.TextField(null=True)
stats_cron = models.TextField(null=True)
stats_link = models.TextField(null=True, blank=True)
stats_cron = models.TextField(null=True, blank=True)
stats_enabled = models.BooleanField(default=False)
next_stats_fetch_time = models.DateTimeField(null=True)
next_stats_fetch_time = models.DateTimeField(null=True, blank=True)
class Meta:
indexes = [