diff --git a/interactive-mining-madoap/madoap/src/madserverv2.py b/interactive-mining-madoap/madoap/src/madserverv2.py index 042864b..f6603ea 100755 --- a/interactive-mining-madoap/madoap/src/madserverv2.py +++ b/interactive-mining-madoap/madoap/src/madserverv2.py @@ -113,6 +113,41 @@ def numberOfDocsUploaded(user_id): return num_lines return 0 +def loadProfile(profileLocation, user_id): + # extract data from profile file + import sys + sys.path.append(msettings.MADIS_PATH) + import madis + # get the profile database cursor + cursor=madis.functions.Connection(profileLocation).cursor() + + # data to be sent + data = {} + # Write to csv file the grants ids + if len([r for r in cursor.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='grants'")]): + cursor.execute("output '/tmp/p{0}.tsv' select c1,c2 from grants".format(user_id)) + # Get the number of grants uploaded + file_name = "/tmp/p%s.tsv" % (user_id) + if os.path.isfile(file_name): + numberOfGrants = sum(1 for line in open(file_name)) + data['grants'] = numberOfGrants + # write to json the poswords + if len([r for r in cursor.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='poswords'")]): + results = [r for r in cursor.execute("select c1, c2 from poswords")] + data['poswords'] = {value:key for value, key in results} + # write to json the negwords + if len([r for r in cursor.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='negwords'")]): + results = [r for r in cursor.execute("select c1, c2 from negwords")] + data['negwords'] = {value:key for value, key in results} + # write to json the filters + if len([r for r in cursor.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='filters'")]): + results = [r for r in cursor.execute("select c1, c2 from filters")] + for value, key in results: + data[value] = key + # data['filters'] = {value:key for value, key in results} + cursor.close() + return data + def deleteAllUserFiles(user_id): if user_id: file_name = "/tmp/p%s.tsv" % (user_id) @@ -122,6 +157,22 @@ def deleteAllUserFiles(user_id): if os.path.isfile(file_name): os.remove(file_name) +def loadExampleDocs(user_id): + sample_file = open("static/exampleDocs.txt", 'r') + # write data to physical file + cname = "/tmp/docs{0}.json".format(user_id) + fh = open(cname, 'w') + while 1: + copy_buffer = sample_file.read(1048576) + if not copy_buffer: + break + fh.write(copy_buffer) + fh.close() + lines_num = sum(1 for line in open(cname)) + +def loadExampleProfile(user_id): + return loadProfile("static/exampleProfile.oamp", user_id) + class BaseHandler(ozhandler.DjangoErrorMixin, ozhandler.BasicAuthMixin, tornado.web.RequestHandler): def __init__(self, *args): @@ -322,6 +373,8 @@ class createUploadProfileHandler(BaseHandler): try: user_id = self.get_secure_cookie('madgikmining') if user_id is None: + self.set_status(400) + self.write("Missing cookie containing user's id...") return if 'upload' in self.request.files: # get file info and body from post data @@ -337,39 +390,23 @@ class createUploadProfileHandler(BaseHandler): fh = open(cname, 'w') fh.write(fileinfo['body']) fh.close() - # extract data from profile file - import sys - sys.path.append(msettings.MADIS_PATH) - import madis - # get the profile database cursor - cursor=madis.functions.Connection(cname).cursor() - - # data to be sent - data = {} - # Write to csv file the grants ids - if len([r for r in cursor.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='grants'")]): - cursor.execute("output '/tmp/p{0}.csv' select * from grants".format(user_id)) - numberOfGrants = numberOfGrantsUploaded(user_id, "puppet_value") - self.set_secure_cookie('madgikmining_grantsuploaded', str(numberOfGrants)) - data['grants'] = numberOfGrants - # write to json the poswords - if len([r for r in cursor.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='poswords'")]): - results = [r for r in cursor.execute("select c1, c2 from poswords")] - data['poswords'] = {value:key for value, key in results} - # write to json the negwords - if len([r for r in cursor.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='negwords'")]): - results = [r for r in cursor.execute("select c1, c2 from negwords")] - data['negwords'] = {value:key for value, key in results} - # write to json the filters - if len([r for r in cursor.execute("SELECT name FROM sqlite_master WHERE type='table' AND name='filters'")]): - results = [r for r in cursor.execute("select c1, c2 from filters")] - data['filters'] = {value:key for value, key in results} - cursor.close() + data = loadProfile(cname, user_id) + self.set_secure_cookie('madgikmining_grantsuploaded', str(data['grants'])) + self.write(json.dumps(data)) + self.finish() + elif 'example' in self.request.arguments: + # reset everything + deleteAllUserFiles(user_id) + # load example data + loadExampleDocs(user_id) + data = loadExampleProfile(user_id) + self.set_secure_cookie('madgikmining_grantsuploaded', str(data['grants'])) self.write(json.dumps(data)) self.finish() except Exception as ints: - self.write(json.dumps({'respond': "Something went very wrong!"})) + self.set_status(400) + self.write("Something is wrong with this profile file...") print ints return @@ -389,12 +426,15 @@ class uploadCodesHandler(BaseHandler): # reset everything deleteAllUserFiles(user_id) # check if he already uploaded his grants ids and inform him via a message - self.render('upload_codes.html', settings=msettings) + numOfGrants = numberOfGrantsUploaded(user_id, self.get_secure_cookie('madgikmining_grantsuploaded')) + self.render('upload_codes.html', settings=msettings, numOfGrants=numOfGrants) def post(self): try: # get user id from cookie. Must have user_id = self.get_secure_cookie('madgikmining') if user_id is None: + self.set_status(400) + self.write("Missing cookie containing user's id...") return # service to upload a tsv file with the codes. Returns the codes if 'upload' in self.request.files: @@ -404,7 +444,8 @@ class uploadCodesHandler(BaseHandler): extn = os.path.splitext(fname)[1] # must be .pdf or .json if extn != ".tsv" and extn != ".txt": - self.write(json.dumps({'respond': "File must be .tsv or .txt"})) + self.set_status(400) + self.write("File must be .tsv or .txt...") return codes = {} lines = fileinfo['body'].splitlines() @@ -440,7 +481,9 @@ class uploadCodesHandler(BaseHandler): # data to be sent data = {} if len(concepts) == 0: - data['error'] = "You have to provide at least one concept to continue" + self.set_status(400) + self.write("You have to provide at least one concept to continue!") + return else: data['respond'] = "{0} Codes loaded successfully!".format(len(concepts)) self.set_secure_cookie('madgikmining_grantsuploaded', str(len(concepts))) @@ -470,9 +513,8 @@ class uploadCodesHandler(BaseHandler): self.finish() except Exception as ints: - data = {} - data['error'] = "File Failed to Upload!" - self.write(json.dumps(data)) + self.set_status(400) + self.write("A server error occurred, please contact administrator!") self.finish() print ints return @@ -491,7 +533,7 @@ class configureProfileHandler(BaseHandler): return # check if he uploaded his codes if numberOfGrantsUploaded(user_id, self.get_secure_cookie('madgikmining_grantsuploaded')): - self.render('configure_profile.html', settings=msettings) + self.render('configure_profile2.html', settings=msettings) else: self.redirect('/upload-codes') def post(self): @@ -510,7 +552,9 @@ class configureProfileHandler(BaseHandler): data = {} # must be .pdf, .txt or .json if extn != ".pdf" and extn != ".txt" and extn != ".json": - data['error'] = "File must be .pdf, .json or .txt" + self.set_status(400) + self.write("File must be .pdf, .json or .txt") + return return # write data to physical file cname = "/tmp/docs{0}{1}".format(user_id, extn) @@ -523,14 +567,16 @@ class configureProfileHandler(BaseHandler): p = sub.Popen(['pdftotext', '-enc', 'UTF-8', cname],stdout=sub.PIPE,stderr=sub.PIPE) output, errors = p.communicate() if errors: - data['error'] = "Cannot convert .pdf to .txt" + self.set_status(400) + self.write("An error occurred when trying to convert .pdf to .txt...") return os.remove(cname) cname = "/tmp/docs{0}.txt".format(user_id) with open(cname, 'r') as fin: docData=fin.read().replace('\n', ' ') if len(docData)==0: - data['error'] = "Cannot convert .pdf to .txt" + self.set_status(400) + self.write("An error occurred when trying to convert .pdf to text...") return with open("/tmp/docs{0}.json".format(user_id), "wb") as fout: json.dump({"text":docData,"id":os.path.splitext(fname)[0]}, fout) @@ -543,13 +589,16 @@ class configureProfileHandler(BaseHandler): jsonlist.append(json.loads(line)) os.rename(cname, "/tmp/docs{0}.json".format(user_id)) except ValueError, e: - data['error'] = "File is not in a valid json format" + self.set_status(400) + self.write("File is not in a valid json format...") os.remove(cname) print e return file_name = "/tmp/docs%s.json" % (user_id) if os.path.isfile(file_name): - data['data'] = sum(1 for line in open(file_name)) + lines = sum(1 for line in open(file_name)) + data['respond'] = "{0} Documents loaded successfully!".format(lines) + data['data'] = lines self.write(json.dumps(data)) self.finish() # post case where the user selects form preset documents samples @@ -578,8 +627,11 @@ class configureProfileHandler(BaseHandler): # data to be sent data = {} if lines_num == 0: - data['error'] = "You have to provide at least one concept to continue" + self.set_status(400) + self.write("File must contain atleast one document...") + return else: + data['respond'] = "{0} Documents loaded successfully!".format(lines_num) data['data'] = lines_num self.write(json.dumps(data)) self.finish() @@ -598,8 +650,63 @@ class configureProfileHandler(BaseHandler): self.finish() # post case for the actual mining proccess else: + # get the database cursor + cursor=msettings.Connection.cursor() + # data to be sent data = {} + + # set the textwindow size + extracontextprev = 10 + extracontextnext = 10 + contextprev = 10 + contextnext = 5 + # Automatically find middle size from grant codes white spaces + querygrantsize = "select max(p1) from (select regexpcountwords('\s',stripchars(p1)) as p1 from (setschema 'p1,p2' file '/tmp/p{0}.tsv' dialect:tsv))".format(user_id) + contextmiddle = [r for r in cursor.execute(querygrantsize)][0][0]+1 + if 'contextprev' in self.request.arguments and self.request.arguments['contextprev'][0] != '': + contextprev = int(self.request.arguments['contextprev'][0]) + if contextprev < 0 or contextprev > 20: + self.set_status(400) + self.write("Context size must be in its limits...") + return + if 'contextnext' in self.request.arguments and self.request.arguments['contextnext'][0] != '': + contextnext = int(self.request.arguments['contextnext'][0]) + if contextnext < 0 or contextnext > 20: + self.set_status(400) + self.write("Context size must be in its limits...") + return + j2sextraprev = "j2s(prev1" + for cnt in xrange(2,extracontextprev+1): + j2sextraprev += ",prev"+str(cnt) + j2sextraprev += ")" + j2sprev = "" + j2scontext = "(" + if contextprev: + j2scontext = "j2s(prev"+str(extracontextprev+1) + j2sprev = "j2s(prev"+str(extracontextprev+1) + for cnt in xrange(extracontextprev+2,extracontextprev+contextprev+1): + j2sprev += ",prev"+str(cnt) + j2scontext += ",prev"+str(cnt) + j2sprev += ")" + j2scontext += "," + else: + j2scontext = "j2s(" + j2snext = "j2s(next1" + j2scontext += "middle" + if contextnext: + j2scontext += ",next1" + for cnt in xrange(2,contextnext+1): + j2snext += ",next"+str(cnt) + j2scontext += ",next"+str(cnt) + j2snext += ")" + j2scontext += ")" + j2sextranext = "j2s(next"+str(contextnext+1) + for cnt in xrange(contextnext+2,extracontextnext+contextnext+1): + j2sextranext += ",next"+str(cnt) + j2sextranext += ")" + print j2sextraprev, j2sprev, j2snext, j2sextranext, j2scontext + # create positive and negative words weighted regex text pos_set = neg_set = conf = whr_conf = '' if 'poswords' in self.request.arguments and self.request.arguments['poswords'][0] != '{}': @@ -607,7 +714,10 @@ class configureProfileHandler(BaseHandler): # construct math string for positive words matching calculation with weights pos_words = json.loads(self.request.arguments['poswords'][0]) for key, value in pos_words.iteritems(): - pos_set += r'regexpcountuniquematches("(?:\b)%s(?:\b)",j2s(prev,middle,next))*%s + ' % (key,value) + # MONO GIA TO EGI + pos_set += r'regexpcountuniquematches("%s",%s)*%s + ' % (key,j2scontext,value) + # ORIGINAL + # pos_set += r'regexpcountuniquematches("(?:\b)%s(?:\b)",j2s(prev,middle,next))*%s + ' % (key,value) data['poswords'].append(key) pos_set += "0" if 'negwords' in self.request.arguments and self.request.arguments['negwords'][0] != '{}': @@ -615,7 +725,10 @@ class configureProfileHandler(BaseHandler): # construct math string for negative words matching calculation with weights neg_words = json.loads(self.request.arguments['negwords'][0]) for key, value in neg_words.iteritems(): - neg_set += r'regexpcountuniquematches("(?:\b)%s(?:\b)",j2s(prev,middle,next))*%s - ' % (key,value) + # MONO GIA TO EGI + neg_set += r'regexpcountuniquematches("%s",%s)*%s + ' % (key,j2scontext,value) + # ORIGINAL + # neg_set += r'regexpcountuniquematches("(?:\b)%s(?:\b)",j2s(prev,middle,next))*%s - ' % (key,value) data['negwords'].append(key) neg_set += "0" if pos_set != '' and neg_set != '': @@ -628,25 +741,23 @@ class configureProfileHandler(BaseHandler): conf += ' as conf' whr_conf = 'and conf>=0' - # get the database cursor - cursor=msettings.Connection.cursor() - if numberOfDocsUploaded(user_id) != 0: - doc_filters = "regexpr('[\n|\r]',d2,' ')" - ackn_filters = "regexpr(\"\\'\", p2,'')" + doc_filters = "comprspaces(regexpr('[\n|\r]',d2,' '))" + ackn_filters = "comprspaces(regexpr(\"\\'\", p2,''))" if 'punctuation' in self.request.arguments and self.request.arguments['punctuation'][0] == "1": doc_filters = 'keywords('+doc_filters+')' ackn_filters = 'keywords('+ackn_filters+')' - if 'lettercase' in self.request.arguments and self.request.arguments['lettercase'][0] != '' and self.request.arguments['lettercase'][0] != 'None': - if self.request.arguments['lettercase'][0] == 'Lowercase': + if 'lettercase' in self.request.arguments and self.request.arguments['lettercase'][0] != '' and self.request.arguments['lettercase'][0] != 'none': + if self.request.arguments['lettercase'][0] == 'lowercase': doc_filters = 'lower('+doc_filters+')' ackn_filters = 'lower('+ackn_filters+')' - elif self.request.arguments['lettercase'][0] == 'Uppercase': + elif self.request.arguments['lettercase'][0] == 'uppercase': doc_filters = 'upper('+doc_filters+')' ackn_filters = 'upper('+ackn_filters+')' if 'stopwords' in self.request.arguments and self.request.arguments['stopwords'][0] == "1": doc_filters = 'filterstopwords('+doc_filters+')' ackn_filters = 'filterstopwords('+ackn_filters+')' + print "DOCCC", doc_filters list(cursor.execute("drop table if exists grantstemp"+user_id, parse=False)) query_pre_grants = "create temp table grantstemp{0} as select stripchars(p1) as gt1, case when p2 is null then null else {1} end as gt2 from (setschema 'p1,p2' file '/tmp/p{0}.tsv' dialect:tsv)".format(user_id, ackn_filters) cursor.execute(query_pre_grants) @@ -654,27 +765,38 @@ class configureProfileHandler(BaseHandler): query1 = "create temp table docs{0} as select d1, {1} as d2 from (setschema 'd1,d2' select jsonpath(c1, '$.id', '$.text') from (file '/tmp/docs{0}.json'))".format(user_id, doc_filters) cursor.execute(query1) else: - data['error'] = "You have to provide at least one concept to continue" - self.write(json.dumps(data)) - self.finish() + self.set_status(400) + self.write("You have to provide atleast 1 document...") return list(cursor.execute("drop table if exists grants"+user_id, parse=False)) # string concatenation workaround because of the special characters conflicts if 'wordssplitnum' in self.request.arguments and self.request.arguments['wordssplitnum'][0] != '': words_split = int(self.request.arguments['wordssplitnum'][0]) + # MONO GIA TO EGI if 0 < words_split and words_split <= 10: - acknowledgment_split = r'textwindow2s(regexpr("([\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|])", gt2, "\\\1"),0,'+str(words_split)+r',0)' + acknowledgment_split = r'textwindow2s(gt2,0,'+str(words_split)+r',0)' else: - acknowledgment_split = r'"prev" as prev, regexpr("([\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|])", gt2, "\\\1") as middle, "next" as next' + acknowledgment_split = r'"dummy" as prev, gt2 as middle, "dummy" as next' + # ORIGINAL + # if 0 < words_split and words_split <= 10: + # acknowledgment_split = r'textwindow2s(regexpr("([\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|])", gt2, "\\\1"),0,'+str(words_split)+r',0)' + # else: + # acknowledgment_split = r'"dummy" as prev, regexpr("([\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|])", gt2, "\\\1") as middle, "dummy" as next' + # query0 = r"create temp table grants"+user_id+r' as select gt1 as g1, jmergeregexp(jgroup("(?<=[\s\b])"||middle||"(?=[\s\b])")) as g2 from '+r"(setschema 'gt1,prev,middle,next' select gt1, "+acknowledgment_split+r' from grantstemp'+user_id+r' where (gt1 or gt1!="") and gt2 not null) group by gt1 union all select distinct gt1 as g1, "(?!.*)" as g2 from grantstemp'+user_id+r" where (gt1 or gt1!='') and gt2 is null" - query0 = r"create temp table grants"+user_id+r' as select gt1 as g1, jmergeregexp(jgroup(middle)) as g2 from '+r"(setschema 'gt1,prev,middle,next' select gt1, "+acknowledgment_split+r' from grantstemp'+user_id+r' where (gt1 or gt1!="") and gt2 not null) group by gt1 union all select distinct gt1 as g1, "(?!.*)" as g2 from grantstemp'+user_id+r" where (gt1 or gt1!='') and gt2 is null" + query0 = r"create temp table grants"+user_id+r' as select gt1 as g1, jmergeregexp(jgroup(middle)) as g2 from '+r"(setschema 'gt1,prev,middle,next' select gt1, "+acknowledgment_split+r' from grantstemp'+user_id+r' where (gt1 or gt1!="") and gt2 != "") group by gt1 union all select distinct gt1 as g1, "(?!.*)" as g2 from grantstemp'+user_id+r" where (gt1 or gt1!='') and gt2 = ''" cursor.execute(query0) query0get = "select * from grants{0}".format(user_id) results0get = [r for r in cursor.execute(query0get)] print results0get - query2 = "select d1, g1, context, acknmatch, max(confidence) as confidence from (select d1, g1, regexpcountuniquematches(g2, j2s(prev,middle,next)) as confidence, j2s(prev,middle,next) as context, regexprfindall(g2, j2s(prev,middle,next)) as acknmatch {0} from (select d1, textwindow2s(d2,20,1,20) from (select * from docs{1})), (select g1, g2 from grants{1}) T where middle = T.g1 {2}) group by d1".format(conf, user_id, whr_conf) + # FOR EGI ONLY + query2 = r'select distinct d1, g1, extraprev, prev, middle, next, extranext, acknmatch, max(confidence) as confidence from (select d1, g1, regexpcountuniquematches(g2, '+j2scontext+r') as confidence, stripchars('+j2sextraprev+r') as extraprev, stripchars('+j2sprev+r') as prev, middle, stripchars('+j2snext+r') as next, stripchars('+j2sextranext+r') as extranext, '+j2scontext+r' as context, regexprfindall(g2, '+j2scontext+r') as acknmatch '+conf+r' from (select d1, textwindow(d2,'+str(extracontextprev+contextprev)+r','+str(extracontextnext+contextnext)+r','+str(contextmiddle)+r') from docs'+user_id+r'), (select g1, g2 from grants'+user_id+r') T where regexprmatches("(\b|\d|\W)"||T.g1||"(\b|\d|\W)",middle) '+whr_conf+r') group by d1' + # ORIGINAL + # query2 = "select d1, g1, context, acknmatch, max(confidence) as confidence from (select d1, g1, regexpcountuniquematches(g2, j2s(prev,middle,next)) as confidence, j2s(prev,middle,next) as context, regexprfindall(g2, j2s(prev,middle,next)) as acknmatch {0} from (select d1, textwindow2s(d2,20,{3},20) from docs{1}), (select g1, g2 from grants{1}) T where regexprmatches(T.g1,middle) {2}) group by d1".format(conf, user_id, whr_conf, contextmiddle) + + # OLD ONE # query2 = "select c1, c3 {0} from (select c1, textwindow2s(c2,10,1,5) from (select * from docs{1})), (select c3 from grants{1}) T where middle = T.c3 {2}".format(conf, user_id, whr_conf) results = [r for r in cursor.execute(query2)] print results @@ -682,16 +804,16 @@ class configureProfileHandler(BaseHandler): for r in results: if r[0] not in doctitles: doctitles[r[0]] = [] - doctitles[r[0]].append({"match": r[1], "context": r[2], "acknmatch": json.loads(r[3]), "confidence": r[4]}) + doctitles[r[0]].append({"match": r[1], "extraprev": r[2], "prev": r[3], "middle": r[4], "next":r[5], "extranext":r[6], "acknmatch": json.loads(r[7]), "confidence": r[8]}) data['matches'] = doctitles + data['respond'] = "Matching results updated!" self.write(json.dumps(data)) self.flush() self.finish() except Exception as ints: - data = {} - data['error'] = "Something went very very wrong!" - self.write(json.dumps(data)) + self.set_status(400) + self.write("A server error occurred, please contact administrator!") self.finish() print ints @@ -759,7 +881,7 @@ class saveProfileHandler(BaseHandler): cursor.execute("create table filters(c1,c2)", parse=False) # Create grants table cursor.execute("drop table if exists grants", parse=False) - cursor.execute("create table grants(c1)", parse=False) + cursor.execute("create table grants(c1,c2)", parse=False) if 'poswords' in self.request.arguments and self.request.arguments['poswords'][0] != '{}': # construct math string for positive words matching calculation with weights pos_words = json.loads(self.request.arguments['poswords'][0]) @@ -785,7 +907,7 @@ class saveProfileHandler(BaseHandler): ) ) if numberOfGrantsUploaded(user_id, self.get_secure_cookie('madgikmining_grantsuploaded')) != 0: - cursor.execute("insert into grants select stripchars(c1) as c1 from (file '/tmp/p{0}.csv')".format(user_id)) + cursor.execute("insert into grants select stripchars(c1) as c1, stripchars(c2) as c2 from (file '/tmp/p{0}.tsv')".format(user_id)) cursor.close() data = {} diff --git a/interactive-mining-madoap/madoap/src/static/OA DISCOVER_A.png b/interactive-mining-madoap/madoap/src/static/OA DISCOVER_A.png index e8c097c..e15058e 100644 Binary files a/interactive-mining-madoap/madoap/src/static/OA DISCOVER_A.png and b/interactive-mining-madoap/madoap/src/static/OA DISCOVER_A.png differ diff --git a/interactive-mining-madoap/madoap/src/static/OA DISCOVER_B.png b/interactive-mining-madoap/madoap/src/static/OA DISCOVER_B.png index 26d4846..75d2070 100644 Binary files a/interactive-mining-madoap/madoap/src/static/OA DISCOVER_B.png and b/interactive-mining-madoap/madoap/src/static/OA DISCOVER_B.png differ diff --git a/interactive-mining-madoap/madoap/src/static/animations.css b/interactive-mining-madoap/madoap/src/static/animations.css index 904d84c..cd74718 100644 --- a/interactive-mining-madoap/madoap/src/static/animations.css +++ b/interactive-mining-madoap/madoap/src/static/animations.css @@ -1,5 +1,5 @@ /*ANIMATIONS*/ -tr.new-item { +tr.new-item, li.new-item { opacity:0; -webkit-animation:fadeIn .1s linear forwards; -o-animation:fadeIn .1s linear forwards; @@ -17,7 +17,7 @@ tr.new-item { } } -tr.removed-item { +tr.removed-item, li.removed-item { -webkit-animation: removed-item-animation .3s cubic-bezier(.55,-0.04,.91,.94) forwards; -o-animation: removed-item-animation .3s cubic-bezier(.55,-0.04,.91,.94) forwards; animation: removed-item-animation .3s cubic-bezier(.55,-0.04,.91,.94) forwards diff --git a/interactive-mining-madoap/madoap/src/static/configure-profile.js b/interactive-mining-madoap/madoap/src/static/configure-profile.js index b284800..1b003f0 100644 --- a/interactive-mining-madoap/madoap/src/static/configure-profile.js +++ b/interactive-mining-madoap/madoap/src/static/configure-profile.js @@ -39,8 +39,10 @@ var handleMatchLevelChoice = function() { $('#1-level').on('click', function( e ) { + $(".cm-config-option.active").removeClass("active"); + $(this).addClass("active"); if (advanced_options_open) { - UIkit.accordion($('#advanced-opts-toggle')).toggle(0, true); + toggleAdvancedTools(); advanced_options_open = 0; } if (match_level_choice != 0) { @@ -57,8 +59,10 @@ match_level_choice = 0; }); $('#2-level').on('click', function( e ) { + $(".cm-config-option.active").removeClass("active"); + $(this).addClass("active"); if (advanced_options_open) { - UIkit.accordion($('#advanced-opts-toggle')).toggle(0, true); + toggleAdvancedTools(); advanced_options_open = 0; } if (match_level_choice != 1) { @@ -71,8 +75,10 @@ match_level_choice = 1; }); $('#3-level').on('click', function( e ) { + $(".cm-config-option.active").removeClass("active"); + $(this).addClass("active"); if (advanced_options_open) { - UIkit.accordion($('#advanced-opts-toggle')).toggle(0, true); + toggleAdvancedTools(); advanced_options_open = 0; } if (match_level_choice != 2) { @@ -84,9 +90,52 @@ } match_level_choice = 2; }); - $('#c-level').on('click', function( e ) { + // $('#c-level').on('click', function( e ) { + // $(".cm-config-option.active").removeClass("active"); + // $(this).addClass("active"); + // if (advanced_options_open == 0) { + // toggleAdvancedTools(); + // advanced_options_open = 1; + // } + // if (match_level_choice != 3) { + // console.log('#c-level'); + // // store change to localstorage + // localStorage.setItem('matchlevel', "#c-level"); + // } + // }); + + $("#advaned-tools-label").change(function() { + if(this.checked) { + advanced_options_open = 1; + $(".cm-config-option.active").removeClass("active"); + // $('#c-level').click(); + $('#advaned-tools').show(); + localStorage.setItem('matchlevel', "#c-level"); + } else { + advanced_options_open = 0; + if (match_level_choice == 0 || match_level_choice == -1 || match_level_choice == 3) { + match_level_choice = 3; + $('#1-level').click(); + } else if (match_level_choice == 1) { + match_level_choice = 3; + $('#2-level').click(); + } else if (match_level_choice == 2) { + match_level_choice = 3; + $('#3-level').click(); + } + $('#advaned-tools').hide(); + } + }); + + // UIkit.accordion($('#advanced-opts-toggle')).toggle(0, true); + // UIkit.switcher($('#uk-switcher')).show(3); + // UIkit.switcher($('.uk-switcher')).show(3); + } + + var handlePreccisionMode = function(choice) { + if (choice === "#c-level") { if (advanced_options_open == 0) { - UIkit.accordion($('#advanced-opts-toggle')).toggle(0, true); + toggleAdvancedTools(); advanced_options_open = 1; } if (match_level_choice != 3) { @@ -94,43 +143,25 @@ // store change to localstorage localStorage.setItem('matchlevel', "#c-level"); } - }); - // $('#advanced-opts-toggle').on('show', function () { - // console.log('#GG-level'); - // UIkit.switcher($('#uk-switcher')).show(3); - // UIkit.switcher($('.uk-switcher')).show(3); - // advanced_options_open = 1; - // }); - // $('#advanced-opts-toggle').on('hide', function () { - // console.log('#BB-level'); - // UIkit.switcher($('#uk-switcher')).show(match_level_choice); - // UIkit.switcher($('.uk-switcher')).show(match_level_choice); - // advanced_options_open = 0; - // }); - - $('#advanced-opts-toggle').on('show', function () { - console.log('#GG-level'); - advanced_options_open = 1; - $('#c-level').click(); - }); - $('#advanced-opts-toggle').on('hide', function () { - console.log('#BB-level'); - advanced_options_open = 0; - if (match_level_choice == 0) { - match_level_choice = 3; - $('#1-level').click(); - } else if (match_level_choice == 1) { - match_level_choice = 3; - $('#2-level').click(); - } else if (match_level_choice == 2) { - match_level_choice = 3; - $('#3-level').click(); - } - }); + } else { + $(choice).click(); + } + } - // UIkit.accordion($('#advanced-opts-toggle')).toggle(0, true); - // UIkit.switcher($('#uk-switcher')).show(3); - // UIkit.switcher($('.uk-switcher')).show(3); + var toggleAdvancedTools = function() { + if($("#advaned-tools-label").prop('checked')) { + $("#advaned-tools-label").prop('checked', false); + $("#advaned-tools-label").attr('checked', false); + $('#advaned-tools-label')[0].checked = false; + $('#advaned-tools-label').removeAttr('checked'); + $('#advaned-tools').hide(); + } else { + localStorage.setItem('matchlevel', "#c-level"); + $("#advaned-tools-label").prop('checked', true); + $("#advaned-tools-label").attr('checked', true); + $('#advaned-tools-label')[0].checked = true; + $('#advaned-tools').show(); + } } /////////// LIST FUNCTIONS @@ -160,7 +191,7 @@ } //generates a unique id - var generateId = function(is_pos){ + var generateId = function(is_pos) { if (is_pos) { return "positive-" + +new Date() + Math.random().toFixed(5).substring(2); } else { @@ -168,24 +199,49 @@ } } + var wordAlreadyExists = function(is_pos, word) { + var found = false; + for (var key in localStorage) { + if (key === null) + continue; + var value = localStorage.getItem(key); + if(is_pos && key.indexOf('positive') === 0){ + data = JSON.parse(value); + if (data.phrase === word) { + found = true; + alert("OOOOOOOOOP"); + break; + } + } else if (key.indexOf('negative') === 0) { + data = JSON.parse(value); + if (data.phrase === word) { + found = true; + alert("OOOOOOOOOP"); + break; + } + } + } + return found; + } + var wordsDataToArray = function(is_pos) { // TODO var data = {}; if (is_pos === 1) { - $("#word-pos tbody tr").each(function(i, v){ + $("#word-pos li").each(function(i, v){ // data[i] = Array(); // $(this).children('td').each(function(ii, vv){ // data[i][ii] = $(this).text(); // }); - data[$(v).find("td.phrase").text()] = $(v).find("td.weight").text(); + data[$(v).find("div.phrase").text()] = $(v).find("div.weight").text(); }) } else { - $("#word-neg tbody tr").each(function(i, v){ + $("#word-neg li").each(function(i, v){ // data[i] = Array(); // $(this).children('td').each(function(ii, vv){ // data[i][ii] = $(this).text(); // }); - data[$(v).find("td.phrase").text()] = $(v).find("td.weight").text(); + data[$(v).find("div.phrase").text()] = $(v).find("div.weight").text(); }) } @@ -231,8 +287,8 @@ }); // Handle clicks outside editboxes $(document).click(function (event) { - if($(event.target).attr('class')!="thVal") { - saveEditBox(currentEle); + if($(event.target).hasClass('thVal')===false) { + saveEditBox(clickedElement); $(document).off('click'); clickedElement = null; } @@ -242,7 +298,7 @@ // a fucntion to catch double click on positive and negative phrases edit boxes var addDoubleClick = function(element){ $(element).click(function (event) { - if($(event.target).attr('class')!="thVal") { + if($(event.target).hasClass('thVal')===false) { event.stopPropagation(); // save previous clicked box if (clickedElement) @@ -261,7 +317,7 @@ $(this).remove(); }); // remove from localstorage - localStorage.remove('#' + id); + localStorage.removeItem(id); if (is_pos === 1) { count_pos--; } else { @@ -273,23 +329,25 @@ var count_pos = 0, count_neg = 0; var addDataToTable = function(id, content_word, content_weight, is_pos) { - var row = '' + content_word + '' + content_weight +'' - table = $('#data-table tbody'); + // with number column + // var row = '
  • '+count_pos+'
    ' + content_word + '
    ' + content_weight +'
  • ' + var row = '
  • ' + content_word + '
    ' + content_weight +'
  • ' + table = $('#data-table'); // if content is correct and not empty append to table if(!$('#'+ id).length){ row = $(row).addClass('new-item'); if (is_pos === 1) { - $('#word-pos tbody').append(row); + $('#word-pos').append(row); } else { - $('#word-neg tbody').append(row); + $('#word-neg').append(row); } // add all the item's extra functionality var createdItem = $('#'+ id); // delete button - createdItem.append($('').append($('', { + createdItem.append($('
    ' , {"class": "uk-width-1-4@m uk-text-center erase"}).append($('', { "class" :"uk-icon-link", "uk-icon" : "icon: trash", "contenteditable" : "false", @@ -300,8 +358,8 @@ } } }))); - addDoubleClick($(createdItem).find("td.phrase")); - addDoubleClick($(createdItem).find("td.weight")); + addDoubleClick($(createdItem).find("div.phrase")); + addDoubleClick($(createdItem).find("div.weight")); createdItem.on('keydown', function(ev){ if(ev.keyCode === 13) return false; }); @@ -317,12 +375,6 @@ obj["phrase"] = content_word; obj["weight"] = content_weight; localStorage.setItem(id, JSON.stringify(obj)); - for(var key in localStorage){ - if (key === null) - continue; - var json_string = localStorage.getItem(key); - console.log(key+' '+json_string); - } } } @@ -331,6 +383,9 @@ event.preventDefault(); var input_word = $('#text-pos'); word = input_word.val(); + if(wordAlreadyExists(1,word)) { + return false; + } var input_weight = $('#weight-pos'); weight = input_weight.val(); if (word && weight){ @@ -344,6 +399,9 @@ event.preventDefault(); var input_word = $('#text-neg'); word = input_word.val(); + if(wordAlreadyExists(0,word)) { + return false; + } var input_weight = $('#weight-neg'); weight = input_weight.val(); if (word && weight){ @@ -361,7 +419,7 @@ var deleteAllWords = function(warnUser = 1, is_pos) { if(!warnUser || confirm('Are you sure you want to delete all the items in the list? There is no turning back after that.')){ //remove items from DOM if (is_pos) { - var items = $('tr[id ^= positive]'); + var items = $('li[id ^= positive]'); items.addClass('removed-item').one('webkitAnimationEnd oanimationend msAnimationEnd animationend', function(e) { $(this).remove(); }); @@ -377,7 +435,7 @@ count_pos = 0; updateCounter(1); } else { - var items = $('tr[id ^= negative]'); + var items = $('li[id ^= negative]'); items.addClass('removed-item').one('webkitAnimationEnd oanimationend msAnimationEnd animationend', function(e) { $(this).remove(); }); @@ -403,43 +461,104 @@ }; var handleFiltersInput = function() { - $("#letter-case-select").on('change', function(e) { - localStorage.setItem('lettercase', $("#letter-case-select option:selected").text()); + $("#context-prev-words").on('change', function(e) { + localStorage.setItem('contextprev', $("#context-prev-words").val()); }); + $("#context-next-words").on('change', function(e) { + localStorage.setItem('contextnext', $("#context-next-words").val()); + }); + $("#letter-case-radio .uk-radio").each(function() {$(this).on('change', function(e) { + console.log("YEAH"); + localStorage.setItem('lettercase', $("#letter-case-radio input:checked").val()); + })}); $("#word-split").on('change', function(e) { localStorage.setItem('wordssplitnum', $("#word-split").val()); }); $("#stop-words-filter").on('change', function(e) { localStorage.setItem('stopwords', $('#stop-words-filter').prop('checked')===true?1:0); - console.log('stop-words-filter '+localStorage.getItem('stopwords')); }); $("#punctuation-filter").on('change', function(e) { localStorage.setItem('punctuation', $('#punctuation-filter').prop('checked')===true?1:0); - console.log('punctuation-filter '+localStorage.getItem('punctuation')); }); } + function highlightInElement(element, text){ + var elementHtml = element.html(); + var tags = []; + var tagLocations= []; + var htmlTagRegEx = /<{1}\/{0,1}\w+>{1}/; + + //Strip the tags from the elementHtml and keep track of them + var htmlTag; + while(htmlTag = elementHtml.match(htmlTagRegEx)){ + tagLocations[tagLocations.length] = elementHtml.search(htmlTagRegEx); + tags[tags.length] = htmlTag; + elementHtml = elementHtml.replace(htmlTag, ''); + } + + //Search for the text in the stripped html + var textLocation = elementHtml.search(text); + if(textLocation){ + //Add the highlight + var highlightHTMLStart = ""; + var highlightHTMLEnd = ""; + elementHtml = elementHtml.replace(text, highlightHTMLStart + text + highlightHTMLEnd); + + //plug back in the HTML tags + var textEndLocation = textLocation + text.length; + for(i=tagLocations.length-1; i>=0; i--){ + var location = tagLocations[i]; + if(location > textEndLocation){ + location += highlightHTMLStart.length + highlightHTMLEnd.length; + } else if(location > textLocation){ + location += highlightHTMLStart.length; + } + elementHtml = elementHtml.substring(0,location) + tags[i] + elementHtml.substring(location); + } + } + + //Update the innerHTML of the element + element.html(elementHtml); + return element; + } + var handleRunMiningButton = function() { $("#run-mining-btn").on('click', function( e ) { var formData = new FormData(); formData.append("poswords", JSON.stringify(wordsDataToArray(1))); formData.append("negwords", JSON.stringify(wordsDataToArray(0))); - formData.append("lettercase", $("#letter-case-select option:selected").text()); + formData.append("contextprev", $("#context-prev-words").val()); + formData.append("contextnext", $("#context-next-words").val()); + formData.append("lettercase", $("#letter-case-radio input:checked").val()); formData.append("wordssplitnum", $("#word-split").val()); formData.append("stopwords", $('#stop-words-filter').prop('checked')===true?1:0); formData.append("punctuation", $('#punctuation-filter').prop('checked')===true?1:0); - filters_list = {}; - filters_list["lettercase"] = $("#letter-case-select option:selected").text(); - filters_list["wordssplitnum"] = $("#word-split").val(); - filters_list["stopwords"] = $('#stop-words-filter').prop('checked')===true?1:0; - filters_list["punctuation"] = $('#punctuation-filter').prop('checked')===true?1:0; - formData.append("filters", JSON.stringify(filters_list)); + // filters_list = {}; + // filters_list["lettercase"] = $("#letter-case-select option:selected").text(); + // filters_list["wordssplitnum"] = $("#word-split").val(); + // filters_list["stopwords"] = $('#stop-words-filter').prop('checked')===true?1:0; + // filters_list["punctuation"] = $('#punctuation-filter').prop('checked')===true?1:0; + // formData.append("filters", JSON.stringify(filters_list)); $.ajax({ url: "configure-profile", type: 'POST', data: formData, - async: false, + async: true, + beforeSend: function () { + // UIkit.modal($("#wait-spinner-modal-center")).show(); + $("#wait-spinner-modal-center").css("display", "flex"); + $("#wait-spinner-modal-center").addClass("uk-open"); + + }, success: function (data) { + UIkit.modal($("#wait-spinner-modal-center")).hide(); + respond = JSON && JSON.parse(data).respond || $.parseJSON(data).respond; + UIkit.notification({ + message: respond, + status: 'success', + pos: 'top-center', + timeout: 5000 + }); obj = JSON && JSON.parse(data) || $.parseJSON(data); console.log(obj); // get poswords @@ -455,76 +574,110 @@ // get matches var matches = []; if (obj.hasOwnProperty("matches")) { + var matches_counter = 0; doc_matches = obj["matches"]; + $("#docs-results").empty(); for (var docname in doc_matches) { if (doc_matches.hasOwnProperty(docname)) { // create document section - var li = $('
  • '+docname+'

  • '); + var li = $('
  • '+docname+'

  • '); // create matches section word_matches = doc_matches[docname]; var accordion_content = $('
    '); + var doc_match_count = 1; for (var match in word_matches) { console.log(word_matches[match]); var result = word_matches[match]; - var paragraph = $('

    '+result.context.split(' ').map(function(x){return ""+x+"";}).join('')+'

    '); - // find center match string and surrounded text - var matched = paragraph.find(":contains('"+result.match+"')"); - var prev = matched.prev(); - var next = matched.next(); + // construct middle match + // Find center match + var match_regexp = new RegExp(result.match, "g"); + + + + + + + + + + // var paragraph = $('

    '+result.context.split(' ').map(function(x){return ""+x+"";}).join('')+'

    '); + // // find center match string and surrounded text + // var matched = paragraph.find(":contains('"+result.match+"')"); + // var prev = matched.prev(); + // var next = matched.next(); // get textwindows text as context var context = []; - var prev_context = []; - var next_context = []; - for (i = 0; prev.text()!=''; i++) { - if (i < 10) { - context.unshift(prev.text()); - } else { - prev_context.unshift(prev.text()); - } - prev = prev.prev(); - } - context.push(matched.text()); - for (i = 0; next.text()!=''; i++) { - if (i < 5) { - context.push(next.text()); - } else { - next_context.push(next.text()); - } - next = next.next(); - } + context.push(result.prev); + context.push(result.middle); + context.push(result.next); + + // var prev_context = []; + // var next_context = []; + // for (i = 0; prev.text()!=''; i++) { + // if (i < 10) { + // context.unshift(prev.text()); + // } else { + // prev_context.unshift(prev.text()); + // } + // prev = prev.prev(); + // } + // context.push(matched.text()); + // for (i = 0; next.text()!=''; i++) { + // if (i < 5) { + // context.push(next.text()); + // } else { + // next_context.push(next.text()); + // } + // next = next.next(); + // } + + // hightlight textwindow - context = $(''+context.join(' ')+''); + context = $(''+context.join(' ')+''); // hightlight positive words for (var index in poswords) { var search_regexp = new RegExp(poswords[index], "g"); - context.html(context.html().replace(search_regexp,""+poswords[index]+"")); + context.html(context.html().replace(search_regexp,""+poswords[index]+"")); } // hightlight acknowledgment keywords if (result.hasOwnProperty("acknmatch")) { var acknmatches = result["acknmatch"]; for (var index in acknmatches) { var search_regexp = new RegExp(acknmatches[index], "g"); - context.html(context.html().replace(search_regexp,""+acknmatches[index]+"")); + context.html(context.html().replace(search_regexp,""+acknmatches[index]+"")); } } // hightlight negative words for (var index in negwords) { var search_regexp = new RegExp(negwords[index], "g"); - context.html(context.html().replace(search_regexp,""+negwords[index]+"")); + context.html(context.html().replace(search_regexp,""+negwords[index]+"")); } - // hightlight matched phrase - var search_regexp = new RegExp(result.match, "g"); - context.html(context.html().replace(search_regexp,""+result.match+"")); + // TESTTTTTTTTT + context = highlightInElement(context, result.match); + + // // hightlight matched phrase + // var search_regexp = new RegExp(result.match, "g"); + // context.html(context.html().replace(search_regexp,""+result.match+"")); + + match_title = $('Match '+(matches_counter+1)+': '+result.match+''); + doc_match_count++; + matches_counter++; + accordion_content.append(match_title); // construct results paragraph to show - paragraph = $('

    '+prev_context.join(' ')+' '+context[0].outerHTML+' '+next_context.join(' ')+'

    '); - - li.append(paragraph); + paragraph = $('

    '+result.extraprev+' '+context[0].outerHTML+' '+result.extranext+'

    '); + accordion_content.append(paragraph); + li.append(accordion_content); } $("#docs-results").append(li); } } UIkit.accordion($("#docs-results")); + var prev_res_cnt = $("#results-number").html(); + $("#results-number").html(matches_counter+" matches found"); + if (prev_res_cnt != "") { + $("#results-number-previous").html(prev_res_cnt+" previously"); + } } $("#results-section").show(); // split all paragraphs to word spans @@ -549,8 +702,13 @@ // }); }, error: function (xhr, ajaxOptions, thrownError) { - $('#file-upload-response').html('File Failed to Upload!'+xhr.status) - // $('#file-uploaded')[0].checked = false; + UIkit.modal($("#wait-spinner-modal-center")).hide(); + UIkit.notification({ + message: xhr.status, + status: 'danger', + pos: 'top-center', + timeout: 0 + }); }, cache: false, contentType: false, @@ -567,20 +725,54 @@ } var hideInitialDocsUploadForm = function() { - console.log("AAAAAAAAA") + $(".cm-results-hide-pannel").hide(); $("#docs-more-btn").show(); $("#run-mining-btn").removeAttr('disabled').removeClass('disabled'); $('#documents-change-btn').addClass("uk-button"); $('#initial-docs-upload-form').attr("class", ""); + $('#initial-docs-upload-form').addClass("cm-docs-selection-form-dialog"); $('#initial-docs-upload-form').attr("uk-dropdown", "mode: click;"); $('#initial-docs-upload-form').appendTo("#documents-section"); UIkit.dropdown($("#initial-docs-upload-form")); - UIkit.dropdown($("#initial-docs-upload-form")).mode = "click"; + $("#initial-docs-upload-form").mode = "click"; + stickyResultsHeader = UIkit.sticky($("#cm-results-section-header"), { + top: 25, + showOnUp: true, + animation: "uk-animation-slide-top", + bottom: ".cm-results-section" + }); + console.log(stickyResultsHeader); + $("#initial-docs-upload-form").on('beforeshow', function () { + $(".cm-results-hide-pannel").show(); + $(".cm-header-hide-pannel").addClass("cm-header-shown"); + stickyResultsHeader.$destroy(); + stickyResultsHeader = UIkit.sticky($("#cm-results-section-header"), { + top: 25, + bottom: ".cm-results-section" + }); + }); + $("#initial-docs-upload-form").on('hidden', function () { + $(".cm-results-hide-pannel").hide(); + $(".cm-header-hide-pannel").removeClass("cm-header-shown"); + stickyResultsHeader.$destroy(); + stickyResultsHeader = UIkit.sticky($("#cm-results-section-header"), { + top: 25, + showOnUp: true, + animation: "uk-animation-slide-top", + bottom: ".cm-results-section" + }); + // stickyResultsHeader = UIkit.sticky($("#cm-results-section-header"), { + // top: 25, + // showOnUp: true, + // animation: "uk-animation-slide-top", + // bottom: ".cm-results-section" + // }); + }); handleRunMiningButton(); } var handleFileUploadInput = function() { - $("#docs-file-input").on('change', function() { + $("form#docs-file-input").on('change', function() { if ($('#docs-file-input')[0].value === "") { return false; } @@ -591,9 +783,19 @@ url: "configure-profile", type: 'POST', data: formData, - async: false, + async: true, + beforeSend: function () { + // UIkit.modal($("#wait-spinner-modal-center")).show(); + }, success: function (data) { -// TODO TODO TODO TODO TODO TODO check for error + // UIkit.modal($("#wait-spinner-modal-center")).hide(); + respond = JSON && JSON.parse(data).respond || $.parseJSON(data).respond; + UIkit.notification({ + message: respond, + status: 'success', + pos: 'top-center', + timeout: 5000 + }); obj = JSON && JSON.parse(data).data || $.parseJSON(data).data; // console.log(obj); if (obj > 0) { @@ -605,8 +807,13 @@ } }, error: function (xhr, ajaxOptions, thrownError) { - $('#codes-file-upload-response').html('File Failed to Upload!'+xhr.status) - // $('#file-uploaded')[0].checked = false; + // UIkit.modal($("#wait-spinner-modal-center")).hide(); + UIkit.notification({ + message: xhr.status, + status: 'danger', + pos: 'top-center', + timeout: 0 + }); }, cache: false, contentType: false, @@ -616,6 +823,59 @@ return false; }); + + var bar = document.getElementById('js-progressbar'); + UIkit.upload('.js-upload', { + url: 'configure-profile', + multiple: false, + name: 'upload', + loadStart: function (e) { + bar.removeAttribute('hidden'); + bar.max = e.total; + bar.value = e.loaded; + }, + progress: function (e) { + bar.max = e.total; + bar.value = e.loaded; + }, + loadEnd: function (e) { + bar.max = e.total; + bar.value = e.loaded; + }, + completeAll: function (data) { + console.log(data.responseText); + setTimeout(function () { + bar.setAttribute('hidden', 'hidden'); + }, 1000); + // UIkit.modal($("#wait-spinner-modal-center")).hide(); + respond = JSON && JSON.parse(data.responseText).respond || $.parseJSON(data.responseText).respond; + UIkit.notification({ + message: respond, + status: 'success', + pos: 'top-center', + timeout: 5000 + }); + obj = JSON && JSON.parse(data.responseText).data || $.parseJSON(data.responseText).data; + // console.log(obj); + if (obj > 0) { + if (uploadedDocs == 0) { + hideInitialDocsUploadForm(); + } + docsUploaded(obj); + UIkit.dropdown($("#initial-docs-upload-form")).hide(); + } + }, + error: function (xhr, ajaxOptions, thrownError) { + $('#codes-file-upload-response').html('File Failed to Upload!'+xhr.responseText) + // $('#file-uploaded')[0].checked = false; + UIkit.notification({ + message: xhr.responseText, + status: 'danger', + pos: 'top-center', + timeout: 0 + }); + } + }); } var handleDocSampleChoice = function(btnIndex) { @@ -633,9 +893,19 @@ url: "configure-profile", type: 'POST', data: formData, - async: false, + async: true, + beforeSend: function () { + // UIkit.modal($("#wait-spinner-modal-center")).show(); + }, success: function (data) { -// TODO TODO TODO TODO TODO TODOcheck for error + // UIkit.modal($("#wait-spinner-modal-center")).hide(); + respond = JSON && JSON.parse(data).respond || $.parseJSON(data).respond; + UIkit.notification({ + message: respond, + status: 'success', + pos: 'top-center', + timeout: 5000 + }); obj = JSON && JSON.parse(data).data || $.parseJSON(data).data; if (obj > 0) { if (uploadedDocs == 0) { @@ -646,8 +916,13 @@ } }, error: function (xhr, ajaxOptions, thrownError) { - $('#codes-file-upload-response').html('File Failed to Upload!'+xhr.status) - // $('#file-uploaded')[0].checked = false; + // UIkit.modal($("#wait-spinner-modal-center")).hide(); + UIkit.notification({ + message: xhr.status, + status: 'danger', + pos: 'top-center', + timeout: 0 + }); }, cache: false, contentType: false, @@ -675,7 +950,9 @@ formData.append("poswords", JSON.stringify(wordsDataToArray(1))); formData.append("negwords", JSON.stringify(wordsDataToArray(0))); filters_list = {}; - filters_list["lettercase"] = $("#letter-case-select option:selected").text(); + filters_list["contextprev"] = $("#context-prev-words").val(); + filters_list["contextnext"] = $("#context-next-words").val(); + filters_list["lettercase"] = $("#letter-case-radio input:checked").val(); filters_list["wordssplitnum"] = $("#word-split").val(); filters_list["stopwords"] = $('#stop-words-filter').prop('checked')===true?1:0; filters_list["punctuation"] = $('#punctuation-filter').prop('checked')===true?1:0; @@ -684,8 +961,12 @@ url: "save-profile", type: 'POST', data: formData, - async: false, + async: true, + beforeSend: function () { + // UIkit.modal($("#wait-spinner-modal-center")).show(); + }, success: function (data) { + // UIkit.modal($("#wait-spinner-modal-center")).hide(); console.log(data) // if (data.indexOf('successfully!') != -1) { // $('#file-uploaded')[0].checked = true; @@ -693,8 +974,13 @@ window.location="save-profile" }, error: function (xhr, ajaxOptions, thrownError) { - $('#file-upload-response').html('File Failed to Upload!'+xhr.status) - // $('#file-uploaded')[0].checked = false; + // UIkit.modal($("#wait-spinner-modal-center")).hide(); + UIkit.notification({ + message: xhr.status, + status: 'danger', + pos: 'top-center', + timeout: 0 + }); }, cache: false, contentType: false, @@ -706,9 +992,9 @@ $("#next-button").on('click', function(e) { handleSaveProfileInfoSend(); }); - $("#save-profile-option").on('click', function(e) { - handleSaveProfileInfoSend(); - }); + // $("#save-profile-option").on('click', function(e) { + // handleSaveProfileInfoSend(); + // }); } var checkAlreadyUploadedDocs = function() { @@ -725,14 +1011,16 @@ if (obj > 0) { hideInitialDocsUploadForm(); docsUploaded(obj); - } else if (obj == -1) { - localStorage.clear(); } init(); }, error: function (xhr, ajaxOptions, thrownError) { - $('#codes-file-upload-response').html('File Failed to Upload!'+xhr.status) - // $('#file-uploaded')[0].checked = false; + UIkit.notification({ + message: xhr.status, + status: 'danger', + pos: 'top-center', + timeout: 0 + }); }, cache: false, contentType: false, @@ -741,6 +1029,7 @@ } var checkAlreadyMiningSettings = function() { + console.log(localStorage) for (var key in localStorage) { if (key === null) continue; @@ -754,9 +1043,13 @@ addDataToTable(key, data.phrase, data.weight, 0); } else if (key === 'matchlevel') { console.log(key+' '+value); - $(value).click(); + handlePreccisionMode(value); + } else if (key === 'contextprev') { + $("#context-prev-words").val(value); + } else if (key === 'contextnext') { + $("#context-next-words").val(value); } else if (key === 'lettercase') { - $("#letter-case-select").val(value); + $('#letter-case-radio input.'+value).prop('checked', true); } else if (key === 'wordssplitnum') { $("#word-split").val(value) } else if (key === 'stopwords') { @@ -789,7 +1082,10 @@ } } + var stickyResultsHeader = null; + var init = function(){ + $("#child1").stickySidebar(); handleMatchLevelChoice(); checkAlreadyMiningSettings(); handleWordsInput(); diff --git a/interactive-mining-madoap/madoap/src/static/custom.css b/interactive-mining-madoap/madoap/src/static/custom.css index ef73792..5b89990 100644 --- a/interactive-mining-madoap/madoap/src/static/custom.css +++ b/interactive-mining-madoap/madoap/src/static/custom.css @@ -6,6 +6,14 @@ .tm-toolbar .uk-subnav-line .custom-discover-li a{ color:#05007A !important; } +.tm-toolbar .uk-subnav-line .custom-connect-li { + color:#05007A !important; + background:#fff; + display: block; +} +.tm-toolbar .uk-subnav-line .custom-connect-li a{ + color:#05007A !important; +} .custom-discover-toolbar ul.uk-subnav.uk-subnav-line{ background-color: #f25f30 !important; } @@ -17,6 +25,17 @@ .custom-discover-toolbar{ border-top-color:#f25f30 !important; } +.custom-connect-toolbar ul.uk-subnav.uk-subnav-line{ + background-color: #ffc800 !important; + } + + .custom-connect-toolbar .inner { + background-color: #ffc800 !important; + } + + .custom-connect-toolbar{ + border-top-color:#ffc800 !important; + } .custom-footer{ position:relative; bottom:0; diff --git a/interactive-mining-madoap/madoap/src/static/database.db b/interactive-mining-madoap/madoap/src/static/database.db index 57780be..7090403 100644 Binary files a/interactive-mining-madoap/madoap/src/static/database.db and b/interactive-mining-madoap/madoap/src/static/database.db differ diff --git a/interactive-mining-madoap/madoap/src/static/dl119_files/custom.css b/interactive-mining-madoap/madoap/src/static/dl119_files/custom.css index 4ed5436..656f06e 100644 --- a/interactive-mining-madoap/madoap/src/static/dl119_files/custom.css +++ b/interactive-mining-madoap/madoap/src/static/dl119_files/custom.css @@ -599,4 +599,741 @@ font-weight: 300; font-family: 'Open Sans', sans-serif !important; } .readon-button:hover { +} + + +/* TASOS css */ + +/* Custom controls + ========================================================================== */ +/* + * 1. Container fits its content + * 2. Create position context + * 3. Prevent content overflow + * 4. Behave like most inline-block elements + */ +.uk-form-custom { + /* 1 */ + display: inline-block; + /* 2 */ + position: relative; + /* 3 */ + max-width: 100%; + /* 4 */ + vertical-align: middle; +} +/* + * 1. Position and resize the form control to always cover its container + * 2. Required for Firefox for positioning to the left + * 3. Required for Webkit to make `height` work + * 4. Hide controle and show cursor + * 5. Needed for the cursor + * 6. Clip height caused by 5. Needed for Webkit only + */ +.uk-form-custom select, +.uk-form-custom input[type="file"] { + /* 1 */ + position: absolute; + top: 0; + z-index: 1; + width: 100%; + height: 100%; + /* 2 */ + left: 0; + /* 3 */ + -webkit-appearance: none; + /* 4 */ + opacity: 0; + cursor: pointer; +} +.uk-form-custom input[type="file"] { + /* 5 */ + font-size: 500px; + /* 6 */ + overflow: hidden; +} +/* + * Horizontal + */ +/* Tablet portrait and smaller */ +@media (max-width: 959px) { + /* Behave like `uk-form-stacked` */ + .uk-form-horizontal .uk-form-label { + display: block; + margin-bottom: 5px; + } +} +/* Tablet landscape and bigger */ +@media (min-width: 960px) { + .uk-form-horizontal .uk-form-label { + width: 200px; + margin-top: 7px; + float: left; + } + .uk-form-horizontal .uk-form-controls { + margin-left: 215px; + } + /* Better vertical alignment if controls are checkboxes and radio buttons with text */ + .uk-form-horizontal .uk-form-controls-text { + padding-top: 7px; + } +} + +/* Custom Buttons + ========================================================================== */ +.cm-main-button { + background-color: #ffc800; + color: #2c2b5d; + box-shadow: 0 3px 12px rgba(0,0,0,0.12); +} + +.cm-main-button:hover { + background-color: #f7c200; + color: #2c2b5d; + box-shadow: 0 6px 50px rgba(0,0,0,0.08); +} +.cm-phrases-button { + padding: 0px; + margin: 6px; + height: 33px; + width: 70px; + line-height: inherit; +} +.cm-white-button { + background-color: #ffffff; + width: 103px; + margin: 0; +} +.cm-close-btn { + color: #ffffffaa; +} +.cm-close-btn:hover, .cm-close-btn:focus { + color: #ffffff; +} +/* Custom Navigation + ========================================================================== */ + .cm-navigation { +border-bottom: 5px solid #05007A; +position:relative; +color: #fff; +padding-top: 0px; +padding-bottom:0px; +background:rgba(255,255,255, 0.0); +/*background: linear-gradient(rgba(255,255,255,0), rgba(255,255,255,0)), url(/images/toolbar_bg.png);*/ + +} +.cm-navigation .forimage { +background:rgba(255,255,255, 0.4); +} + +.uk-section-overlap { + /*margin-top:-40px!important;*/ +} +.uk-sticky{ +} + +.tm-header .uk-navbar-left {position:relative;z-index:9999!important;} +.tm-header .uk-logo {padding: 5px 10px 10px 10px; position:relative;z-index:1000!important;} +.tm-header .uk-navbar-transparent{ + /* background:rgba(255,255,255, 0.7);*/ + padding-top:4px; +} +.cm-navigation .uk-container { + padding-right:0px; +} + +.cm-navigation ul.uk-subnav.uk-subnav-line{ + background-color: #05007A; + padding-top:0px; + transform: skew(25deg); + padding-right:0px; + margin-right:10px; + padding-left:0px; +} + +.cm-navigation .uk-subnav-line li { + /*transition: background 0.2s;*/ + /* display:inline-block;*/ + font-family:Roboto!important; + font-weight:900!important; + text-transform:uppercase!important; + font-size:12px!important; + opacity:1!important; + display:inline-block; +} +.cm-navigation .uk-subnav-line > :before { + content: none; + display: block; + /* display: inline-block*/ + height: 10px; + vertical-align: middle +} + +.uk-subnav-line > :nth-child(n + 2):before { + margin-right: 10px; + border-left: 0px ; +} + +.cm-navigation .uk-subnav-line li a{ + display: block; + text-decoration:none; + transform: skew(-25deg); + font-family:Roboto:900!important; + text-transform:uppercase!important; + font-size:13px!important; + opacity:1!important; + color:#05007A!important; + +} +.cm-navigation .uk-subnav-line li:hover { + color:#05007A!important; + background:#fff; + display: block; +} + + + +.cm-navigation .uk-subnav-line li a:hover, +.cm-navigation .uk-subnav-line li:hover a{ + display: block; + color:#05007A!important; +} + +.cm-navigation .uk-dotnav, .cm-navigation .uk-subnav { + margin-bottom:0px!important; +} +.cm-nav-container { + width: 100%; + border-style: solid; + border-width: 0px 0px 5px 0px; + border-bottom-color: #ffc800 !important; + box-shadow: 0px 10px 16px 0px #fff3d1; +} +.cm-left-box { + background-color: #ffc800; + padding: 10px 89px 10px 41px; +} +.cm-nav-toolbar { + border-width: 0px 0px 0px 0px; +} +.cm-nav-toolbar ul.uk-subnav.uk-subnav-line { + background-color: #ffc800 !important; +} +/*.cm-navigation .uk-subnav-line .cm-nav-li { + color: #05007A !important; + background: #fff; + display: block; +}*/ +.cm-nav-li { + padding: 0; + background-color: #ffc800 !important; +} +.cm-nav-li:hover { + background-color: #fff !important; +} +.cm-nav-li:hover { + background-color: #fff !important; +} +.cm-nav-li a { + padding: 0; +} +.cm-nav-number-container { + margin-left: -1px; + padding: 8px 13px 3px 40px; + background-color: #ffc800; + transform: skew(25deg); + display: inline-block; + color: #05007A; +} +.cm-nav-li-number { + padding: 5px 15px 5px 25px; +} +.cm-nav-number { + font-size: x-large; + font-weight: bold; + display: inline-block; + line-height: 1.5; + transform: skew(-25deg); +} +.cm-nav-title { + display: inline-block; + padding: 0px 20px 0px 20px; + line-height: 1.4; +} +.cm-nav-active { + background-color: #fff !important; +} +.cm-nav-active .cm-nav-title { + color: #05007A !important; +} +.cm-nav-disabled, +.cm-nav-disabled:hover, +.cm-nav-disabled .cm-nav-number-container { + background-color: #fce39a !important; + color: #91919d; + cursor: default; +} +.cm-nav-disabled a { + cursor: default; +} +.cm-nav-disabled span.cm-nav-title { + color: #91919d; +} +/* Custom File drop Area Upload + ========================================================================== */ +.cm-file-drop-area { + background-color: #fef4d7; + border: 1px dashed #f9c735; + font-weight: 500; +} +/* Custom Inputs + ========================================================================== */ +#initial-type-input { + border: 2px solid #f9c735; + font-weight: bold !important; + padding: 28px; + border-radius: 3px; + font: inherit; +} +.cm-text-input:-ms-input-placeholder { + color: #aaa !important; +} +.cm-text-input::-moz-placeholder { + color: #aaa; + opacity: 1; +} +.cm-text-input::-webkit-input-placeholder { + color: #aaa; +} + +/* Custom Table + ========================================================================== */ +.cm-table { + border-collapse: collapse; + /*border-radius: 3px;*/ + border-style: hidden; /* hide standard table (collapsed) border */ + box-shadow: 0 0 0 1px #f7c800; /* this draws the table border */ +} +.cm-table td, .cm-table th { + padding: 16px 20px; + -webkit-transition: color .1s linear; + transition: color .1s linear; +} +.cm-table td.code, .cm-table td.acknowl, .cm-table td.delete, .cm-table td.edit, .cm-table-footer { + border-top: 1px solid #e8e8e8; + font-weight: 400; +} +.cm-table td.code:hover, .cm-table td.acknowl:hover, .cm-table td.edit:hover a { + color: #55546d; + cursor: pointer; +} +.cm-table thead tr { + background-color: #fef4d7; +} +.cm-table tr th { + color: #5b6065; + font-weight: bold; +} +.cm-table-number { + background-color: #fbe39a; + border-right: 1px solid #f7c800; +} +.empty:before { + content: "Empty field"; + color: #ccc; +} +.cm-tooltip { + width: 15px; + display: inline-flex; +} +/* Custom config section + ========================================================================== */ +.cm-config-settings-section { + /*overflow: auto; + -webkit-overflow-scrolling: touch; + height: 841px;*/ + max-width: 850px !important; + min-width: 460px !important; + width: 35% !important; +} +.cm-config-section { + +} +.cm-easy-config-section { + padding: 20px; +} +.cm-config-options-container { + display: block; + margin-top: -10px; +} +.cm-config-options-connect-line { + margin: auto; + display: block; + position: relative; + top: 29px; + background-color: #ececec; + z-index: -1; + width: 70%; + height: 8px; + box-shadow: 0px 2px 0px #dedede; + /* Permalink - use to edit and share this gradient: http://colorzilla.com/gradient-editor/#72bbd6+0,617dd3+50,5243a7+100 */ + background: #72bbd6; /* Old browsers */ + background: -moz-linear-gradient(left, #72bbd6 0%, #617dd3 50%, #5243a7 100%); /* FF3.6-15 */ + background: -webkit-linear-gradient(left, #72bbd6 0%,#617dd3 50%,#5243a7 100%); /* Chrome10-25,Safari5.1-6 */ + background: linear-gradient(to right, #72bbd6 0%,#617dd3 50%,#5243a7 100%); /* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */ + filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#72bbd6', endColorstr='#5243a7',GradientType=1 ); /* IE6-9 */ +} +.cm-config-option { + display: block; +} +/*.cm-config-light .cm-circle-button { + background-color: #58bd87; +} +.cm-config-medium .cm-circle-button { + background-color: #269487; +} +.cm-config-hard .cm-circle-button { + background-color: #324b7f; +} +.cm-config-advance .cm-circle-button { + background-color: #161264; +}*/ +.cm-config-light .cm-circle-button, .cm-config-option:hover.cm-config-light .cm-outer-circle-button, .cm-config-option.cm-config-light.active .cm-outer-circle-button { + background-color: #72bbd6; +} +.cm-config-medium .cm-circle-button, .cm-config-option:hover.cm-config-medium .cm-outer-circle-button, .cm-config-option.cm-config-medium.active .cm-outer-circle-button { + background-color: #617dd3; +} +.cm-config-hard .cm-circle-button, .cm-config-option:hover.cm-config-hard .cm-outer-circle-button, .cm-config-option.cm-config-hard.active .cm-outer-circle-button { + background-color: #5243a7; +} +.cm-config-advance .cm-circle-button, .cm-config-option:hover.cm-config-advance .cm-outer-circle-button, .cm-config-option.cm-config-advance.active .cm-outer-circle-button { + background-color: #161264; +} +.cm-config-option:hover .cm-circle-button, .cm-config-option.active .cm-circle-button { + background-color: #efefef; +} +/*.cm-config-option:hover .cm-circle-button-fill, .cm-config-option.active .cm-circle-button-fill { + background-color: rgba(255, 255, 255, 0.39); +}*/ +.cm-outer-circle-button { + background-color: transparent; + margin: 0 auto; + height: 50px; + width: 50px; + border-radius: 45px; + position: relative; + -webkit-transition: .1s ease-in-out; + transition: .1s ease-in-out; +} +.cm-circle-button { + height: 30px; + width: 30px; + top: 10px; + left: 10px; + border-radius: 45px; + position: absolute; + -webkit-transition: .1s ease-in-out; + transition: .1s ease-in-out; +} +.cm-circle-button-fill { + width: 16px; + height: 16px; + border-radius: 45px; + position: absolute; + top: 7px; + left: 7px; + background-color: #efefef; +} +.cm-config-option span { + font-weight: normal; + font-family: Roboto; + text-transform: uppercase; + vertical-align: middle; + font-size: 13px; + text-align: center; + -webkit-transition: .1s ease-in-out; + transition: .1s ease-in-out; + color: #c7c6c6; +} +.cm-config-option:hover span, .cm-config-option.active span { + color: #565656; + text-decoration: none; +} +.cm-config-option-check { + display: none; + position: absolute; + left: -1px; + top: -1px; + color: black; +} +.cm-config-option.active .cm-config-option-check { + display: block; +} +.cm-advanced-tools-section { + padding: 0px 20px 20px 20px; + min-height: 296px; +} +.cm-advanced-tools-section .uk-accordion-title { + font-size: 16px; +} +.cm-advaned-tools-label { + line-height: 1.4; + font-size: 18px; + font-weight: 700; + text-transform: uppercase; +} +/*.cm-prhases { + min-width: 350px !important; + margin-top: 40px !important; +}*/ +.cm-phrases-container { + border-collapse: collapse; + border-radius: 3px; + border-style: hidden; /* hide standard table (collapsed) border */ + box-shadow: 0 0 0 1px #f7c800; /* this draws the table border */ +} +.cm-phrases-container header { + background-color: #fafafa; + color: #5b6065; + font-weight: bold; + border-bottom: 1px solid #e8e8e8; +} +.cm-phrases-container ul { + height: 180px; + overflow-y: scroll; + overflow-x: hidden; + margin: 0; +} +.cm-phrases-container ul li { + padding: 0; + border: none; +} +.cm-number-space, .cm-phrases-container ul li .num { + background-color: #fafafa; + border-right: 1px solid #e8e8e8; + width: 40px; + padding: 12px 0px; + font-size: 14px; +} +.cm-text-input-phrase, .cm-text-input-weight { + height: 34px; + border: 1px solid #f7c800; + font-weight: bold !important; + text-indent: 8px; + border-radius: 5px; + font: inherit; + margin: 5px 0px 5px 5px; +} +.cm-text-input-weight { + width: 80px; +} +.cm-phrases-container .weight { + width: 95px; +} +.cm-phrases-container footer { + padding: 6px 6px 6px 20px; +} +.cm-phrases-container footer.positive { + background-color: #c0ff94; +} +.cm-phrases-container footer.negative { + background-color: #ffbfc9; +} +.cm-phrases-container ul li:hover { + background: #ffd; +} +.cm-phrases-container ul li .phrase, .cm-phrases-container ul li .weight { + padding: 6px 0px 6px 13px; + line-height: 1.5; + border-bottom: 1px solid #e8e8e8; + font-weight: 400; +} +.cm-phrases-container ul li .phrase:hover, .cm-phrases-container ul li .weight:hover { + color: #00a0de; + text-decoration: underline; + cursor: default; +} +.cm-phrases-container ul li .erase { + width: 55px; + border-bottom: 1px solid #e8e8e8; +} +.cm-match-area { + padding: 7px; + border: 1px solid #f7c800; + margin-top: -1px; +} +.cm-match-area.left, .cm-match-area.right { + background-color: #ffff94; +} +.cm-match-area.middle { + background-color: #bedfff; +} + +/* Custom Results Section + ========================================================================== */ +.cm-results-section { + background-color: rgb(242, 242, 242); + min-height: 700px; + position: relative; + border-bottom: 1px solid #f7c800; + border-left: 1px solid #f7c800; +} +.cm-results-section header { + padding: 0; + -webkit-transition: box-shadow 500ms; + transition: box-shadow 500ms; +} +.cm-results-section header.uk-sticky-fixed { + background-color: transparent !important; + box-shadow: rgba(0, 0, 0, 0.07) 0px 3px 0px; +} +.cm-results-controls { + padding: 40px 20px 20px 20px; +} +header.uk-sticky-fixed .cm-results-controls { + background-color: rgb(242, 242, 242) !important; + padding: 20px; +} +.cm-results-count-section { + padding: 5px 20px 20px 20px; +} +header.uk-sticky-fixed .cm-results-count-section { + background-color: rgba(245, 245, 245, 0.8) !important; + padding: 5px 20px 5px 20px; +} +.cm-text-muted { + color: #737373 !important; +} +.cm-results-rows { + /*overflow: auto; + -webkit-overflow-scrolling: touch; + height: 600px;*/ + padding: 0px 20px 40px 20px; +} +.cm-results-rows .match { + font-weight: bold; + color: #336699; +} +.cm-document-result { + margin-top: 5px; +} +.cm-document-result .textwindow { + background-color: #ffff94; + color: #555; +} +.cm-document-result .highlight { + font-weight: bold; + background-color: #bedfff; + padding: 2px 8px; + color: #222; +} +.cm-document-result .negative { + background-color: #ffbfc9; +} +.cm-document-result .positive { + background-color: #c0ff94; +} +.cm-results-hide-pannel { + height: 100%; + width: 100%; + position: absolute; + top: 0; + right: 0; + background-color: rgba(0, 0, 0, 0.5); +} +.cm-header-hide-pannel { + display: none; + height: 100%; + width: 100%; + position: absolute; + top: 0; + right: 0; + background-color: rgba(0, 0, 0, 0.5); +} +.uk-sticky-fixed .cm-header-hide-pannel.cm-header-shown { + display: block; +} +.cm-save-profile-step { + /*position: absolute; + bottom: -60px; + right: 0;*/ + line-height: 38px; +} +/* Custom Docs selection form + ========================================================================== */ +.cm-docs-selection-form { + margin: 0 auto; + display: block; + position: relative; + z-index: 1020; + box-sizing: border-box; + min-width: 500px; + padding: 35px; + background: #fff; + color: #767779; + border-radius: 2px; + box-shadow: 0 3px 12px rgba(0,0,0,0.07); +} +.cm-docs-selection-form-dialog { + min-width: 700px; +} +/* Custom labels + ========================================================================== */ +.cm-label { + display: inline-block; + padding: 1px 7px; + background: #8688a5; + line-height: 1.625; + font-size: 12px; + color: #fff; + vertical-align: middle; + white-space: nowrap; + font-family: Roboto; + font-weight: normal; + text-transform: uppercase; + border-radius: 2px; + margin-right: 5px; +} +/* Custom text + ========================================================================== */ +.cm-coloured-text { + color: #64667f; +} + +#parent { + position: relative; + display: -webkit-flex; + display: flex; + -webkit-flex-wrap: wrap; + flex-wrap: wrap; + -ms-flex-align: start; + -webkit-align-items: start; + align-items: start; + margin-bottom: 64px; +} +#child1 { + padding-top: 20px; + -webkit-flex: 0.35; + flex: 0.35; + will-change: min-height; +} +#child1.is-affixed { + padding-top: 0px; +} +#child1-inner { + transform: translate(0, 0); /* For browsers don't support translate3d. */ + transform: translate3d(0, 0, 0); + will-change: position, transform; + padding-bottom: 20px; + border-bottom: 1px solid #f7c800; + border-right: 1px solid #f7c800; + margin-right: -1px; + min-height: 640px; +} +#child2 { + position: relative; + -webkit-flex: 1; + flex: 1; + right: 0; } \ No newline at end of file diff --git a/interactive-mining-madoap/madoap/src/static/upload-codes.js b/interactive-mining-madoap/madoap/src/static/upload-codes.js index 772f79a..a037bb2 100644 --- a/interactive-mining-madoap/madoap/src/static/upload-codes.js +++ b/interactive-mining-madoap/madoap/src/static/upload-codes.js @@ -51,11 +51,10 @@ } var handleAddRowButton = function() { - $('#add-row-below').on('click', function( e ) { + $('#add-row-below').on('focus', function( e ) { var newId = generateId(); addDataToTable(newId, "", ""); - var currentEle = $('#'+ newId).find("td.code"); - editValue(currentEle, " ", 0); + $('#'+ newId).find("td.code").trigger("click"); }); } @@ -74,8 +73,14 @@ window.location="configure-profile" }, error: function (xhr, ajaxOptions, thrownError) { - $('#file-upload-response').html('File Failed to Upload!'+xhr.status) + $('#file-upload-response').html('File Failed to Upload!'+xhr.responseText) // $('#file-uploaded')[0].checked = false; + UIkit.notification({ + message: xhr.responseText, + status: 'danger', + pos: 'top-center', + timeout: 0 + }); }, cache: false, contentType: false, @@ -100,35 +105,87 @@ var clickedElement=null; var saveEditBox = function(element) { - var new_val = $(".thVal").val(); - $(element).html($(".thVal").val().trim()); + codeElement = element.find(".code"); + ackowElement = element.find(".acknowl"); + codeElement2 = element.find(".code .thVal"); + ackowElement2 = element.find(".acknowl .thVal"); + var codeValue2 = codeElement2.val().trim(); + var ackowValue2 = ackowElement2.val().trim(); + $(codeElement).html(codeValue2); + $(ackowElement).html(ackowValue2); + if (codeValue2 == "") { + codeElement.addClass("empty"); + } + if (ackowValue2 == "") { + ackowElement.addClass("empty"); + } } - var editValue = function(currentEle, value, isArea) { + var editValue = function(currentEle, target) { clickedElement = currentEle; + // Locate code ande acknow + codeElement = currentEle.find(".code"); + ackowElement = currentEle.find(".acknowl"); + // remove empty class if any + codeElement.removeClass("empty"); + ackowElement.removeClass("empty"); $(document).off('click'); - if (isArea) { - $(currentEle).html(''); + // get elements lines number + var divHeight = ackowElement.outerHeight(true); + var lineHeight = parseInt(ackowElement.css('line-height')); + var lines = divHeight / lineHeight; + + var codeValue = codeElement.html(); + input1 = $(''); + input1.val(codeValue); + $(codeElement).html(input1); + + + var ackowValue = ackowElement.html(); + input2 = $('