added persistent and cant_close to PA_JobManager_FE_Message, used them from pa_job_manager to set status messages with persistence/close buttons appropriately for items like fix_dups/stale_jobs. When "fixing" now, the persistent Status message stays, but its now positioned approx. below the navbar on the right and is ok. Started on changing status to a more sensible naming conventions (away from alert to level) - more work to complete this
This commit is contained in:
15
TODO
15
TODO
@@ -1,17 +1,7 @@
|
|||||||
### GENERAL
|
### GENERAL
|
||||||
* get all status messages to use toasts AND get func to also increase/descrease the job counter as appropriate)
|
* get all status messages to use toasts AND get func to also increase/descrease the job counter as appropriate)
|
||||||
- [DONE] all (success/creation) status messages use toasts
|
- [DONE] all (success/creation) status messages use toasts
|
||||||
-- [DONE] make a helper func for setting toast body and use it in base.html && file_support.js
|
-- [TODO] ensure all pa_job_mgr jobs are sending messages back to the FE -- SHOULD??? I just hook FinishJob???
|
||||||
-- [DONE] make a helper func for setting 'Active Jobs' text/badge and call it when document ready (rather/both than start of base.html)
|
|
||||||
-- [DONE] trigger a timeout to play back pa_job_mgr message to FE and reset 'Active Jobs' text/badge until it hits 0
|
|
||||||
-- [DONE] (re)start this code if any new jobs is created (on move ONLY FOR NOW
|
|
||||||
-- [DONE] make js StatusMsg() take a 'data' (json response) and process that
|
|
||||||
-- [DONE] make it include message from the API endpoint doing the work, not in the js code...
|
|
||||||
-- [TODO] fix base.html to only call toast() and only in document.ready()
|
|
||||||
-- [DONE] this means handling danger, and persistent / no time-out toast()s
|
|
||||||
-- [DONE] warning works now (colors, etc.)
|
|
||||||
-- [DONE] clean up has to be a POST back to server to clear DB (jscript/async has no other way)
|
|
||||||
-- [TODO] go through the crazy persistent status msgs for checkdups, etc. and make sure they all work
|
|
||||||
|
|
||||||
* should be using jsonify to return real json to my API calls, e.g:
|
* should be using jsonify to return real json to my API calls, e.g:
|
||||||
use make_response( jsonify (... ) )
|
use make_response( jsonify (... ) )
|
||||||
@@ -19,7 +9,8 @@
|
|||||||
all GETs stay as is for now (as they expect a html reply, not data, and then html is base.html+ and it handles the status)
|
all GETs stay as is for now (as they expect a html reply, not data, and then html is base.html+ and it handles the status)
|
||||||
-- ONLY time this will fail is multiple status messages (which can occur I believe if a Wake of job mgr and then a job is created in DB, the success will only be shown)
|
-- ONLY time this will fail is multiple status messages (which can occur I believe if a Wake of job mgr and then a job is created in DB, the success will only be shown)
|
||||||
-- [TODO] simple fix will be to get 'hidden' jobs (wake job_mgr and maybe? metadata) to post failure events to the JobMgr_FE DB queue
|
-- [TODO] simple fix will be to get 'hidden' jobs (wake job_mgr and maybe? metadata) to post failure events to the JobMgr_FE DB queue
|
||||||
-- [TODO] when ALL converted, replace 'alert="..."' with 'status="..."'
|
-- [TODO] -- change class Status to class UILog
|
||||||
|
-- [TODO] -- change alert to level
|
||||||
|
|
||||||
* delete files should behave like /move_files (stay on same page) as well as the status messages above
|
* delete files should behave like /move_files (stay on same page) as well as the status messages above
|
||||||
|
|
||||||
|
|||||||
2
files.py
2
files.py
@@ -593,7 +593,7 @@ def move_files():
|
|||||||
return make_response( jsonify(
|
return make_response( jsonify(
|
||||||
job_id=job.id,
|
job_id=job.id,
|
||||||
message=f"Created <a class='link-light' href=/job/{job.id}>Job #{job.id}</a> to move selected file(s)",
|
message=f"Created <a class='link-light' href=/job/{job.id}>Job #{job.id}</a> to move selected file(s)",
|
||||||
status="success", alert="success" ) )
|
level="success", alert="success", persistent=False, cant_close=False ) )
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@app.route("/viewlist", methods=["POST"])
|
@app.route("/viewlist", methods=["POST"])
|
||||||
|
|||||||
@@ -3,11 +3,14 @@ var next_toast_id=1
|
|||||||
|
|
||||||
function NewToast(data)
|
function NewToast(data)
|
||||||
{
|
{
|
||||||
|
console.log(data)
|
||||||
// make new div, include data.alert as background colour, and data.message as toast body
|
// make new div, include data.alert as background colour, and data.message as toast body
|
||||||
d_id='st' + String(next_toast_id)
|
d_id='st' + String(next_toast_id)
|
||||||
div='<div id="' + d_id + '"'
|
div='<div id="' + d_id + '"'
|
||||||
if( data.persistent === true )
|
if( data.persistent === true )
|
||||||
div+=' data-bs-autohide="false"'
|
div+=' data-bs-autohide="false"'
|
||||||
|
if( data.job_id !== undefined )
|
||||||
|
div+=' job_id=' + String(data.job_id)
|
||||||
div +=' class="toast hide align-items-center border-0'
|
div +=' class="toast hide align-items-center border-0'
|
||||||
if( data.alert == "success" || data.alert == "danger" )
|
if( data.alert == "success" || data.alert == "danger" )
|
||||||
div += ' text-white'
|
div += ' text-white'
|
||||||
@@ -42,6 +45,7 @@ function NewToast(data)
|
|||||||
// can reuse any that are hidden, OR, create a new one by appending as needed (so we can have 2+ toasts on screen)
|
// can reuse any that are hidden, OR, create a new one by appending as needed (so we can have 2+ toasts on screen)
|
||||||
function StatusMsg(st)
|
function StatusMsg(st)
|
||||||
{
|
{
|
||||||
|
console.log('StatusMsg' + st )
|
||||||
el=NewToast(st)
|
el=NewToast(st)
|
||||||
$('#' + el ).toast("show")
|
$('#' + el ).toast("show")
|
||||||
// if there is a job_id, then clear the message for it or it will be picked up again on reload
|
// if there is a job_id, then clear the message for it or it will be picked up again on reload
|
||||||
@@ -49,7 +53,11 @@ function StatusMsg(st)
|
|||||||
// now, we will do this to get a first pass working
|
// now, we will do this to get a first pass working
|
||||||
if( st.job_id !== undefined )
|
if( st.job_id !== undefined )
|
||||||
{
|
{
|
||||||
$.ajax( { type: 'POST', url: '/clearmsgforjob/'+st.job_id, success: function(data) { } } )
|
console.log( 'set hidden.bs.toast handler for: ' + st.job_id )
|
||||||
|
$('#' + el).on( 'hidden.bs.toast',
|
||||||
|
function() {
|
||||||
|
$.ajax( { type: 'POST', url: '/clearmsgforjob/'+st.job_id, success: function(data) { console.log('cleared job id' )} } )
|
||||||
|
} )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
9
job.py
9
job.py
@@ -74,6 +74,8 @@ class PA_JobManager_Message(db.Model):
|
|||||||
job_id = db.Column(db.Integer, db.ForeignKey('job.id') )
|
job_id = db.Column(db.Integer, db.ForeignKey('job.id') )
|
||||||
alert = db.Column(db.String)
|
alert = db.Column(db.String)
|
||||||
message = db.Column(db.String)
|
message = db.Column(db.String)
|
||||||
|
persistent = db.Column(db.Boolean)
|
||||||
|
cant_close = db.Column(db.Boolean)
|
||||||
job = db.relationship ("Job" )
|
job = db.relationship ("Job" )
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return f"<id: {self.id}, job_id: {self.job_id}, alert: {self.alert}, message: {self.message}, job: {self.job}"
|
return f"<id: {self.id}, job_id: {self.job_id}, alert: {self.alert}, message: {self.message}, job: {self.job}"
|
||||||
@@ -90,6 +92,8 @@ def GetJM_Message():
|
|||||||
# ClearJM_Message: used in html to clear any message just displayed
|
# ClearJM_Message: used in html to clear any message just displayed
|
||||||
################################################################################
|
################################################################################
|
||||||
def ClearJM_Message(id):
|
def ClearJM_Message(id):
|
||||||
|
print(f"DDP: DID NOT clear JM message: {id}" )
|
||||||
|
return
|
||||||
PA_JobManager_Message.query.filter(PA_JobManager_Message.id==id).delete()
|
PA_JobManager_Message.query.filter(PA_JobManager_Message.id==id).delete()
|
||||||
db.session.commit()
|
db.session.commit()
|
||||||
return
|
return
|
||||||
@@ -307,12 +311,11 @@ def joblog_search():
|
|||||||
@login_required
|
@login_required
|
||||||
def CheckForJobs():
|
def CheckForJobs():
|
||||||
num=GetNumActiveJobs()
|
num=GetNumActiveJobs()
|
||||||
|
print( f"called: /checkforjobs -- num={num}" )
|
||||||
sts=[]
|
sts=[]
|
||||||
print("CheckForJobs called" )
|
|
||||||
for msg in PA_JobManager_Message.query.all():
|
for msg in PA_JobManager_Message.query.all():
|
||||||
print("there is a PA_J_MGR status message" )
|
|
||||||
u='<a class="link-light" href="' + url_for('joblog', id=msg.job_id) + '">Job # ' + str(msg.job_id) + '</a>: '
|
u='<a class="link-light" href="' + url_for('joblog', id=msg.job_id) + '">Job # ' + str(msg.job_id) + '</a>: '
|
||||||
sts.append( { 'message': u+msg.message, 'alert': msg.alert, 'job_id': msg.job_id } )
|
sts.append( { 'message': u+msg.message, 'alert': msg.alert, 'job_id': msg.job_id, 'persistent': msg.persistent, 'cant_close': msg.cant_close } )
|
||||||
return make_response( jsonify( num_active_jobs=num, sts=sts ) )
|
return make_response( jsonify( num_active_jobs=num, sts=sts ) )
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|||||||
@@ -503,6 +503,8 @@ class PA_JobManager_FE_Message(Base):
|
|||||||
job_id = Column(Integer, ForeignKey('job.id') )
|
job_id = Column(Integer, ForeignKey('job.id') )
|
||||||
alert = Column(String)
|
alert = Column(String)
|
||||||
message = Column(String)
|
message = Column(String)
|
||||||
|
persistent = Column(Boolean)
|
||||||
|
cant_close = Column(Boolean)
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "<id: {}, job_id: {}, alert: {}, message: {}".format(self.id, self.job_id, self.alert, self.message)
|
return "<id: {}, job_id: {}, alert: {}, message: {}".format(self.id, self.job_id, self.alert, self.message)
|
||||||
|
|
||||||
@@ -561,8 +563,8 @@ def NewJob(name, num_files=0, wait_for=None, jex=None, parent_job=None ):
|
|||||||
# MessageToFE(): sends a specific alert/messasge for a given job via the DB to
|
# MessageToFE(): sends a specific alert/messasge for a given job via the DB to
|
||||||
# the front end
|
# the front end
|
||||||
##############################################################################
|
##############################################################################
|
||||||
def MessageToFE( job_id, alert, message ):
|
def MessageToFE( job_id, alert, message, persistent, cant_close ):
|
||||||
msg = PA_JobManager_FE_Message( job_id=job_id, alert=alert, message=message)
|
msg = PA_JobManager_FE_Message( job_id=job_id, alert=alert, message=message, persistent=persistent, cant_close=cant_close)
|
||||||
session.add(msg)
|
session.add(msg)
|
||||||
session.commit()
|
session.commit()
|
||||||
return msg.id
|
return msg.id
|
||||||
@@ -904,7 +906,7 @@ def HandleJobs(first_run=False):
|
|||||||
job.pa_job_state = 'Stale'
|
job.pa_job_state = 'Stale'
|
||||||
session.add(job)
|
session.add(job)
|
||||||
AddLogForJob( job, "ERROR: Job has been marked stale as it did not complete" )
|
AddLogForJob( job, "ERROR: Job has been marked stale as it did not complete" )
|
||||||
MessageToFE( job.id, "danger", f'Stale job, click <a href="javascript:document.body.innerHTML+=\'<form id=_fm method=GET action=/stale_jobs></form>\'; document.getElementById(\'_fm\').submit();">here</a> to restart or cancel' )
|
MessageToFE( job.id, "danger", f'Stale job, click <a href="javascript:document.body.innerHTML+=\'<form id=_fm method=GET action=/stale_jobs></form>\'; document.getElementById(\'_fm\').submit();">here</a> to restart or cancel', True, False )
|
||||||
session.commit()
|
session.commit()
|
||||||
continue
|
continue
|
||||||
if job.pa_job_state == 'New':
|
if job.pa_job_state == 'New':
|
||||||
@@ -930,7 +932,7 @@ def HandleJobs(first_run=False):
|
|||||||
# threading.Thread(target=RunJob, args=(job,)).start()
|
# threading.Thread(target=RunJob, args=(job,)).start()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
try:
|
try:
|
||||||
MessageToFE( job.id, "danger", "Failed with: {} (try job log for details)".format(e) )
|
MessageToFE( job.id, "danger", "Failed with: {} (try job log for details)".format(e), True, False )
|
||||||
except Exception as e2:
|
except Exception as e2:
|
||||||
print("ERROR: Failed to let front-end know, but back-end Failed to run job (id: {}, name: {} -- orig exep was: {}, this exception was: {})".format( job.id, job.name, e, e2) )
|
print("ERROR: Failed to let front-end know, but back-end Failed to run job (id: {}, name: {} -- orig exep was: {}, this exception was: {})".format( job.id, job.name, e, e2) )
|
||||||
print("INFO: PA job manager is waiting for a job")
|
print("INFO: PA job manager is waiting for a job")
|
||||||
@@ -954,7 +956,7 @@ def JobScanNow(job):
|
|||||||
JobProgressState( job, "In Progress" )
|
JobProgressState( job, "In Progress" )
|
||||||
ProcessImportDirs(job)
|
ProcessImportDirs(job)
|
||||||
FinishJob( job, "Completed (scan for new files)" )
|
FinishJob( job, "Completed (scan for new files)" )
|
||||||
MessageToFE( job.id, "success", "Completed (scan for new files)" )
|
MessageToFE( job.id, "success", "Completed (scan for new files)", False, False )
|
||||||
return
|
return
|
||||||
|
|
||||||
##############################################################################
|
##############################################################################
|
||||||
@@ -964,7 +966,7 @@ def JobScanStorageDir(job):
|
|||||||
JobProgressState( job, "In Progress" )
|
JobProgressState( job, "In Progress" )
|
||||||
ProcessStorageDirs(job)
|
ProcessStorageDirs(job)
|
||||||
FinishJob( job, "Completed (scan for new files)" )
|
FinishJob( job, "Completed (scan for new files)" )
|
||||||
MessageToFE( job.id, "success", "Completed (scan for new files)" )
|
MessageToFE( job.id, "success", "Completed (scan for new files)", False, False )
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
@@ -1078,7 +1080,7 @@ def JobForceScan(job):
|
|||||||
ProcessImportDirs(job)
|
ProcessImportDirs(job)
|
||||||
ProcessStorageDirs(job)
|
ProcessStorageDirs(job)
|
||||||
FinishJob(job, "Completed (forced remove and recreation of all file data)")
|
FinishJob(job, "Completed (forced remove and recreation of all file data)")
|
||||||
MessageToFE( job.id, "success", "Completed (forced remove and recreation of all file data)" )
|
MessageToFE( job.id, "success", "Completed (forced remove and recreation of all file data)", False, False )
|
||||||
return
|
return
|
||||||
|
|
||||||
##############################################################################
|
##############################################################################
|
||||||
@@ -1319,6 +1321,10 @@ def MoveFileToRecycleBin(job,del_me):
|
|||||||
bin_path=session.query(Path).join(PathType).filter(PathType.name=='Bin').first()
|
bin_path=session.query(Path).join(PathType).filter(PathType.name=='Bin').first()
|
||||||
parent_dir=session.query(Dir).join(PathDirLink).filter(PathDirLink.path_id==bin_path.id).first()
|
parent_dir=session.query(Dir).join(PathDirLink).filter(PathDirLink.path_id==bin_path.id).first()
|
||||||
|
|
||||||
|
# check/delete if we already have a deleted file of this name/number (only # happened in testing, but jic)
|
||||||
|
# 99.9% of the time, this will just delete nothing
|
||||||
|
session.query(DelFile).filter(DelFile.file_eid==del_me.id).delete()
|
||||||
|
|
||||||
# if we ever need to restore, lets remember this file's original path
|
# if we ever need to restore, lets remember this file's original path
|
||||||
# (use a string in case the dir/path is ever deleted from FS (and then DB) and we need to recreate)
|
# (use a string in case the dir/path is ever deleted from FS (and then DB) and we need to recreate)
|
||||||
del_file_details = DelFile( file_eid=del_me.id, orig_path_prefix=del_me.in_dir.in_path.path_prefix )
|
del_file_details = DelFile( file_eid=del_me.id, orig_path_prefix=del_me.in_dir.in_path.path_prefix )
|
||||||
@@ -2036,7 +2042,7 @@ def JobCheckForDups(job):
|
|||||||
for row in res:
|
for row in res:
|
||||||
if row.count > 0:
|
if row.count > 0:
|
||||||
AddLogForJob(job, f"Found duplicates, Creating Status message in front-end for attention")
|
AddLogForJob(job, f"Found duplicates, Creating Status message in front-end for attention")
|
||||||
MessageToFE( job.id, "danger", f'Found duplicate(s), click <a href="javascript:document.body.innerHTML+=\'<form id=_fm method=POST action=/fix_dups></form>\'; document.getElementById(\'_fm\').submit();">here</a> to finalise import by removing duplicates' )
|
MessageToFE( job.id, "danger", f'Found duplicate(s), click <a href="javascript:document.body.innerHTML+=\'<form id=_fm method=POST action=/fix_dups></form>\'; document.getElementById(\'_fm\').submit();">here</a> to finalise import by removing duplicates', True, True )
|
||||||
else:
|
else:
|
||||||
FinishJob(job, f"No duplicates found")
|
FinishJob(job, f"No duplicates found")
|
||||||
FinishJob(job, f"Finished looking for duplicates")
|
FinishJob(job, f"Finished looking for duplicates")
|
||||||
@@ -2107,7 +2113,8 @@ def JobRemoveDups(job):
|
|||||||
|
|
||||||
# Need to put another checkdups job in now to force / validate we have no dups
|
# Need to put another checkdups job in now to force / validate we have no dups
|
||||||
next_job=NewJob( "checkdups" )
|
next_job=NewJob( "checkdups" )
|
||||||
AddLogForJob(job, "adding <a href='/job/{}'>job id={} {}</a> to confirm there are no more duplicates".format( next_job.id, next_job.id, next_job.name ) )
|
AddLogForJob(job, f"adding <a href='/job/{next_job.id}'>job id={next_job.id} {next_job.name}</a> to confirm there are no more duplicates" )
|
||||||
|
MessageToFE( job.id, "success", f"Finished Job#{job.id} removing duplicate files", False, False )
|
||||||
return
|
return
|
||||||
|
|
||||||
####################################################################################################################################
|
####################################################################################################################################
|
||||||
@@ -2137,7 +2144,7 @@ def JobMoveFiles(job):
|
|||||||
move_me=session.query(Entry).get(jex.value)
|
move_me=session.query(Entry).get(jex.value)
|
||||||
MoveEntriesToOtherFolder( job, move_me, dst_storage_path, f"{prefix}{suffix}" )
|
MoveEntriesToOtherFolder( job, move_me, dst_storage_path, f"{prefix}{suffix}" )
|
||||||
next_job=NewJob( "checkdups" )
|
next_job=NewJob( "checkdups" )
|
||||||
MessageToFE( job.id, "success", "Completed (move of selected files)" )
|
MessageToFE( job.id, "success", "Completed (move of selected files)", False, False )
|
||||||
FinishJob(job, f"Finished move selected file(s)")
|
FinishJob(job, f"Finished move selected file(s)")
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -2152,7 +2159,7 @@ def JobDeleteFiles(job):
|
|||||||
del_me=session.query(Entry).join(File).filter(Entry.id==jex.value).first()
|
del_me=session.query(Entry).join(File).filter(Entry.id==jex.value).first()
|
||||||
MoveFileToRecycleBin(job,del_me)
|
MoveFileToRecycleBin(job,del_me)
|
||||||
next_job=NewJob( "checkdups" )
|
next_job=NewJob( "checkdups" )
|
||||||
MessageToFE( job.id, "success", "Completed (delete of selected files)" )
|
MessageToFE( job.id, "success", "Completed (delete of selected files)", False, False )
|
||||||
FinishJob(job, f"Finished deleting selected file(s)")
|
FinishJob(job, f"Finished deleting selected file(s)")
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -2167,7 +2174,7 @@ def JobRestoreFiles(job):
|
|||||||
restore_me=session.query(Entry).join(File).filter(Entry.id==jex.value).first()
|
restore_me=session.query(Entry).join(File).filter(Entry.id==jex.value).first()
|
||||||
RestoreFile(job,restore_me)
|
RestoreFile(job,restore_me)
|
||||||
next_job=NewJob( "checkdups" )
|
next_job=NewJob( "checkdups" )
|
||||||
MessageToFE( job.id, "success", "Completed (restore of selected files)" )
|
MessageToFE( job.id, "success", "Completed (restore of selected files)", False, False )
|
||||||
FinishJob(job, f"Finished restoring selected file(s)")
|
FinishJob(job, f"Finished restoring selected file(s)")
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|||||||
10
status.py
10
status.py
@@ -5,18 +5,18 @@ from shared import PA
|
|||||||
# including when duplicates are found on import. These status messages are exposed into
|
# including when duplicates are found on import. These status messages are exposed into
|
||||||
# the html files, and they show once for success/green, and sticky for danger/red
|
# the html files, and they show once for success/green, and sticky for danger/red
|
||||||
class Status(PA):
|
class Status(PA):
|
||||||
alert="success"
|
level="success"
|
||||||
message=""
|
message=""
|
||||||
|
|
||||||
def GetAlert(self):
|
def GetAlert(self):
|
||||||
return self.alert
|
return self.level
|
||||||
|
|
||||||
def GetMessage(self):
|
def GetMessage(self):
|
||||||
return self.message
|
return self.message
|
||||||
|
|
||||||
def SetMessage(self, msg, al="success"):
|
def SetMessage(self, msg, l="success"):
|
||||||
self.message=msg
|
self.message=msg
|
||||||
self.alert=al
|
self.level=l
|
||||||
return
|
return
|
||||||
|
|
||||||
def AppendMessage(self, msg):
|
def AppendMessage(self, msg):
|
||||||
@@ -24,7 +24,7 @@ class Status(PA):
|
|||||||
return
|
return
|
||||||
|
|
||||||
def ClearStatus(self):
|
def ClearStatus(self):
|
||||||
self.alert="success"
|
self.level="success"
|
||||||
self.message=""
|
self.message=""
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
|
|||||||
@@ -160,7 +160,7 @@ create table JOBEXTRA ( ID integer, JOB_ID integer, NAME varchar(32), VALUE varc
|
|||||||
create table JOBLOG ( ID integer, JOB_ID integer, LOG_DATE timestamptz, LOG varchar,
|
create table JOBLOG ( ID integer, JOB_ID integer, LOG_DATE timestamptz, LOG varchar,
|
||||||
constraint PK_JL_ID primary key(ID), constraint FK_JL_JOB_ID foreign key(JOB_ID) references JOB(ID) );
|
constraint PK_JL_ID primary key(ID), constraint FK_JL_JOB_ID foreign key(JOB_ID) references JOB(ID) );
|
||||||
|
|
||||||
create table PA_JOB_MANAGER_FE_MESSAGE ( ID integer, JOB_ID integer, ALERT varchar(16), MESSAGE varchar(1024),
|
create table PA_JOB_MANAGER_FE_MESSAGE ( ID integer, JOB_ID integer, ALERT varchar(16), MESSAGE varchar(1024), PERSISTENT boolean, CANT_CLOSE boolean,
|
||||||
constraint PA_JOB_MANAGER_FE_ACKS_ID primary key(ID),
|
constraint PA_JOB_MANAGER_FE_ACKS_ID primary key(ID),
|
||||||
constraint FK_PA_JOB_MANAGER_FE_MESSAGE_JOB_ID foreign key(JOB_ID) references JOB(ID) );
|
constraint FK_PA_JOB_MANAGER_FE_MESSAGE_JOB_ID foreign key(JOB_ID) references JOB(ID) );
|
||||||
|
|
||||||
|
|||||||
@@ -128,40 +128,14 @@
|
|||||||
</div class="collapse navbar-collapse">
|
</div class="collapse navbar-collapse">
|
||||||
</div class="container-fluid">
|
</div class="container-fluid">
|
||||||
</nav>
|
</nav>
|
||||||
|
{% endif %} {# not InDBox #}
|
||||||
{% if GetJM_Message() != None %}
|
|
||||||
{% set msg=GetJM_Message() %}
|
|
||||||
<!-- if we are fixing things dont put up alert -->
|
|
||||||
{% if request.endpoint != "fix_dups" and request.endpoint != "rm_dups" and request.endpoint != "stale_jobs" %}
|
|
||||||
{% if msg.alert != "success" %}
|
|
||||||
<div class="py-2 mx-1 alert alert-{{msg.alert}}">
|
|
||||||
{% if msg.job.name != "checkdups" %}
|
|
||||||
<form id="_dismiss" action="{{url_for('clear_jm_msg', id=msg.id)}}" method="POST">
|
|
||||||
<button type="button" class="close btn border-secondary me-3" aria-label="Close" onClick="$('#_dismiss').submit()">
|
|
||||||
<span aria-hidden="true">×</span>
|
|
||||||
</button>
|
|
||||||
{% endif %}
|
|
||||||
{% if msg.job_id %}
|
|
||||||
<a href="{{url_for('joblog', id=msg.job_id)}}">Job #{{msg.job_id}}</a>:
|
|
||||||
{% endif %}
|
|
||||||
{{msg.message|safe}}
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
{# if a JM is a danger message, allow code to remove the status, it should be 'permanent' until addressed -- e.g. you have duplicates, fix them #}
|
|
||||||
{% if msg.alert != "danger" %}
|
|
||||||
{% set dont_print=ClearJM_Message(msg.id) %}
|
|
||||||
{% endif %}
|
|
||||||
{% endif %}
|
|
||||||
{% endif %}
|
|
||||||
{% endif %}
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% block main_content %}
|
{% block main_content %}
|
||||||
{% endblock main_content %}
|
{% endblock main_content %}
|
||||||
|
|
||||||
{% if not InDBox %}
|
{% if not InDBox %}
|
||||||
{%block script_content %}{% endblock script_content %}
|
{%block script_content %}{% endblock script_content %}
|
||||||
<div id="status_container" class="position-fixed top-1 end-0 p-1" style="z-index: 11">
|
<div id="status_container" class="position-fixed top-0 end-0 p-1 my-5" "z-index: 11">
|
||||||
<div id="st1" class="toast hide align-items-center text-white bg-success border-0" role="alert" aria-live="assertive" aria-atomic="true">
|
<div id="st1" class="toast hide align-items-center text-white bg-success border-0" role="alert" aria-live="assertive" aria-atomic="true">
|
||||||
<div class="d-flex">
|
<div class="d-flex">
|
||||||
<div class="toast-body">
|
<div class="toast-body">
|
||||||
@@ -177,7 +151,6 @@
|
|||||||
msg = "{{ GetMessage()|safe }}"
|
msg = "{{ GetMessage()|safe }}"
|
||||||
msg=msg.replace('href=', 'class=link-light href=')
|
msg=msg.replace('href=', 'class=link-light href=')
|
||||||
st=Object; st.message=msg; st.alert='{{GetAlert()}}'; StatusMsg(st)
|
st=Object; st.message=msg; st.alert='{{GetAlert()}}'; StatusMsg(st)
|
||||||
alert( '{{GetAlert()}}' )
|
|
||||||
<!-- call ClearStatus: strictly not needed as we are near finished rendering, and any new page will lose it from memory (better to be explicit) -->
|
<!-- call ClearStatus: strictly not needed as we are near finished rendering, and any new page will lose it from memory (better to be explicit) -->
|
||||||
{{ ClearStatus() }}
|
{{ ClearStatus() }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|||||||
Reference in New Issue
Block a user