diff --git a/js/message.js b/js/message.js
deleted file mode 100644
index e064ac5..0000000
--- a/js/message.js
+++ /dev/null
@@ -1,100 +0,0 @@
-class Message {
- timer;
-
- constructor() {
- this.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 = $(`${message}
`);
-
- 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);
- }
-}
diff --git a/js/noticer.min.js b/js/noticer.min.js
new file mode 100644
index 0000000..e9e9957
--- /dev/null
+++ b/js/noticer.min.js
@@ -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=$(''),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=$(`${e}
`);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)}}
diff --git a/js/script.js b/js/script.js
index 711df54..845d167 100644
--- a/js/script.js
+++ b/js/script.js
@@ -1,7 +1,7 @@
var numbers = [];
$(document).ready(function () {
- message = new Message;
+ noticer = new Noticer;
$("button").button();
$("#tabs").tabs();
@@ -59,9 +59,9 @@ function isJSON(str) {
function loadData() {
request('listsgroups', 'text').then(data => {
- data.error ? message.error(data.message) : generateListsGroups(data);
+ data.error ? noticer.error(data.message) : generateListsGroups(data);
}).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 => {
if (isJSON(data) && JSON.parse(data).error)
- message.error(JSON.parse(data).message);
+ noticer.error(JSON.parse(data).message);
else {
numbers = data;
showNumbers(panel);
}
}).catch(error => {
- message.error(error.message);
+ noticer.error(error.message);
});
}
@@ -95,7 +95,7 @@ function showNumbers(panel, data = numbers) {
(new divNotFoundNumbers).remove();
let body = panel.find('.body').html('');
$(data).each((i, j) => {
- let row = $(`
`);
+ let row = $(`
`);
row.append(`${j.number} | `);
row.append(`${j.list} | `);
row.append(`${j.all_cc} | `);
@@ -104,8 +104,8 @@ function showNumbers(panel, data = numbers) {
row.append(`${j.comment} | `);
body.append(row);
- row.click(function(){
- // numberEdit($(this).data('number'));
+ row.click(function() {
+ numberEdit($(this).data('number'));
});
});
@@ -133,3 +133,75 @@ function divNotFoundNumbers() {
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();
+}
+
diff --git a/public/style.css b/public/style.css
index 3f86680..767e236 100644
--- a/public/style.css
+++ b/public/style.css
@@ -49,18 +49,19 @@ input {
border: 1px solid#c5c5c5;
}
-.input-focus:hover {
- border: 1px solid #ccc
+.input-focus:hover:not([disabled]) {
+ border: 1px solid #999;
+ box-shadow: 1px 1px 10px 1px #ccc;
}
.input-focus::placeholder {
color: #333
}
-.input-focus:focus {
+.input-focus:focus:not([disabled]) {
outline: none;
- box-shadow: 1px 1px 10px 1px #007fff;
- border: 1px solid #003eff;
+ box-shadow: 1px 1px 10px 1px #666;
+ border: 1px solid #555;
}
/* BODY */
@@ -96,6 +97,12 @@ td {
text-align: center;
}
+.body-rows td {
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+
.body-rows tbody tr:nth-child(even){
background: #fff;
}
@@ -105,3 +112,48 @@ tr.row:hover, tr.row:nth-child(even):hover {
color: #fff;
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;
+}
diff --git a/source/daster.d b/source/daster.d
index 7c2c52a..14a7121 100644
--- a/source/daster.d
+++ b/source/daster.d
@@ -18,6 +18,7 @@ import structures;
import requests.listsgroups;
import requests.groupnumbers;
+import requests.editnumber;
static ServerInfo serverInfo;
@@ -169,10 +170,10 @@ void postReq(HTTPServerRequest req, HTTPServerResponse res) {
switch (query) {
case "listsgroups":
- listsgroups(req, res);
+ listsGroups(req, res);
break;
case "groupnumbers":
- groupnumbers(req, res);
+ groupNumbers(req, res);
break;
// case "authorization":
// authorization(req, res);
@@ -189,9 +190,9 @@ void postReq(HTTPServerRequest req, HTTPServerResponse res) {
// case "write":
// writeNumber(req, res);
// break;
- // case "edit":
- // editNumber(req, res);
- // break;
+ case "editnumber":
+ editNumber(req, res);
+ break;
// case "update":
// updateNumber(req, res);
// break;
diff --git a/source/data.d b/source/data.d
index b333388..0b6eaaa 100644
--- a/source/data.d
+++ b/source/data.d
@@ -11,10 +11,10 @@ GroupDB[] getListGroups() {
try {
auto queryResult = pgsql.sql(
"select distinct
- n.da_group,
- g.da_comment
- from da_numbers n
- left join da_groups g ON g.da_name = n.da_group"
+ dan.da_group,
+ dag.da_comment
+ from da_numbers dan
+ left join da_groups dag ON dag.da_name = dan.da_group"
);
foreach (row; queryResult) {
GroupDB data;
@@ -43,8 +43,8 @@ NumberDB[] getListNumbers(string group) {
dan.da_black_cc,
dan.da_comment
from da_numbers dan
- left join da_lists dal on dal.da_name = dan.da_list
- where da_group = ?",
+ left join da_lists dal on dal.da_name = dan.da_list
+ where dan.da_group = ?",
group
);
foreach (row; queryResult) {
@@ -65,3 +65,77 @@ NumberDB[] getListNumbers(string group) {
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;
+}
diff --git a/source/requests/editnumber.d b/source/requests/editnumber.d
new file mode 100644
index 0000000..4d8be89
--- /dev/null
+++ b/source/requests/editnumber.d
@@ -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);
+}
diff --git a/source/requests/groupnumbers.d b/source/requests/groupnumbers.d
index 62f6288..1d7f73a 100644
--- a/source/requests/groupnumbers.d
+++ b/source/requests/groupnumbers.d
@@ -5,7 +5,7 @@ import response;
import data;
import singlog;
-void groupnumbers(HTTPServerRequest req, HTTPServerResponse res) {
+void groupNumbers(HTTPServerRequest req, HTTPServerResponse res) {
auto jsr = req.json;
res.writeJsonBody(getListNumbers(jsr["group"].get!string).serializeToJson());
}
diff --git a/source/requests/listsgroups.d b/source/requests/listsgroups.d
index 4d6bec3..94e6dbb 100644
--- a/source/requests/listsgroups.d
+++ b/source/requests/listsgroups.d
@@ -4,7 +4,7 @@ import vibe.vibe;
import response;
import data;
-void listsgroups(HTTPServerRequest req, HTTPServerResponse res) {
+void listsGroups(HTTPServerRequest req, HTTPServerResponse res) {
auto listGroups = getListGroups();
render!("group-numbers-list.dt", listGroups)(res);
}
diff --git a/source/structures.d b/source/structures.d
index 1f04a77..a115318 100644
--- a/source/structures.d
+++ b/source/structures.d
@@ -22,6 +22,11 @@ struct GroupDB {
string comment;
}
+struct ListDB {
+ string name;
+ string comment;
+}
+
struct NumberDB {
string number;
string group;
diff --git a/views/edit-number.dt b/views/edit-number.dt
new file mode 100644
index 0000000..fd8c788
--- /dev/null
+++ b/views/edit-number.dt
@@ -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}
diff --git a/views/index.dt b/views/index.dt
index 69887bd..e32e093 100644
--- a/views/index.dt
+++ b/views/index.dt
@@ -6,7 +6,7 @@ head
link(rel='stylesheet', type='text/css', href='style.css')
script(src='jquery-3.7.0.min.js')
script(src='jquery-ui.min.js')
- script(src='message.js')
+ script(src='noticer.min.js')
script(src='script.js')
body
div.div-header