- Добавлено модальное окно редактирования номера
This commit is contained in:
Alexander Zhirov 2023-06-01 01:10:08 +03:00
parent cf3962d71d
commit c0290cd753
12 changed files with 294 additions and 128 deletions

View File

@ -1,100 +0,0 @@
class Message {
timer;
constructor() {
this.div = $('<div id="div-message"></div>');
this.div.css({
"position": "absolute",
"top": "10px",
"right": "20px",
"z-index": "1000"
});
$('body').append(this.div);
}
success(message, delay = 6000) {
this.print(message, delay, '#52b818', '#bffdc0');
}
warning(message, delay = 6000) {
this.print(message, delay, '#b8ae18', '#f8fdbf');
}
error(message, delay = 6000) {
this.print(message, delay, '#b96161', '#fddede');
}
print = function(message, delay, border, background) {
if (delay < 6000) delay = 6000;
let Timer = function(callback, delay) {
let timerId, start, remaining = delay;
this.pause = function() {
clearTimeout(timerId);
remaining -= new Date() - start;
};
this.resume = function() {
start = new Date();
clearTimeout(timerId);
timerId = setTimeout(callback, remaining);
};
this.dead = function() {
clearTimeout(timerId);
};
this.resume();
}
let newMessage = $(`<div class="message">${message}</div>`);
newMessage.css({
"border": `1px solid ${border}`,
"background-color": `${background}`,
"color": "#333",
"padding": "10px 30px",
"text-align": "center",
"display": "none",
"margin": "10px 0 0 0",
"width": "350px",
"opacity": "1",
"cursor": "pointer"
});
newMessage.hover(function(){
$(this).css({
"opacity": "1"
});
}, function(){
$(this).css({
"opacity": "0.3"
});
});
this.div.append(newMessage);
let opacityTimeout = setTimeout(function() {
newMessage.fadeTo(1000, 0.3);
}, 2500);
newMessage.fadeIn(500).mouseenter(() => {
clearTimeout(opacityTimeout);
this.timer.pause();
}).mouseleave(() => {
this.timer.resume();
}).click(() => {
this.timer.dead();
newMessage.fadeOut(0, function(){
this.remove();
});
});
this.timer = new Timer(() => {
newMessage.fadeOut(500, function(){
this.remove();
});
}, delay);
}
}

4
js/noticer.min.js vendored Normal file
View File

@ -0,0 +1,4 @@
/*! noticer - v0.1.0 - 2023-05-31
* https://git.zhirov.kz/alexander/noticer
* Copyright Alexander Zhirov; Licensed GPL-2.0 */
class Noticer{timer;constructor(){this.div=$('<div id="noticer"></div>'),this.div.css({position:"absolute",top:"10px",right:"20px","z-index":"1000"}),$("body").append(this.div)}success(e,t=6e3){this.print(e,t,"#52b818","#bffdc0")}warning(e,t=6e3){this.print(e,t,"#b8ae18","#f8fdbf")}error(e,t=6e3){this.print(e,t,"#b96161","#fddede")}print=function(e,t,n,s){t<6e3&&(t=6e3);let i=function(e,t){let n,s,o=t;this.pause=function(){clearTimeout(n),o-=new Date-s},this.resume=function(){s=new Date,clearTimeout(n),n=setTimeout(e,o)},this.dead=function(){clearTimeout(n)},this.resume()},o=$(`<div class="notice">${e}</div>`);o.css({border:`1px solid ${n}`,"background-color":`${s}`,color:"#333",padding:"10px 30px","text-align":"center",display:"none",margin:"10px 0 0 0",width:"350px",opacity:"1",cursor:"pointer"}),o.hover(function(){$(this).css({opacity:"1"})},function(){$(this).css({opacity:"0.3"})}),this.div.append(o);let a=setTimeout(function(){o.fadeTo(1e3,.3)},2500);o.fadeIn(500).mouseenter(()=>{clearTimeout(a),this.timer.pause()}).mouseleave(()=>{this.timer.resume()}).click(()=>{this.timer.dead(),o.fadeOut(0,function(){this.remove()})}),this.timer=new i(()=>{o.fadeOut(500,function(){this.remove()})},t)}}

View File

