[EDIT] CAMBIOS DE DISEÑO Y MULTIPLES REPARACIONES

parent b65c7316
...@@ -30,7 +30,7 @@ public interface UsuarioDAO { ...@@ -30,7 +30,7 @@ public interface UsuarioDAO {
public int eliminarUsuario(int codigo) throws Exception; public int eliminarUsuario(int codigo) throws Exception;
public JSONObject listarUsuarioDetalle(String filtro, int vstart, int vlength, String draw) throws Exception; public JSONObject listarUsuarioDetalle(JSONObject filtro, int vstart, int vlength, String draw) throws Exception;
public int eliminarUsuarioDetalle(int codigo) throws Exception; public int eliminarUsuarioDetalle(int codigo) throws Exception;
......
...@@ -45,7 +45,8 @@ public class ProyectoMYSQLDAO implements ProyectoDAO { ...@@ -45,7 +45,8 @@ public class ProyectoMYSQLDAO implements ProyectoDAO {
} }
query = " select cod_proyecto, nom, est, url from proyecto " query = " select cod_proyecto, nom, est, url from proyecto "
+ " where true" + " where true"
+ " " + busqueda + " "; + " " + busqueda + " " +
" limit " + vstart + "," + (vstart+vlength) + " ";
con = MySQLDAOFactory.getConnectionSQL(base); con = MySQLDAOFactory.getConnectionSQL(base);
System.out.println("query: " + query); System.out.println("query: " + query);
pst = con.prepareStatement(query); pst = con.prepareStatement(query);
...@@ -64,7 +65,7 @@ public class ProyectoMYSQLDAO implements ProyectoDAO { ...@@ -64,7 +65,7 @@ public class ProyectoMYSQLDAO implements ProyectoDAO {
String query2 = " select count(*) as cant " String query2 = " select count(*) as cant "
+ " from proyecto " + " from proyecto "
+ " where 1 = 1 " + " where 1 = 1 "
+ " " + busqueda + " "; + " " + busqueda +";";
PreparedStatement pst2 = null; PreparedStatement pst2 = null;
ResultSet rs2 = null; ResultSet rs2 = null;
con = MySQLDAOFactory.getConnectionSQL(base); con = MySQLDAOFactory.getConnectionSQL(base);
......
...@@ -22,45 +22,42 @@ public class UsuarioMYSQLDAO implements UsuarioDAO { ...@@ -22,45 +22,42 @@ public class UsuarioMYSQLDAO implements UsuarioDAO {
@Override @Override
public JSONArray listarUsuario(JSONObject datos, int vstart, int vlength, int draw) throws Exception { public JSONArray listarUsuario(JSONObject datos, int vstart, int vlength, int draw) throws Exception {
String base = "security"; String base = "security";
Connection con = null; Connection con = null;
PreparedStatement pst = null; PreparedStatement pst = null;
ResultSet rs = null; ResultSet rs = null;
String query = ""; String query = "";
JSONArray lista = new JSONArray(); JSONArray lista = new JSONArray();
String busqueda01;
try { try {
switch (datos.getString("tipo")) { String estado = !datos.getBoolean("estado") ? " and a.est = 1 " : " and a.est = 0 ";
case "1": int proyecto = datos.isNull("proyecto") ? 0 : datos.getInt("proyecto");
busqueda01 = " and a.usu like '%" + datos.getString("filtro") + "%' "; int tipoUsuario = datos.isNull("tipoUsuario") ? 0 : datos.getInt("tipoUsuario");
break; int estadoPersonal = datos.isNull("estadoPersonal") ? 2 : datos.getInt("estadoPersonal") == 0 ? 2 : datos.getInt("estadoPersonal") == 1 ? 0 : 1;
case "2": String personal = datos.isNull("trabajador") ? "" : datos.getString("trabajador");
busqueda01 = " and pd.cod_proyecto = " + datos.getString("filtro") + " "; boolean isNumber = personal.matches("[0-9]+");
break; String cargo = datos.isNull("cargo") ? "" : datos.getString("cargo");
case "3": query = "WITH tablaOrdenada AS (SELECT a.cod_usuario, a.cod_trabajador, a.usu, a.est,p.tmp_id,p.retirado\n" +
busqueda01 = " and ud.cod_proyecto_detalle = " + datos.getString("filtro") + " "; " FROM usuario AS a\n" +
break; " LEFT JOIN seguridad.usuario_detalle AS ud ON ud.cod_usuario = a.cod_usuario\n" +
default: " LEFT JOIN seguridad.proyecto_detalle AS pd\n" +
busqueda01 = ""; " ON pd.cod_proyecto_detalle = ud.cod_proyecto_detalle\n" +
break; " left join seguridad.tipo_usuario as tu on pd.cod_tipo_usuario = tu.cod_tipo_usuario\n" +
} " left join nuevo.personal as p on a.cod_trabajador = p.tmp_id\n" +
if (!datos.getBoolean("estado")) { " left join nuevo.cargo as c on p.codcargo = c.codcargo\n" +
busqueda01 += " and a.est = 1 "; " WHERE 1 = 1\n" +
} else { " and if("+proyecto+" = 0, true, pd.cod_proyecto = "+proyecto+")\n" +
busqueda01 += " and a.est = 0 "; " and if("+tipoUsuario+" = 0, true, pd.cod_proyecto_detalle = "+tipoUsuario+")\n" +
} " " + estado + "\n" +
query = " WITH tablaOrdenada AS (SELECT a.cod_usuario, a.cod_trabajador, a.usu, a.est, ROW_NUMBER() OVER (ORDER BY a.cod_usuario) AS cantidad FROM usuario AS a " " and if("+estadoPersonal+" = 2, true, p.retirado = "+estadoPersonal+")\n" +
+ " LEFT JOIN usuario_detalle AS ud ON ud.cod_usuario = a.cod_usuario " (isNumber ? " and p.numero_documento = "+personal+" \n" : " and a.usu like '%"+personal+"%' \n" )+
+ " LEFT JOIN proyecto_detalle AS pd ON pd.cod_proyecto_detalle = ud.cod_proyecto_detalle " " and if('"+cargo+"' = '', true, c.descargo = '"+cargo+"')\n" +
+ " WHERE 1= 1 " " GROUP BY a.cod_usuario, a.cod_trabajador, a.usu, a.est)\n" +
+ " " + busqueda01 + " " "select cod_usuario, cod_trabajador, usu, est,tmp_id,retirado\n" +
+ " GROUP BY a.cod_usuario, a.cod_trabajador, a.usu, a.est) " "from tablaOrdenada\n" +
+ " select cod_usuario, cod_trabajador, usu, est, cantidad from tablaOrdenada " "ORDER BY usu limit "+vlength+" offset "+vstart+";";
+ " where cantidad BETWEEN "+vstart+" and "+vlength*draw
+ " ORDER BY usu ASC";
con = MySQLDAOFactory.getConnectionSQL(base); con = MySQLDAOFactory.getConnectionSQL(base);
pst = con.prepareStatement(query); pst = con.prepareStatement(query);
rs = pst.executeQuery(); rs = pst.executeQuery();
int conta = vstart + 1; int conta = vstart + 1;
...@@ -71,6 +68,8 @@ public class UsuarioMYSQLDAO implements UsuarioDAO { ...@@ -71,6 +68,8 @@ public class UsuarioMYSQLDAO implements UsuarioDAO {
obj.put("codigoTrabajador", rs.getString(2)); obj.put("codigoTrabajador", rs.getString(2));
obj.put("usuario", rs.getString(3)); obj.put("usuario", rs.getString(3));
obj.put("estadoUsuario", rs.getInt(4)); obj.put("estadoUsuario", rs.getInt(4));
obj.put("tmp_id", rs.getInt(5));
obj.put("retirado", rs.getInt(6));
lista.put(obj); lista.put(obj);
conta++; conta++;
} }
...@@ -93,30 +92,28 @@ public class UsuarioMYSQLDAO implements UsuarioDAO { ...@@ -93,30 +92,28 @@ public class UsuarioMYSQLDAO implements UsuarioDAO {
String query = ""; String query = "";
String busqueda = ""; String busqueda = "";
try { try {
switch (datos.getString("tipo")) { String estado = !datos.getBoolean("estado") ? " and a.est = 1 " : " and a.est = 0 ";
case "1": int proyecto = datos.isNull("proyecto") ? 0 : datos.getInt("proyecto");
busqueda = " and a.usu like '%" + datos.getString("filtro") + "%' "; int tipoUsuario = datos.isNull("tipoUsuario") ? 0 : datos.getInt("tipoUsuario");
break; int estadoPersonal = datos.isNull("estadoPersonal") ? 2 : datos.getInt("estadoPersonal") == 0 ? 2 : datos.getInt("estadoPersonal") == 1 ? 0 : 1;
case "2": String personal = datos.isNull("trabajador") ? "" : datos.getString("trabajador");
busqueda = " and pd.cod_proyecto = " + datos.getString("filtro") + " "; String cargo = datos.isNull("cargo") ? "" : datos.getString("cargo");
break; boolean isNumber = personal.matches("[0-9]+");
case "3": query = " SELECT COUNT(*) as cant FROM usuario AS a " +
busqueda = " and ud.cod_proyecto_detalle = " + datos.getString("filtro") + " "; " LEFT JOIN usuario_detalle AS ud ON ud.cod_usuario = a.cod_usuario " +
break; " LEFT JOIN proyecto_detalle AS pd ON pd.cod_proyecto_detalle = ud.cod_proyecto_detalle " +
default: " left join seguridad.tipo_usuario as tu on pd.cod_tipo_usuario = tu.cod_tipo_usuario\n" +
busqueda = ""; " left join nuevo.personal as p on a.cod_trabajador = p.tmp_id\n" +
break; " left join nuevo.cargo as c on p.codcargo = c.codcargo\n" +
} " WHERE 1 = 1\n" +
if (!datos.getBoolean("estado")) { " and if(" + proyecto + " = 0, true, pd.cod_proyecto = " + proyecto + ")\n" +
busqueda += " and a.est = 1 "; " and if(" + tipoUsuario + " = 0, true, pd.cod_proyecto_detalle = " + tipoUsuario + ")\n" +
} else { " " + estado + "\n" +
busqueda += " and a.est = 0 "; " and if(" + estadoPersonal + " = 2, true, p.retirado = " + estadoPersonal + ")\n" +
} " and if('"+cargo+"' = '', true, c.descargo = '"+cargo+"')\n" +
query = " SELECT COUNT(*) as cant FROM usuario AS a " (isNumber ? " and p.numero_documento = " + personal + " \n" : " and a.usu like '%" + personal + "%' \n")
+ " LEFT JOIN usuario_detalle AS ud ON ud.cod_usuario = a.cod_usuario "
+ " LEFT JOIN proyecto_detalle AS pd ON pd.cod_proyecto_detalle = ud.cod_proyecto_detalle " + " GROUP BY a.cod_usuario ";
+ " WHERE 1 = 1 " + busqueda + " "
+ " GROUP BY a.cod_usuario ";
con = MySQLDAOFactory.getConnectionSQL(base); con = MySQLDAOFactory.getConnectionSQL(base);
pst = con.prepareStatement(query); pst = con.prepareStatement(query);
rs = pst.executeQuery(); rs = pst.executeQuery();
...@@ -281,7 +278,7 @@ public class UsuarioMYSQLDAO implements UsuarioDAO { ...@@ -281,7 +278,7 @@ public class UsuarioMYSQLDAO implements UsuarioDAO {
} }
@Override @Override
public JSONObject listarUsuarioDetalle(String filtro, int vstart, int vlength, String draw) throws Exception { public JSONObject listarUsuarioDetalle(JSONObject json, int vstart, int vlength, String draw) throws Exception {
String base = "security"; String base = "security";
Connection con = null; Connection con = null;
PreparedStatement pst = null; PreparedStatement pst = null;
...@@ -290,6 +287,7 @@ public class UsuarioMYSQLDAO implements UsuarioDAO { ...@@ -290,6 +287,7 @@ public class UsuarioMYSQLDAO implements UsuarioDAO {
ResultSet rs = null; ResultSet rs = null;
String query = ""; String query = "";
int conta = vstart; int conta = vstart;
int filtro = json.isNull("filtro") ? 0 : json.getInt("filtro");
try { try {
query = " select ud.cod_usuario_detalle, ud.est, p.nom, tu.nom from usuario_detalle as ud " query = " select ud.cod_usuario_detalle, ud.est, p.nom, tu.nom from usuario_detalle as ud "
+ " inner join proyecto_detalle as pd " + " inner join proyecto_detalle as pd "
...@@ -298,7 +296,7 @@ public class UsuarioMYSQLDAO implements UsuarioDAO { ...@@ -298,7 +296,7 @@ public class UsuarioMYSQLDAO implements UsuarioDAO {
+ " on p.cod_proyecto = pd.cod_proyecto " + " on p.cod_proyecto = pd.cod_proyecto "
+ " inner join tipo_usuario as tu " + " inner join tipo_usuario as tu "
+ " on tu.cod_tipo_usuario = pd.cod_tipo_usuario " + " on tu.cod_tipo_usuario = pd.cod_tipo_usuario "
+ " where ud.cod_usuario = " + filtro + ""; + " where ud.cod_usuario = " + filtro + ";";
con = MySQLDAOFactory.getConnectionSQL(base); con = MySQLDAOFactory.getConnectionSQL(base);
pst = con.prepareStatement(query); pst = con.prepareStatement(query);
rs = pst.executeQuery(); rs = pst.executeQuery();
......
...@@ -99,7 +99,7 @@ public class UsuarioService { ...@@ -99,7 +99,7 @@ public class UsuarioService {
return rs; return rs;
} }
public JSONObject listarUsuarioDetalle(String filtro, int vstart, int vlength, String draw) { public JSONObject listarUsuarioDetalle(JSONObject filtro, int vstart, int vlength, String draw) {
JSONObject rs = null; JSONObject rs = null;
try { try {
rs = dao.listarUsuarioDetalle(filtro, vstart, vlength, draw); rs = dao.listarUsuarioDetalle(filtro, vstart, vlength, draw);
......
...@@ -104,7 +104,11 @@ public class MantenimientoMenuServlet extends HttpServlet { ...@@ -104,7 +104,11 @@ public class MantenimientoMenuServlet extends HttpServlet {
int tipo = Integer.parseInt(request.getParameter("tipo")); int tipo = Integer.parseInt(request.getParameter("tipo"));
int proyecto = Integer.parseInt(request.getParameter("proyecto")); int proyecto = Integer.parseInt(request.getParameter("proyecto"));
String draw = request.getParameter("draw"); String draw = request.getParameter("draw");
int listarPermisos = Integer.parseInt(request.getParameter("listarPermisos")); System.out.println(request.getParameter("listarPermisos"));
int listarPermisos = 0;
if(request.getParameter("listarPermisos") != null){
listarPermisos = Integer.parseInt(request.getParameter("listarPermisos"));
}
JSONObject rs = new JSONObject(); JSONObject rs = new JSONObject();
JSONArray lista = new JSONArray(); JSONArray lista = new JSONArray();
JSONArray listaTitulo = srv.listarTituloCompleto(proyecto_detalle, proyecto, tipo); JSONArray listaTitulo = srv.listarTituloCompleto(proyecto_detalle, proyecto, tipo);
......
...@@ -133,7 +133,21 @@ public class UsuarioServlet extends HttpServlet { ...@@ -133,7 +133,21 @@ public class UsuarioServlet extends HttpServlet {
objeto.put("nombreCargo", prs.getString("nom_car")); objeto.put("nombreCargo", prs.getString("nom_car"));
objeto.put("nombreUsuario", prs.getString("nom_per") + " " + prs.getString("ape_pat_per") + " " + prs.getString("ape_mat_per")); objeto.put("nombreUsuario", prs.getString("nom_per") + " " + prs.getString("ape_pat_per") + " " + prs.getString("ape_mat_per"));
objeto.put("nombreSede", prs.getString("nom_sed")); objeto.put("nombreSede", prs.getString("nom_sed"));
objeto.put("tmp_id", obj.getInt("tmp_id"));
objeto.put("retirado", obj.getInt("retirado"));
lista.put(objeto); lista.put(objeto);
}else{
objeto.put("codigoUsuario", obj.getInt("codigoUsuario"));
objeto.put("numeral", obj.getInt("numeral"));
objeto.put("usuario", obj.getString("usuario"));
objeto.put("estadoUsuario", obj.getInt("estadoUsuario"));
objeto.put("nombreArea", "");
objeto.put("nombreCargo", "");
objeto.put("nombreUsuario", "");
objeto.put("nombreSede", "");
objeto.put("tmp_id", obj.getInt("tmp_id"));
objeto.put("retirado", obj.getInt("retirado"));
lista.put(objeto);
} }
} }
int cantidad = srv.cantidadRegistros(filtro); int cantidad = srv.cantidadRegistros(filtro);
...@@ -238,12 +252,13 @@ public class UsuarioServlet extends HttpServlet { ...@@ -238,12 +252,13 @@ public class UsuarioServlet extends HttpServlet {
response.setContentType("application/json"); response.setContentType("application/json");
PrintWriter out = response.getWriter(); PrintWriter out = response.getWriter();
UsuarioService srv = new UsuarioService(); UsuarioService srv = new UsuarioService();
String filtro = request.getParameter("filtro"); String json = request.getParameter("json");
JSONObject obj = new JSONObject(json);
String draw = request.getParameter("draw"); String draw = request.getParameter("draw");
int vstart = Integer.parseInt(request.getParameter("start")); int vstart = Integer.parseInt(request.getParameter("start"));
int vlength = Integer.parseInt(request.getParameter("length")); int vlength = Integer.parseInt(request.getParameter("length"));
JSONObject json = srv.listarUsuarioDetalle(filtro, vstart, vlength, draw); JSONObject resp = srv.listarUsuarioDetalle(obj, vstart, vlength, draw);
out.println(json); out.println(resp);
} }
private void eliminarUsuarioDetalle(HttpServletRequest request, HttpServletResponse response) throws IOException { private void eliminarUsuarioDetalle(HttpServletRequest request, HttpServletResponse response) throws IOException {
......
...@@ -90,7 +90,7 @@ let tipo_usuario_nombre = ""; ...@@ -90,7 +90,7 @@ let tipo_usuario_nombre = "";
"infoEmpty": "    Mostrando 0 de 0 registros", "infoEmpty": "    Mostrando 0 de 0 registros",
"search": "Filtrar:", "search": "Filtrar:",
"loadingRecords": "Cargando...", "loadingRecords": "Cargando...",
"processing": '<span style="width:100%;"><img src="https://upload.wikimedia.org/wikipedia/commons/7/7a/Ajax_loader_metal_512.gif?20180219130538"></span>', "processing": '<span style="width:2rem;height: 2rem"><img src="https://upload.wikimedia.org/wikipedia/commons/7/7a/Ajax_loader_metal_512.gif?20180219130538"></span>',
"paginate": { "paginate": {
"first": "First", "first": "First",
"last": "Last", "last": "Last",
...@@ -493,7 +493,7 @@ let tipo_usuario_nombre = ""; ...@@ -493,7 +493,7 @@ let tipo_usuario_nombre = "";
let print = ""; let print = "";
var lista = data.data; var lista = data.data;
lista.forEach(v => { lista.forEach(v => {
print += '<option value="' + v.codAccion +'">'+v.nombreAccion+'</option>'; print += '<option value="' + v.codAccion +'">'+v.codAccion+' - '+v.nombreAccion+'</option>';
}); });
$("#cboListadoAcciones").html(print); $("#cboListadoAcciones").html(print);
$("#cboListadoAcciones").editableSelect(); $("#cboListadoAcciones").editableSelect();
...@@ -1742,7 +1742,7 @@ function crearAcciones(vista, jerarquia,accion, nom_accion){ ...@@ -1742,7 +1742,7 @@ function crearAcciones(vista, jerarquia,accion, nom_accion){
"infoEmpty": "&nbsp;&nbsp;&nbsp; Mostrando 0 de 0 registros", "infoEmpty": "&nbsp;&nbsp;&nbsp; Mostrando 0 de 0 registros",
"search": "Filtrar:", "search": "Filtrar:",
"loadingRecords": "Cargando...", "loadingRecords": "Cargando...",
"processing": '<span style="width:100%;"><img src="https://upload.wikimedia.org/wikipedia/commons/7/7a/Ajax_loader_metal_512.gif?20180219130538"></span>', "processing": '<span style="width:2rem;height: 2rem"><img src="https://upload.wikimedia.org/wikipedia/commons/7/7a/Ajax_loader_metal_512.gif?20180219130538"></span>',
"scrollY": false, "scrollY": false,
"paginate": { "paginate": {
"first": "First", "first": "First",
......
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
"infoEmpty": "&nbsp;&nbsp;&nbsp; Mostrando 0 de 0 registros", "infoEmpty": "&nbsp;&nbsp;&nbsp; Mostrando 0 de 0 registros",
"search": "Filtrar:", "search": "Filtrar:",
"loadingRecords": "Cargando...", "loadingRecords": "Cargando...",
"processing": '<span style="width:100%;"><img src="https://upload.wikimedia.org/wikipedia/commons/7/7a/Ajax_loader_metal_512.gif?20180219130538"></span>', "processing": '<span style="width:2rem;height: 2rem"><img src="https://upload.wikimedia.org/wikipedia/commons/7/7a/Ajax_loader_metal_512.gif?20180219130538"></span>',
"scrollY": false, "scrollY": false,
"paginate": { "paginate": {
"first": "First", "first": "First",
...@@ -683,7 +683,7 @@ ...@@ -683,7 +683,7 @@
"infoEmpty": "&nbsp;&nbsp;&nbsp; Mostrando 0 de 0 registros", "infoEmpty": "&nbsp;&nbsp;&nbsp; Mostrando 0 de 0 registros",
"search": "Filtrar:", "search": "Filtrar:",
"loadingRecords": "Cargando...", "loadingRecords": "Cargando...",
"processing": '<span style="width:100%;"><img src="https://upload.wikimedia.org/wikipedia/commons/7/7a/Ajax_loader_metal_512.gif?20180219130538"></span>', "processing": '<span style="width:2rem;height: 2rem"><img src="https://upload.wikimedia.org/wikipedia/commons/7/7a/Ajax_loader_metal_512.gif?20180219130538"></span>',
"scrollY": false, "scrollY": false,
"paginate": { "paginate": {
"first": "First", "first": "First",
......
...@@ -61,7 +61,7 @@ ...@@ -61,7 +61,7 @@
"infoEmpty": "&nbsp;&nbsp;&nbsp; Mostrando 0 de 0 registros", "infoEmpty": "&nbsp;&nbsp;&nbsp; Mostrando 0 de 0 registros",
"search": "Filtrar:", "search": "Filtrar:",
"loadingRecords": "Cargando...", "loadingRecords": "Cargando...",
"processing": '<span style="width:100%;"><img src="https://upload.wikimedia.org/wikipedia/commons/7/7a/Ajax_loader_metal_512.gif?20180219130538"></span>', "processing": '<span style="width:2rem;height: 2rem"><img src="https://upload.wikimedia.org/wikipedia/commons/7/7a/Ajax_loader_metal_512.gif?20180219130538"></span>',
"scrollY": false, "scrollY": false,
"paginate": { "paginate": {
"first": "First", "first": "First",
...@@ -260,7 +260,7 @@ ...@@ -260,7 +260,7 @@
"infoEmpty": "&nbsp;&nbsp;&nbsp; Mostrando 0 de 0 registros", "infoEmpty": "&nbsp;&nbsp;&nbsp; Mostrando 0 de 0 registros",
"search": "Filtrar:", "search": "Filtrar:",
"loadingRecords": "Cargando...", "loadingRecords": "Cargando...",
"processing": '<span style="width:100%;"><img src="https://upload.wikimedia.org/wikipedia/commons/7/7a/Ajax_loader_metal_512.gif?20180219130538"></span>', "processing": '<span style="width:2rem;height: 2rem"><img src="https://upload.wikimedia.org/wikipedia/commons/7/7a/Ajax_loader_metal_512.gif?20180219130538"></span>',
"scrollY": false, "scrollY": false,
"paginate": { "paginate": {
"first": "First", "first": "First",
...@@ -924,7 +924,7 @@ ...@@ -924,7 +924,7 @@
let print = ""; let print = "";
var lista = data.data; var lista = data.data;
lista.forEach(v => { lista.forEach(v => {
print += '<option value="' + v.codAccion +'">'+v.nombreAccion+'</option>'; print += '<option value="' + v.codAccion +'">'+v.codAccion+' - '+v.nombreAccion+'</option>';
}); });
$("#cboListadoAcciones").html(print); $("#cboListadoAcciones").html(print);
$("#cboListadoAcciones").editableSelect(); $("#cboListadoAcciones").editableSelect();
......
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment