Version 22.46: Oct 13, 2022 Review of projects.

This commit is contained in:
acanas 2022-10-13 22:30:01 +02:00
parent 9dad60355a
commit 53d2c6aafb
5 changed files with 145 additions and 54 deletions

View File

@ -3235,7 +3235,7 @@ table.CELLS_PAD_10 > tbody > tr > td {padding:10px;}
} }
/******************************** Projects ***********************************/ /******************************** Projects ***********************************/
.PRJ_LOCK .PRJ_LOCK, .PRJ_DATE
{ {
display:inline-block; display:inline-block;
} }

View File

@ -606,10 +606,11 @@ TODO: Fix bug: error al enviar un mensaje a dos recipientes, error on duplicate
TODO: Attach pdf files in multimedia. TODO: Attach pdf files in multimedia.
*/ */
#define Log_PLATFORM_VERSION "SWAD 22.45 (2022-10-13)" #define Log_PLATFORM_VERSION "SWAD 22.46 (2022-10-13)"
#define CSS_FILE "swad22.40.css" #define CSS_FILE "swad22.46.css"
#define JS_FILE "swad21.100.js" #define JS_FILE "swad21.100.js"
/* /*
Version 22.46: Oct 13, 2022 Review of projects. (333219 lines)
Version 22.45: Oct 13, 2022 Review of projects (not finished). (333137 lines) Version 22.45: Oct 13, 2022 Review of projects (not finished). (333137 lines)
Version 22.44.3: Oct 12, 2022 Code refactoring in projects. (333015 lines) Version 22.44.3: Oct 12, 2022 Code refactoring in projects. (333015 lines)
Version 22.44.2: Oct 12, 2022 Code refactoring in projects. (333001 lines) Version 22.44.2: Oct 12, 2022 Code refactoring in projects. (333001 lines)

View File

@ -602,7 +602,7 @@ static void Prg_WriteRowItem (Prg_ListingType_t ListingType,
StartEndTime <= (Dat_StartEndTime_t) (Dat_NUM_START_END_TIME - 1); StartEndTime <= (Dat_StartEndTime_t) (Dat_NUM_START_END_TIME - 1);
StartEndTime++) StartEndTime++)
{ {
if (asprintf (&Id,"scd_date_%u_%u",(unsigned) StartEndTime,UniqueId) < 0) if (asprintf (&Id,"prg_date_%u_%u",(unsigned) StartEndTime,UniqueId) < 0)
Err_NotEnoughMemoryExit (); Err_NotEnoughMemoryExit ();
HTM_DIV_Begin ("id=\"%s\" class=\"%s_%s%s\"", HTM_DIV_Begin ("id=\"%s\" class=\"%s_%s%s\"",
Id, Id,

View File

@ -95,14 +95,14 @@ static struct
Ico_Color_t Color; Ico_Color_t Color;
} ReviewIcon[Prj_NUM_REVIEW_STATUS] = } ReviewIcon[Prj_NUM_REVIEW_STATUS] =
{ {
/*
[Prj_UNREVIEWED] = {"file-circle-question.svg" ,Ico_BLACK}, [Prj_UNREVIEWED] = {"file-circle-question.svg" ,Ico_BLACK},
[Prj_UNAPPROVED] = {"file-circle-exclamation.svg",Ico_RED }, [Prj_UNAPPROVED] = {"file-circle-exclamation.svg",Ico_RED },
[Prj_APPROVED ] = {"file-circle-check.svg" ,Ico_GREEN}, [Prj_APPROVED ] = {"file-circle-check.svg" ,Ico_GREEN},
*/ /*
[Prj_UNREVIEWED] = {"filter-circle-xmark.svg",Ico_BLACK}, [Prj_UNREVIEWED] = {"filter-circle-xmark.svg",Ico_BLACK},
[Prj_UNAPPROVED] = {"thumbs-down.svg" ,Ico_RED }, [Prj_UNAPPROVED] = {"thumbs-down.svg" ,Ico_RED },
[Prj_APPROVED ] = {"thumbs-up.svg" ,Ico_GREEN}, [Prj_APPROVED ] = {"thumbs-up.svg" ,Ico_GREEN},
*/
}; };
/***** Locked/unlocked project edition *****/ /***** Locked/unlocked project edition *****/
@ -150,6 +150,8 @@ struct Prj_Faults
bool WrongDescription; bool WrongDescription;
bool WrongNumStds; bool WrongNumStds;
bool WrongAssigned; bool WrongAssigned;
bool WrongReviewStatus;
bool WrongModifTime;
}; };
/*****************************************************************************/ /*****************************************************************************/
@ -209,9 +211,9 @@ static void Prj_ShowProjectDepartment (const struct Prj_Projects *Projects,
static void Prj_ShowProjectReviewStatus (struct Prj_Projects *Projects, static void Prj_ShowProjectReviewStatus (struct Prj_Projects *Projects,
const char *ClassLabel, const char *ClassLabel,
const char *ClassData, const char *ClassData,
const struct Prj_Faults *Faults,
const char *Anchor); const char *Anchor);
static void Prj_FormChangeReviewStatus (struct Prj_Projects *Projects, static void Prj_PutSelectorReviewStatus (struct Prj_Projects *Projects);
const char *Anchor);
static bool Prj_CheckIfICanReviewProjects (void); static bool Prj_CheckIfICanReviewProjects (void);
static void Prj_ShowProjectAssigned (const struct Prj_Projects *Projects, static void Prj_ShowProjectAssigned (const struct Prj_Projects *Projects,
const char *ClassLabel, const char *ClassLabel,
@ -1400,7 +1402,7 @@ static void Prj_ShowProjectRow (struct Prj_Projects *Projects,
Prj_ShowProjectFirstRow (Projects,ClassData,&Faults,NumIndex,UniqueId,Anchor); Prj_ShowProjectFirstRow (Projects,ClassData,&Faults,NumIndex,UniqueId,Anchor);
/***** Review status *****/ /***** Review status *****/
Prj_ShowProjectReviewStatus (Projects,ClassLabel,ClassData,Anchor); Prj_ShowProjectReviewStatus (Projects,ClassLabel,ClassData,&Faults,Anchor);
/***** Assigned? *****/ /***** Assigned? *****/
Prj_ShowProjectAssigned (Projects,ClassLabel,ClassData,&Faults); Prj_ShowProjectAssigned (Projects,ClassLabel,ClassData,&Faults);
@ -1624,10 +1626,26 @@ static void Prj_ShowProjectDepartment (const struct Prj_Projects *Projects,
static void Prj_ShowProjectReviewStatus (struct Prj_Projects *Projects, static void Prj_ShowProjectReviewStatus (struct Prj_Projects *Projects,
const char *ClassLabel, const char *ClassLabel,
const char *ClassData, const char *ClassData,
const struct Prj_Faults *Faults,
const char *Anchor) const char *Anchor)
{ {
extern const char *Txt_Review; extern const char *Txt_Review;
extern const char *Txt_PROJECT_REVIEW_SINGUL[Prj_NUM_REVIEW_STATUS]; extern const char *Txt_PROJECT_REVIEW_SINGUL[Prj_NUM_REVIEW_STATUS];
extern const char *Txt_Comments;
bool PutForm;
static unsigned UniqueId = 0;
char *Id;
/***** Check if put form to change review *****/
switch (Projects->View)
{
case Prj_PRINT_ONE_PROJECT:
PutForm = false;
break;
default:
PutForm = Prj_CheckIfICanReviewProjects ();
break;
}
HTM_TR_Begin (NULL); HTM_TR_Begin (NULL);
@ -1657,20 +1675,85 @@ static void Prj_ShowProjectReviewStatus (struct Prj_Projects *Projects,
break; break;
} }
if (Prj_CheckIfICanReviewProjects ()) if (PutForm)
/* Form to change review status */ {
Prj_FormChangeReviewStatus (Projects,Anchor); /***** Begin form to change review status and text *****/
else Frm_BeginFormAnchor (ActChgPrjRev,Anchor);
HTM_TxtF ("%s&nbsp;",Txt_PROJECT_REVIEW_SINGUL[Projects->Prj.Review.Status]); Prj_PutCurrentParams (Projects);
/* /***** Selector to change review status *****/
if (Faults.WrongAssigned) Prj_PutSelectorReviewStatus (Projects);
Prj_PutWarningIcon (); }
*/ else
HTM_Txt (Txt_PROJECT_REVIEW_SINGUL[Projects->Prj.Review.Status]);
HTM_NBSP ();
Ico_PutIconOff (ReviewIcon[Projects->Prj.Review.Status].Icon, Ico_PutIconOff (ReviewIcon[Projects->Prj.Review.Status].Icon,
ReviewIcon[Projects->Prj.Review.Status].Color, ReviewIcon[Projects->Prj.Review.Status].Color,
Txt_PROJECT_REVIEW_SINGUL[Projects->Prj.Review.Status]); Txt_PROJECT_REVIEW_SINGUL[Projects->Prj.Review.Status]);
/***** Show warning icon depending on review status *****/
if (Faults->WrongReviewStatus)
Prj_PutWarningIcon ();
if (Projects->Prj.Review.Status != Prj_UNREVIEWED)
{
/***** Revision time *****/
HTM_NBSP ();
UniqueId++;
if (asprintf (&Id,"prj_date_%u",UniqueId) < 0)
Err_NotEnoughMemoryExit ();
HTM_DIV_Begin ("id=\"%s\" class=\"PRJ_DATE\"",Id);
Dat_WriteLocalDateHMSFromUTC (Id,Projects->Prj.Review.Time,
Gbl.Prefs.DateFormat,Dat_SEPARATOR_COMMA,
true,true,false,0x6);
HTM_DIV_End ();
free (Id);
/***** Show warning icon depending on modify time *****/
if (Faults->WrongModifTime)
Prj_PutWarningIcon ();
/***** Revision text *****/
if (PutForm)
{
/* Show text form */
HTM_BR ();
HTM_TEXTAREA_Begin ("name=\"ReviewTxt\" rows=\"1\""
" class=\"TITLE_DESCRIPTION_WIDTH INPUT_%s\""
" placeholder=\"%s&hellip;\""
" onchange=\"document.getElementById('%s').submit();return false;\"",
The_GetSuffix (),
Txt_Comments,
Gbl.Form.Id);
HTM_Txt (Projects->Prj.Review.Txt);
HTM_TEXTAREA_End ();
}
else if (Projects->Prj.Review.Status != Prj_UNREVIEWED &&
Projects->Prj.Review.Txt[0])
{
/* Change text format */
Str_ChangeFormat (Str_FROM_HTML,Str_TO_RIGOROUS_HTML,
Projects->Prj.Review.Txt,Cns_MAX_BYTES_TEXT,false); // Convert from HTML to recpectful HTML
switch (Projects->View)
{
case Prj_PRINT_ONE_PROJECT:
break;
default:
ALn_InsertLinks (Projects->Prj.Review.Txt,Cns_MAX_BYTES_TEXT,60); // Insert links
break;
}
/* Show text */
HTM_BR ();
HTM_Txt (Projects->Prj.Review.Txt);
}
}
/****** End form *****/
if (PutForm)
Frm_EndForm ();
HTM_TD_End (); HTM_TD_End ();
HTM_TR_End (); HTM_TR_End ();
@ -1680,35 +1763,27 @@ static void Prj_ShowProjectReviewStatus (struct Prj_Projects *Projects,
/******************** Form to lock/unlock project edition ********************/ /******************** Form to lock/unlock project edition ********************/
/*****************************************************************************/ /*****************************************************************************/
static void Prj_FormChangeReviewStatus (struct Prj_Projects *Projects, static void Prj_PutSelectorReviewStatus (struct Prj_Projects *Projects)
const char *Anchor)
{ {
extern const char *Txt_PROJECT_REVIEW_SINGUL[Prj_NUM_REVIEW_STATUS]; extern const char *Txt_PROJECT_REVIEW_SINGUL[Prj_NUM_REVIEW_STATUS];
Prj_ReviewStatus_t ReviewStatus; Prj_ReviewStatus_t ReviewStatus;
unsigned ReviewStatusUnsigned; unsigned ReviewStatusUnsigned;
/***** Form to change review status and text *****/ /* Selector for review status */
Frm_BeginFormAnchor (ActChgPrjRev,Anchor); HTM_SELECT_Begin (HTM_SUBMIT_ON_CHANGE,
Prj_PutCurrentParams (Projects); "id=\"ReviewStatus\" name=\"ReviewStatus\""
" class=\"INPUT_%s\"",
/* Selector for review status */ The_GetSuffix ());
HTM_SELECT_Begin (HTM_SUBMIT_ON_CHANGE, for (ReviewStatus = (Prj_ReviewStatus_t) 0;
"id=\"ReviewStatus\" name=\"ReviewStatus\"" ReviewStatus <= (Prj_ReviewStatus_t) (Prj_NUM_REVIEW_STATUS - 1);
" class=\"INPUT_%s\"", ReviewStatus++)
The_GetSuffix ()); {
for (ReviewStatus = (Prj_ReviewStatus_t) 0; ReviewStatusUnsigned = (unsigned) ReviewStatus;
ReviewStatus <= (Prj_ReviewStatus_t) (Prj_NUM_REVIEW_STATUS - 1); HTM_OPTION (HTM_Type_UNSIGNED,&ReviewStatusUnsigned,
ReviewStatus++) ReviewStatus == Projects->Prj.Review.Status,false,
{ "%s",Txt_PROJECT_REVIEW_SINGUL[ReviewStatus]);
ReviewStatusUnsigned = (unsigned) ReviewStatus; }
HTM_OPTION (HTM_Type_UNSIGNED,&ReviewStatusUnsigned, HTM_SELECT_End ();
ReviewStatus == Projects->Prj.Review.Status,false,
"%s",Txt_PROJECT_REVIEW_SINGUL[ReviewStatus]);
}
HTM_SELECT_End ();
// Btn_PutConfirmButtonInline ("Cambiar");
Frm_EndForm ();
} }
/*****************************************************************************/ /*****************************************************************************/
@ -2257,6 +2332,8 @@ static void Prj_CheckIfPrjIsFaulty (long PrjCod,struct Prj_Faults *Faults)
bool IsAssigned; bool IsAssigned;
bool HasTitle; bool HasTitle;
bool HasDescription; bool HasDescription;
bool IsUnapproved;
bool ModifiedAfterReview;
unsigned NumProposedStds; unsigned NumProposedStds;
unsigned NumStdsRegisteredInPrj; unsigned NumStdsRegisteredInPrj;
@ -2287,6 +2364,12 @@ static void Prj_CheckIfPrjIsFaulty (long PrjCod,struct Prj_Faults *Faults)
HasTitle = (row[2][0] != '0'); HasTitle = (row[2][0] != '0');
HasDescription = (row[3][0] != '0'); HasDescription = (row[3][0] != '0');
/* Get if project is unnaproved (row[4]) */
IsUnapproved = (row[4][0] != '0');
/* Get if project has been modified after review (row[5]) */
ModifiedAfterReview = (row[5][0] != '0');
/***** Check faults *****/ /***** Check faults *****/
/* 1. Check title */ /* 1. Check title */
Faults->WrongTitle = !HasTitle; Faults->WrongTitle = !HasTitle;
@ -2309,16 +2392,22 @@ static void Prj_CheckIfPrjIsFaulty (long PrjCod,struct Prj_Faults *Faults)
// A non assigned project should not have students registered in it // A non assigned project should not have students registered in it
Faults->WrongAssigned = (NumStdsRegisteredInPrj != 0); Faults->WrongAssigned = (NumStdsRegisteredInPrj != 0);
} }
/* 4. Check review status */
Faults->WrongReviewStatus = IsUnapproved;
Faults->WrongModifTime = ModifiedAfterReview;
} }
/***** Free structure that stores the query result *****/ /***** Free structure that stores the query result *****/
DB_FreeMySQLResult (&mysql_res); DB_FreeMySQLResult (&mysql_res);
} }
Faults->PrjIsFaulty = Faults->WrongTitle || Faults->PrjIsFaulty = Faults->WrongTitle ||
Faults->WrongDescription || Faults->WrongDescription ||
Faults->WrongNumStds || Faults->WrongNumStds ||
Faults->WrongAssigned; Faults->WrongAssigned ||
Faults->WrongReviewStatus ||
Faults->WrongModifTime;
} }
/*****************************************************************************/ /*****************************************************************************/
@ -4480,11 +4569,8 @@ void Prj_ChangeReviewStatus (void)
if (Prj_CheckIfICanReviewProjects ()) if (Prj_CheckIfICanReviewProjects ())
{ {
Projects.Prj.Review.Status = Prj_GetHiddenParamReviewStatus (); Projects.Prj.Review.Status = Prj_GetHiddenParamReviewStatus ();
Projects.Prj.Review.Txt[0] = '\0'; // TODO: Get from parameter Par_GetParToHTML ("ReviewTxt",Projects.Prj.Review.Txt,Cns_MAX_BYTES_TEXT); // Store in HTML format (not rigorous)
Prj_DB_UpdateReview (&Projects.Prj); Prj_DB_UpdateReview (&Projects.Prj);
/*
Ale_ShowAlert (Ale_INFO,"Recibida nueva revisi&oacute;n del proyecto = %u.",
(unsigned) Projects.Prj.Review.Status); */
} }
else else
Err_NoPermissionExit (); Err_NoPermissionExit ();

View File

@ -603,12 +603,16 @@ unsigned Prj_DB_GetPrjDataToCheckFaults (MYSQL_RES **mysql_res,long PrjCod)
{ {
return (unsigned) return (unsigned)
DB_QuerySELECT (mysql_res,"can not get project data", DB_QuerySELECT (mysql_res,"can not get project data",
"SELECT Assigned='Y'," // row[0] = 0 / 1 "SELECT Assigned='Y'," // row[0] = 0 / 1
"NumStds," // row[1] = "NumStds," // row[1] =
"Title<>''," // row[2] = 0 / 1 "Title<>''," // row[2] = 0 / 1
"Description<>''" // row[3] = 0 / 1 "Description<>''," // row[3] = 0 / 1
"ReviewStatus='%s'," // row[4] = 0 / 1
"ReviewStatus<>'%s' AND ModifTime>ReviewTime" // row[5] = 0 / 1
" FROM prj_projects" " FROM prj_projects"
" WHERE PrjCod=%ld", " WHERE PrjCod=%ld",
Prj_ReviewStatus_DB[Prj_UNAPPROVED],
Prj_ReviewStatus_DB[Prj_UNREVIEWED],
PrjCod); PrjCod);
} }