@ -1,7 +1,7 @@
var numbers = []; var numbers = [];
$(document).ready(function () { $(document).ready(function () {
message = new Message; noticer = new Noticer;
$("button").button(); $("button").button();
$("#tabs").tabs(); $("#tabs").tabs();
@ -59,9 +59,9 @@ function isJSON(str) {
function loadData() { function loadData() {
request('listsgroups', 'text').then(data => { request('listsgroups', 'text').then(data => {
data.error ? message.error(data.message) : generateListsGroups(data); data.error ? noticer.error(data.message) : generateListsGroups(data);
}).catch(error => { }).catch(error => {
message.error(error.message); noticer.error(error.message);
}); });
} }
@ -78,16 +78,16 @@ function generateListsGroups(data) {
}); });
} }
async function generateGroupNumbers(panel) { function generateGroupNumbers(panel) {
request('groupnumbers', 'json', { group: panel.data("group-name") }).then(data => { request('groupnumbers', 'json', { group: panel.data("group-name") }).then(data => {
if (isJSON(data) && JSON.parse(data).error) if (isJSON(data) && JSON.parse(data).error)
message.error(JSON.parse(data).message); noticer.error(JSON.parse(data).message);
else { else {
numbers = data; numbers = data;
showNumbers(panel); showNumbers(panel);
} }
}).catch(error => { }).catch(error => {
message.error(error.message); noticer.error(error.message);
}); });
} }
@ -95,7 +95,7 @@ function showNumbers(panel, data = numbers) {
(new divNotFoundNumbers).remove(); (new divNotFoundNumbers).remove();
let body = panel.find('.body').html(''); let body = panel.find('.body').html('');
$(data).each((i, j) => { $(data).each((i, j) => {
let row = $(`<tr class="row" data-number="${j.id}"></tr>`); let row = $(`<tr class="row" data-number="${j.number}"></tr>`);
row.append(`<td>${j.number}</td>`); row.append(`<td>${j.number}</td>`);
row.append(`<td>${j.list}</td>`); row.append(`<td>${j.list}</td>`);
row.append(`<td>${j.all_cc}</td>`); row.append(`<td>${j.all_cc}</td>`);
@ -105,7 +105,7 @@ function showNumbers(panel, data = numbers) {
body.append(row); body.append(row);
row.click(function() { row.click(function() {
// numberEdit($(this).data('number')); numberEdit($(this).data('number'));
}); });
}); });
@ -133,3 +133,75 @@ function divNotFoundNumbers() {
notFound.remove(); notFound.remove();
} }
} }
function numberEdit(number) {
request('editnumber', 'text', {number: number}).then(data => {
if (isJSON(data) && JSON.parse(data).error)
noticer.error(JSON.parse(data).message);
else {
showEditNumber(data, [
{
id: "btn-save",
text: "Сохранить",
icon: "ui-icon-check",
click: function() {
actionNumber($(this), 'update');
}
},
{
id: "btn-delete",
text: "Удалить",
icon: "ui-icon-trash",
click: function() {
// removeNumber($(this));
}
}
], `Редактирование номера ${number}`);
}
}).catch(error => {
noticer.error(error.message);
});
}
function showEditNumber(data, actionButton, title) {
let form = $(data);
form.appendTo('body').dialog({
title: title,
height: 'auto',
width: 'auto',
maxHeight: 500,
minHeight: 50,
resizable: false,
modal: true,
show: { effect: "fade", duration: 500 },
close: function(event, ui) {
$(this).dialog('destroy').remove()
},
buttons: [
...actionButton,
{
text: "Отмена",
icon: "ui-icon-cancel",
click: function() {
$(this).dialog("close");
}
}
]
});
$('#number-group, #number-list').selectmenu({
width: 200
});
}
function actionNumber(currentWindow, query) {
let number = $('#number-number').val();
let group = $('#number-group').val();
let list = $('#number-list').val();
let all_cc = $('#number-all-cc').val();
let white_cc = $('#number-white-cc').val();
let black_cc = $('#number-black-cc').val();
let comment = $('#number-comment').val();
}

View File

