Skip to content

Commit

Permalink
btstr table is changed
Browse files Browse the repository at this point in the history
  • Loading branch information
MarinaProsche committed May 5, 2024
1 parent 13f9aac commit 98168da
Show file tree
Hide file tree
Showing 5 changed files with 242 additions and 41 deletions.
29 changes: 22 additions & 7 deletions app/routes/users.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@ def my_wrapper(*args, **kwargs):
abort(403)
return my_wrapper



@users.route("/data")
@admin_required
def users_data():
Expand All @@ -37,7 +35,22 @@ def users_data():
if f_name := filters.get("name", None):
filter_query["name"] = {"$regex": f_name}


if f_formats := filters.get("all_formats", None):
filter_query["formats"] = {"$regex": f_formats}

if f_criteria := filters.get("all_criteria", None):
filter_query["criteria"] = {"$regex": f_criteria}

if f_check_counts := filters.get("check_counts", None):
try:
f_check_counts_value, f_check_counts_cond = int(f_check_counts.split()[1]), f_check_counts.split()[0]
if f_check_counts_cond == '>':
filter_query["$expr"] = {"$gte": [{"$size": "$presentations"}, f_check_counts_value]}
elif f_check_counts_cond == "<":
filter_query["$expr"] = {"$lte": [{"$size": "$presentations"}, f_check_counts_value]}
except ValueError:
pass

limit = request.args.get("limit", "")
limit = int(limit) if limit.isnumeric() else 10

Expand All @@ -57,6 +70,10 @@ def users_data():
"rows": [{
"username": item["username"],
"name": item["name"],
"all_formats": item["formats"],
"all_criteria": item["criteria"],
"check_counts": len(item["presentations"]),

} for item in rows]
}
return jsonify(response)
Expand All @@ -65,12 +82,10 @@ def users_data():
@users.route('/', methods=["GET"])
@admin_required
def index():
users = list(get_all_users())
usernames = [(user['name'], user['username']) for user in users]
return render_template('user_list.html', usernames=usernames)
return render_template('user_list.html')

@users.route('/<username>', methods=["GET"])
@admin_required
def user_info(username):
user_info = get_user(username)
return render_template('one_user_info.html', user_info=user_info, check_counts = len(user_info.presentations))
return render_template('one_user_info.html', user_info=user_info)
83 changes: 49 additions & 34 deletions app/templates/one_user_info.html
Original file line number Diff line number Diff line change
@@ -1,50 +1,65 @@
{# Accepts: header dependicies, results, id, filename #}


{% extends "root.html" %}

{% block title %}Информация о пользователе{% endblock %}
{% block title %}Информация о пользователях{% endblock %}

{% block main %}
<style>
.fht-cell {
margin: 0 0.2rem 0.2rem;
}

/* .user-list-table th td { border: #54585d; } */

#user-list-table {
table-layout: fixed;
word-wrap: break-word;
}

#user-list-table.table-bordered,
#user-list-table.table-bordered > thead > tr > th,
#user-list-table.table-bordered > tbody > tr > td {
border: 1px solid #a1a1a1;
}
</style>

<div class="header row">{% include "header.html" %}</div>
<div>
<h3 id="results_title" class="texteous ins">
Информация о пользователе {{ user_info.username }}:
<div class="holder row">
<div class="container-fluid table-responsive-xl">
<h3 id="user_title" class="texteous ins">
Страница пользователя: <b>{{ user_info.username }}</b>
</h3>
<table class="table table-striped table-hover" id="results_table">
<a href="{{ url_for('check_list', filter_user=user_info.username) }}"
class="col text-center link">Список всех загрузок пользователя</a>
<table id="one-user-table" class="table bg-white"
data-filter-control="true"
data-pagination="true"
data-page-list="[5, 10, 25, 50, All]"
data-ajax="ajaxRequest"
data-query-params="queryParams"
data-show-refresh="false"
data-auto-refresh="true"
data-auto-refresh-interval="10"
data-show-auto-refresh="false"
data-side-pagination="server"
data-icon-size="lg"
data-buttons="buttons"
data-show-filter-control-switch="true"
data-show-button-icons="false"
data-show-button-text="true">
<thead>
<tr>
<th><button id="showAllVerdicts" class="btn btn-default btn-xs"><i
class="bi bi-chevron-double-down"></i></button></th>
<th scope="col">Username</th>
<th scope="col">Name</th>
<th scope="col">Formats</th>
<th scope="col">criteria</th>
<th scope="'col">count of check</th>
<th data-field="username" data-filter-control="input" data-sortable="true">Username</th>
<th data-field="name" data-filter-control="input" data-sortable="true">Name</th>
<th data-field="all_formats" data-filter-control="input" data-sortable="true">Formats</th>
<th data-field="all_criteria" data-filter-control="input" data-sortable="true">Criteria</th>
<th data-field="check_counts" data-filter-control="input" data-sortable="true" title="insert operator and value with space (f.e > 1000)">Count of checks</th>
</tr>
</thead>
<tbody>
<tr data-toggle="collapse" data-target="#verd{{ user_info.username }}" class="accordion-toggle">
<td>
<button class="btn btn-default btn-xs"><i class="bi bi-chevron-double-down"></i></button>
</td>
<th scope="row" class="ins">{{ user_info.username }}</th>
<td class="ins">{{ user_info.name }}</td>
<td class="ins">{{ user_info.criteria }}</td>
<td class="ins">{{ user_info.formats }}</td>
<td class="ins">{{ check_counts}}</td>
</tr>
<tr>
<td colspan="6" class="hiddenRow">
<div id="verd{{ user_info.username }}" class="accordian-body collapse" style="margin-left: 2em;">
<a href="{{ url_for('check_list', filter_user=user_info.username) }}"
class="col text-center link">Список всех загрузок пользователя</a>
</div>
</td>
</tr>

</tbody>
</table>
</div>
</div>

{% endblock %}
{% endblock main %}
3 changes: 3 additions & 0 deletions app/templates/user_list.html
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ <h3 id="user_title" class="texteous ins">
<tr>
<th data-field="username" data-filter-control="input" data-sortable="true">Username</th>
<th data-field="name" data-filter-control="input" data-sortable="true">Name</th>
<th data-field="all_formats" data-filter-control="input" data-sortable="true">Formats</th>
<th data-field="all_criteria" data-filter-control="input" data-sortable="true">Criteria</th>
<th data-field="check_counts" data-filter-control="input" data-sortable="true" title="insert operator and value with space (f.e > 1000)">Count of checks</th>
</tr>
</thead>
</table>
Expand Down
1 change: 1 addition & 0 deletions assets/scripts/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import './check_list';
import './logs';
import './admin_criterions';
import './user_list';
import './one_user_info'

import '../favicon.ico';
import '../styles/404.css';
Expand Down
167 changes: 167 additions & 0 deletions assets/scripts/one_user_info.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
import { debounce, isFloat, resetTable, ajaxRequest, onPopState } from "./utils"

let $table;
const AJAX_URL = "/users/data"
let debounceInterval = 500;


String.prototype.insert = function (index, string) {
if (index > 0) {
return this.substring(0, index) + string + this.substr(index)
}
return string + this
}


$(() => {
initTable()
window.onpopstate = onPopState

const $dataFilter = $(".bootstrap-table-filter-control-result")
$dataFilter.on("keypress", (e) => {
const val = $dataFilter.val()
const numbers = val.split("-")

if (e.key === ".") {
const carret = $dataFilter[0].selectionStart
let expectedStr
if (carret <= numbers[0].length) {
expectedStr = numbers[0].insert(carret, ".")
} else {
expectedStr = numbers[1].insert(carret - numbers[0].length - 1, ".")
}

if (isFloat(expectedStr)) {
return
}
}

if (e.key >= "0" && e.key <= "9") {
return
}

if (e.key === "-") {
if (numbers.length === 1) {
return
}
}

e.preventDefault()
})
})


function initTable() {
$table = $("#one-user-table");

// get query string
const queryString = window.location.search;

// parse query search to js object
const params = Object.fromEntries(new URLSearchParams(queryString).entries())

// check correct order query
if (params.order !== "asc" && params.order !== "desc" && params.order !== "") {
params.order = ""
}

// check correct sort query
if (params.sort !== "") {
let match = false
$table.find("th[data-sortable='true']").each(function () {
if ($(this).data("field") === params.sort) {
match = true
return false
}
})

if (match === false) {
params.sort = ""
}
}


// check pair of sort and order
if ([params.sort, params.order].includes("")) {
params.sort = ""
params.order = ""
}

// Fill filters
$table.on("created-controls.bs.table", function () {
if (params.filter) {
params.filter = JSON.parse(decodeURI(params.filter))
for (const [key, value] of Object.entries(params.filter)) {
const $input = $(`.bootstrap-table-filter-control-${key}`)
$input.val(value)
}
}
})

// activate bs table
$table.bootstrapTable({
pageNumber: parseInt(params.page) || 1,
pageSize: parseInt(params.size) || 10,
sortName: params.sort,
sortOrder: params.order,
buttons: buttons,
detailView: true,
detailViewIcon: false,
detailViewByClick: true,
detailFormatter: detailFormatter,

queryParams: queryParams,
ajax: debouncedAjaxRequest,
})
}

// debounced ajax calls.
const debouncedAjaxRequest = debounce(function(params) {ajaxRequest(AJAX_URL, params)}, debounceInterval);


function queryParams(params) {
let filters = {}
$('.filter-control').each(function () {
const name = $(this).parents("th").data("field")
const val = this.querySelector("input").value
if (val) {
filters[name] = val
}
})

const query = {
limit: params.limit,
offset: params.offset,
sort: params.sort,
order: params.order,
}

if (!$.isEmptyObject(filters)) {
query.filter = JSON.stringify(filters)
}

return query
}


function buttons() {
let buttonsObj = {}

buttonsObj["ResetTable"] = {
text: 'Reset',
event: function() { resetTable($table, queryParams) }
}

return buttonsObj
}


function detailFormatter(index, row) {
var html = []
$.each(row, function (key, value) {
if (key === 'message' || key === 'pathname') {
html.push('<p><b>' + key + ':</b> ' + row[key] + '</p>')
}
})
return html.join('')
}

0 comments on commit 98168da

Please sign in to comment.