@ -49,18 +49,19 @@ input {
border: 1px solid#c5c5c5; border: 1px solid#c5c5c5;
} }
.input-focus:hover { .input-focus:hover:not([disabled]) {
border: 1px solid #ccc border: 1px solid #999;
box-shadow: 1px 1px 10px 1px #ccc;
} }
.input-focus::placeholder { .input-focus::placeholder {
color: #333 color: #333
} }
.input-focus:focus { .input-focus:focus:not([disabled]) {
outline: none; outline: none;
box-shadow: 1px 1px 10px 1px #007fff; box-shadow: 1px 1px 10px 1px #666;
border: 1px solid #003eff; border: 1px solid #555;
} }
/* BODY */ /* BODY */
@ -96,6 +97,12 @@ td {
text-align: center; text-align: center;
} }
.body-rows td {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.body-rows tbody tr:nth-child(even){ .body-rows tbody tr:nth-child(even){
background: #fff; background: #fff;
} }
@ -105,3 +112,48 @@ tr.row:hover, tr.row:nth-child(even):hover {
color: #fff; color: #fff;
cursor: pointer; cursor: pointer;
} }
/* EDIT NUMBER */
.number-label {
color: #333;
text-align: right;
}
.number-value {
height: 30px;
}
.number-input-main {
height: 25px;
width: 194px;
margin: 0 10px 0 10px;
}
.number-input-cc {
height: 25px;
width: 50px;
margin: 0 10px 0 10px;
}
.div-advanced {
display: flex;
flex-direction: column;
}
.comment {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.comment-content {
width: 100%;
height: 100%;
}
#number-comment {
width: calc(100% - 6px);
resize: none;
}

View File

@ -18,6 +18,7 @@ import structures;
import requests.listsgroups; import requests.listsgroups;
import requests.groupnumbers; import requests.groupnumbers;
import requests.editnumber;
static ServerInfo serverInfo; static ServerInfo serverInfo;
@ -169,10 +170,10 @@ void postReq(HTTPServerRequest req, HTTPServerResponse res) {
switch (query) { switch (query) {
case "listsgroups": case "listsgroups":
listsgroups(req, res); listsGroups(req, res);
break; break;
case "groupnumbers": case "groupnumbers":
groupnumbers(req, res); groupNumbers(req, res);
break; break;
// case "authorization": // case "authorization":
// authorization(req, res); // authorization(req, res);
@ -189,9 +190,9 @@ void postReq(HTTPServerRequest req, HTTPServerResponse res) {
// case "write": // case "write":
// writeNumber(req, res); // writeNumber(req, res);
// break; // break;
// case "edit": case "editnumber":
// editNumber(req, res); editNumber(req, res);
// break; break;
// case "update": // case "update":
// updateNumber(req, res); // updateNumber(req, res);
// break; // break;

View File

@ -11,10 +11,10 @@ GroupDB[] getListGroups() {
try { try {
auto queryResult = pgsql.sql( auto queryResult = pgsql.sql(
"select distinct "select distinct
n.da_group, dan.da_group,
g.da_comment dag.da_comment
from da_numbers n from da_numbers dan
left join da_groups g ON g.da_name = n.da_group" left join da_groups dag ON dag.da_name = dan.da_group"
); );
foreach (row; queryResult) { foreach (row; queryResult) {
GroupDB data; GroupDB data;
@ -44,7 +44,7 @@ NumberDB[] getListNumbers(string group) {
dan.da_comment dan.da_comment
from da_numbers dan from da_numbers dan
left join da_lists dal on dal.da_name = dan.da_list left join da_lists dal on dal.da_name = dan.da_list
where da_group = ?", where dan.da_group = ?",
group group
); );
foreach (row; queryResult) { foreach (row; queryResult) {
@ -65,3 +65,77 @@ NumberDB[] getListNumbers(string group) {
return numbers; return numbers;
} }
NumberDB getDataNumber(string number) {
NumberDB data;
try {
auto queryResult = pgsql.sql(
"select
da_number,
da_group,
da_list,
da_all_cc,
da_white_cc,
da_black_cc,
da_comment
from da_numbers
where da_number = ?",
number
);
foreach (row; queryResult) {
data.number = row["da_number"];
data.group = row["da_group"];
data.list = row["da_list"];
data.all_cc = row["da_all_cc"].to!int;
data.white_cc = row["da_white_cc"].to!int;
data.black_cc = row["da_black_cc"].to!int;
data.comment = row["da_comment"];
}
} catch (Exception e) {
log.e("Не удалось выполнить запрос к БД. " ~ e.msg);
}
return data;
}
GroupDB[] getGroups() {
GroupDB[] groups;
try {
auto queryResult = pgsql.sql(
"select da_name, da_comment from da_groups"
);
foreach (row; queryResult) {
GroupDB data;
data.name = row["da_name"];
data.comment = row["da_comment"];
groups ~= data;
}
} catch (Exception e) {
log.e("Не удалось выполнить запрос к БД. " ~ e.msg);
}
return groups;
}
ListDB[] getLists() {
ListDB[] lists;
try {
auto queryResult = pgsql.sql(
"select da_name, da_comment from da_lists"
);
foreach (row; queryResult) {
ListDB data;
data.name = row["da_name"];
data.comment = row["da_comment"];
lists ~= data;
}
} catch (Exception e) {
log.e("Не удалось выполнить запрос к БД. " ~ e.msg);
}
return lists;
}

View File

@ -0,0 +1,15 @@
module requests.editnumber;
import vibe.vibe;
import response;
import data;
import singlog;
void editNumber(HTTPServerRequest req, HTTPServerResponse res) {
auto jsr = req.json;
bool edit = true;
auto dataNumber = getDataNumber(jsr["number"].get!string);
auto groups = getGroups();
auto lists = getLists();
render!("edit-number.dt", edit, dataNumber, groups, lists)(res);
}

View File

@ -5,7 +5,7 @@ import response;
import data; import data;
import singlog; import singlog;
void groupnumbers(HTTPServerRequest req, HTTPServerResponse res) { void groupNumbers(HTTPServerRequest req, HTTPServerResponse res) {
auto jsr = req.json; auto jsr = req.json;
res.writeJsonBody(getListNumbers(jsr["group"].get!string).serializeToJson()); res.writeJsonBody(getListNumbers(jsr["group"].get!string).serializeToJson());
} }

View File

@ -4,7 +4,7 @@ import vibe.vibe;
import response; import response;
import data; import data;
void listsgroups(HTTPServerRequest req, HTTPServerResponse res) { void listsGroups(HTTPServerRequest req, HTTPServerResponse res) {
auto listGroups = getListGroups(); auto listGroups = getListGroups();
render!("group-numbers-list.dt", listGroups)(res); render!("group-numbers-list.dt", listGroups)(res);
} }

View File

@ -22,6 +22,11 @@ struct GroupDB {
string comment; string comment;
} }
struct ListDB {
string name;
string comment;
}
struct NumberDB { struct NumberDB {
string number; string number;
string group; string group;

43
views/edit-number.dt Normal file
View File

@ -0,0 +1,43 @@
- import structures;
div#number-data
table
tbody
tr
td.number-label Номер:
td.number-value
- if (edit)
input.number-input-main.input-focus#number-number(type='text', value='#{dataNumber.number}', disabled)
- else
input.number-input-main.input-focus#number-number(type='text', value='#{dataNumber.number}')
td.number-label Общие звонки:
td.number-value
input.number-input-cc.input-focus#number-all-cc(type='text', value='#{dataNumber.all_cc}')
tr
td.number-label Группа:
td.number-value
select#number-group
- foreach (group; groups)
- if (dataNumber.group == group.name)
option(selected, value='#{group.name}') #{group.comment}
- else
option(value='#{group.name}') #{group.comment}
td.number-label Белые звонки:
td.number-value
input.number-input-cc.input-focus#number-white-cc(type='text', value='#{dataNumber.white_cc}')
tr
td.number-label Список:
td.number-value
select#number-list
- foreach (list; lists)
- if (dataNumber.list == list.name)
option(selected, value='#{list.name}') #{list.comment}
- else
option(value='#{list.name}') #{list.comment}
td.number-label Черные звонки:
td.number-value
input.number-input-cc.input-focus#number-black-cc(type='text', value='#{dataNumber.black_cc}')
div.div-advanced
div.comment
div.comment-name Комментарий
div.comment-content
textarea.input-focus#number-comment #{dataNumber.comment}

View File

@ -6,7 +6,7 @@ head
link(rel='stylesheet', type='text/css', href='style.css') link(rel='stylesheet', type='text/css', href='style.css')
script(src='jquery-3.7.0.min.js') script(src='jquery-3.7.0.min.js')
script(src='jquery-ui.min.js') script(src='jquery-ui.min.js')
script(src='message.js') script(src='noticer.min.js')
script(src='script.js') script(src='script.js')
body body
div.div-header div.div-header