bug fix: with context handling

pull/25/head
Steve Nyemba 3 weeks ago
parent cbf63d3f56
commit d9bf641a24

@ -7,7 +7,7 @@ from jinja2 import Environment, BaseLoader, FileSystemLoader
import importlib import importlib
import importlib.util import importlib.util
import json import json
from . import sites
from . import apexchart from . import apexchart
class Plugin : class Plugin :
@ -132,13 +132,18 @@ class delegate:
# #
# we need to update the _uri (if context/embeded apps) # we need to update the _uri (if context/embeded apps)
# #
_context = _handler.system()['context'] # _context = _handler.system()['context']
_context = _handler.get('system.context')
if _context : if _context :
_uri = f'{_context}/{_uri}' _uri = f'{_context}/{_uri}'
_plugins = _handler.plugins() # print ([' ** ',_uri, _args['uri']])
# _plugins = _handler.plugins()
_plugins = _handler.get('plugins')
_code = 200 _code = 200
if _uri in _plugins : if _uri in _plugins :
_config = _handler.config() #_args['config'] # _config = _handler.config() #_args['config']
_config = _handler.get(None) #_args['config']
_pointer = _plugins[_uri] _pointer = _plugins[_uri]
@ -159,6 +164,7 @@ class delegate:
if type(_data) == pd.DataFrame : if type(_data) == pd.DataFrame :
_data = _data.to_json(orient='records') _data = _data.to_json(orient='records')
elif type(_data) in [dict,list] : elif type(_data) in [dict,list] :
_data = json.dumps(_data) _data = json.dumps(_data)
pass pass
else: else:

@ -43,11 +43,11 @@ def build (_config, keep=[]): #(_path,_content):
:path path of the files on disk :path path of the files on disk
:config configuration associated with the :config configuration associated with the
""" """
_path = _config['layout']['root'] _path = _config['layout']['root']
# if 'location' in _config['layout'] : # if 'location' in _config['layout'] :
# _path = _config['layout']['location'] # _path = _config['layout']['location']
_path = _realpath(_path,_config) _path = _realpath(_path,_config)
# print (_path)
_items = folders(_path,_config) _items = folders(_path,_config)
_subItems = [ content (os.sep.join([_path,_name]),_config)for _name in _items ] _subItems = [ content (os.sep.join([_path,_name]),_config)for _name in _items ]
@ -57,7 +57,6 @@ def build (_config, keep=[]): #(_path,_content):
_index = _items.index(_name) _index = _items.index(_name)
if _name.startswith('_') or len(_subItems[_index]) == 0: if _name.startswith('_') or len(_subItems[_index]) == 0:
continue continue
# print ([_name,_subItems[_index]])
if _name not in _r : if _name not in _r :
_r[_name] = [] _r[_name] = []
_r[_name] += _subItems[_index] _r[_name] += _subItems[_index]
@ -68,9 +67,8 @@ def build (_config, keep=[]): #(_path,_content):
def _realpath (uri,_config) : def _realpath (uri,_config) :
_layout = _config['layout'] _layout = _config['layout']
_uri = copy.copy(uri) _uri = copy.copy(uri)
if 'location' in _layout : if 'location' in _layout and _layout['location']:
_uri = os.sep.join([_layout['location'],_uri]) _uri = os.sep.join([_layout['location'],_uri])
return _uri return _uri
@ -119,7 +117,9 @@ def html(_uri,_config) :
_context = str(_config['system']['context']) _context = str(_config['system']['context'])
# if '/' in _context : # if '/' in _context :
# _context = _context.split('/')[-1] # _context = _context.split('/')[-1]
_html = ( open(_path)).read() _html = ( open(_path)).read()
_layout = _config['layout'] _layout = _config['layout']
if 'location' in _layout : if 'location' in _layout :
if not _config : if not _config :

@ -26,6 +26,7 @@ import datetime
import requests import requests
from cms import disk, cloud, engine from cms import disk, cloud, engine
import cms.sites
_app = Flask(__name__) _app = Flask(__name__)
cli = typer.Typer() cli = typer.Typer()
@ -49,7 +50,8 @@ def _getHandler (app_id,resource=None) :
return _route._apps[_id] return _route._apps[_id]
def _getId(app_id,app_x): def _getId(app_id,app_x):
if app_x not in [None,''] : if app_x not in [None,''] :
return '/'.join([app_id,app_x]) _uri = '/'.join([app_id,app_x])
return _uri[:-1] if _uri.endswith('/') else _uri
return app_id return app_id
def _setHandler (app_id,resource) : def _setHandler (app_id,resource) :
session['app_id'] = _getId(app_id,resource) session['app_id'] = _getId(app_id,resource)
@ -98,16 +100,32 @@ def _getIndex (app_id ,resource=None):
return render_template(_index_page,**_args),_status_code return render_template(_index_page,**_args),_status_code
@_app.route("/") @_app.route("/")
def _index (): def _index ():
return _getIndex('main') # return _getIndex('main')
global _route
_app = _route.get(None)
_uri = os.sep.join([_app.get('layout.root'),_app.get('layout.index')])
_html = _route.render(_uri,'index')
return render_template('index.html',**_route.render(_uri,'index')),200
@_app.route("/<app>/<resource>") @_app.route("/<app>/<resource>")
@_app.route("/<app>",defaults={'resource':None}) @_app.route("/<app>",defaults={'resource':None})
def _aindex (app,resource=None): def _altIndex(app,resource):
_handler = _getHandler(app,resource) global _route
_id = _getId(app,resource)
_site = _route.get(_id)
_setHandler(app,resource) _uri = os.sep.join([_site.get('layout.root'),_site.get('layout.index')])
_html,_code = _getIndex(app,resource) return render_template('index.html',**_route.render(_uri,'index',_id)),200
return _html,_code
# def _aindex (app,resource=None):
# _handler = _getHandler(app,resource)
# _setHandler(app,resource)
# _html,_code = _getIndex(app,resource)
# return _html,_code
# @_app.route('/id/<uid>') # @_app.route('/id/<uid>')
# def people(uid): # def people(uid):
# """ # """
@ -116,31 +134,34 @@ def _aindex (app,resource=None):
# global _config # global _config
# return "0",200 # return "0",200
@_app.route('/<app>/dialog') @_app.route('/<app>/dialog')
@_app.route('/dialog',defaults={'app':'main'}) @_app.route('/dialog',defaults={'app':None})
def _dialog (app): def _getdialog(app):
# global _config
global _route global _route
_handler = _route.get() _site = _route.get(app)
_uri = request.headers['uri'] _uri = request.headers['uri']
_id = request.headers['dom'] _id = request.headers['dom']
# _html = ''.join(["<div style='padding:1%'>",str( e.render(**_args)),'</div>']) # _html = ''.join(["<div style='padding:1%'>",str( e.render(**_args)),'</div>'])
_args = _route.render(_uri,'html',app) #session.get('app_id','main')) _args = _route.render(_uri,'html',app) #session.get('app_id','main'))
_args['title'] = _id _args['title'] = _id
return render_template('dialog.html',**_args) #title=_id,html=_html) return render_template('dialog.html',**_args) #title=_id,html=_html)
@_app.route("/api/<module>/<name>",defaults={'app':'main','key':None},methods=['GET','POST','DELETE','PUT']) @_app.route("/api/<module>/<name>",defaults={'app':None,'key':None},methods=['GET','POST','DELETE','PUT'])
@_app.route("/<app>/api/<module>/<name>",defaults={'key':None},methods=['GET','POST','DELETE','PUT']) @_app.route("/<app>/api/<module>/<name>",defaults={'key':None},methods=['GET','POST','DELETE','PUT'])
@_app.route("/<app>/<key>/api/<module>/<name>",methods=['GET','POST','DELETE','PUT']) @_app.route("/<app>/<key>/api/<module>/<name>",methods=['GET','POST','DELETE','PUT'])
def _delegate_call(app,key,module,name): def _delegate_call(app,key,module,name):
_handler = _getHandler(app,key) # _handler = _getHandler(app,key)
# print (_handler.config()/) # uri = f'api/{module}/{name}'
uri = f'api/{module}/{name}' # _delegate = cms.delegate()
# return Plugin.call(uri=uri,handler=_handler,request=request) # return _delegate(uri=uri,handler=_handler,request=request)
global _route
_id = _getId(app,key)
_site = _route.get(_id)
_uri = f'api/{module}/{name}'
_delegate = cms.delegate() _delegate = cms.delegate()
return _delegate(uri=uri,handler=_handler,request=request) return _delegate(uri=_uri, handler=_site, request=request)
@_app.route('/version') @_app.route('/version')
def _version (): def _version ():
@ -152,54 +173,38 @@ def _version ():
def _reload(key) : def _reload(key) :
global _route global _route
_handler = _route.get_main() _site = _route.get(None)
_system = _handler.system() _systemKey = _site.get('system.source.key')
if not 'source' in _system : if _systemKey == key and _systemKey:
_systemKey = None _site.reload()
elif 'key' in _system['source'] and _system['source']['key']: return "",200
_systemKey = _system['source']['key'] else:
# print ([key,_systemKey,_systemKey == key]) return "",403
if key and _systemKey and _systemKey == key :
_handler.reload()
return "",200
pass
return "",403
@_app.route('/reload',methods=['POST'])
def reload():
# global _route
# _handler = _route.get_main()
# _system = _handler.system() # _system = _handler.system()
_key = request.headers['key'] if 'key' in request.headers else None
return _reload(_key)
# if not 'source' in _system : # if not 'source' in _system :
# _systemKey = None # _systemKey = None
# elif 'key' in _system['source'] and _system['source']['key']: # elif 'key' in _system['source'] and _system['source']['key']:
# _systemKey = _system['source']['key'] # _systemKey = _system['source']['key']
# print ([_key,_systemKey,_systemKey == _key]) # # print ([key,_systemKey,_systemKey == key])
# if _key and _systemKey and _systemKey == _key : # if key and _systemKey and _systemKey == key :
# _handler.reload() # _handler.reload()
# return "",200 # return "",200
# pass # pass
# return "",403 # return "",403
@_app.route('/reload',methods=['POST'])
def reload():
_key = request.headers['key'] if 'key' in request.headers else None
return _reload(_key)
@_app.route('/page',methods=['POST'],defaults={'app_id':'main','key':None}) @_app.route('/page',methods=['POST'],defaults={'app_id':None,'key':None})
@_app.route('/<app_id>/page',methods=['POST'],defaults={'key':None}) @_app.route('/<app_id>/page',methods=['POST'],defaults={'key':None})
@_app.route('/<app_id>/<key>/page',methods=['POST']) @_app.route('/<app_id>/<key>/page',methods=['POST'])
def _POST_CMSPage(app_id,key): def getPostedPage(app_id,key):
"""
return the content of a folder formatted for a menu
"""
# global _config
global _route global _route
# _handler = _route.get() _id = _getId(app_id,key)
# _config = _handler.config() _site = _route.get(_id)
_handler = _getHandler(app_id,key)
_setHandler(app_id,key)
_config = _handler.config()
# _uri = os.sep.join([_config['layout']['root'],request.headers['uri']])
_uri = request.headers['uri'] _uri = request.headers['uri']
if 'dom' not in request.headers : if 'dom' not in request.headers :
_id = _uri.split('/')[-1].split('.')[0] _id = _uri.split('/')[-1].split('.')[0]
@ -210,8 +215,8 @@ def _POST_CMSPage(app_id,key):
_uri = _uri.split('=')[1] _uri = _uri.split('=')[1]
_args = _route.render(_uri,_id,_getId(app_id,key)) #session.get(app_id,'main')) _args = _route.render(_uri,_id,_getId(app_id,key)) #session.get(app_id,'main'))
return _args[_id],200 return _args[_id],200
# return _html,200
@_app.route('/page',defaults={'app_id':'main','resource':None}) @_app.route('/page',defaults={'app_id':None,'resource':None})
@_app.route('/<app_id>/page',defaults={'resource':None},methods=['GET']) @_app.route('/<app_id>/page',defaults={'resource':None},methods=['GET'])
@_app.route('/<app_id>/<resource>/page',methods=['GET']) @_app.route('/<app_id>/<resource>/page',methods=['GET'])
def _cms_page (app_id,resource): def _cms_page (app_id,resource):
@ -220,10 +225,8 @@ def _cms_page (app_id,resource):
# _handler = _route.get() # _handler = _route.get()
# _config = _handler.config() # _config = _handler.config()
_uri = request.args['uri'] _uri = request.args['uri']
# _uri = os.sep.join([_config['layout']['root'],_uri])
_title = request.args['title'] if 'title' in request.args else '' _title = request.args['title'] if 'title' in request.args else ''
_args = _route.render(_uri,_title,session.get(app_id,'main')) _args = _route.render(_uri,_title,app_id)
return _args[_title],200 return _args[_title],200
@ -250,11 +253,11 @@ def start (
# _route = cms.engine.Router(**_args) #path=path,shared=shared) # _route = cms.engine.Router(**_args) #path=path,shared=shared)
_route = cms.engine.basic.CMS(**_args) # _route = cms.engine.basic.CMS(**_args)
# _args = _route.get().app()
_route = cms.sites.QCMS(**_args)
_args = _route.get().get('system.app')
# dir(_route)
# _args = _route.get().get_app()
_args = _route.get().app()
if port : if port :
_args['port'] = port _args['port'] = port
_app.secret_key = str(uuid.uuid4()) _app.secret_key = str(uuid.uuid4())

@ -0,0 +1,352 @@
"""
This file will describe how a site is loaded
"""
from cms.engine.config.structure import Layout, System
from cms import disk, cloud
import copy
import json
import io
import os
from jinja2 import Environment, BaseLoader, FileSystemLoader
from datetime import datetime
class IOConfig:
"""
This class encapsulates read/write for configuration
"""
def __init__(self,**_args):
self._config = {'system':{},'layout':{},'plugins':{}}
self._caller = None
self._location= _args['location'] if 'location' in _args else None
self._logs = []
def get(self,_key) :
if not _key :
return self._config
_keys = _key.split('.') if '.' in _key else [_key]
_value= None
_object = copy.deepcopy(self._config)
for _key in _keys :
if _key in _object :
_object = _object[_key]
else:
return None
return _object
def set(self,_expr,value):
if len(_expr.split('.')) == 1 :
self._config[_expr] = value
else:
_object = self._config
for _attr in _expr.split('.')[:-1] :
if _attr not in _object :
_object[_attr] = {}
_object = _object[_attr]
_attr = _expr.split('.')[-1]
_object[_attr] = value
def log(self,**_args):
_row = dict({'_date':datetime.now().strftime('%Y-%m-%d'),'time':datetime.now().strftime('%H:%M:%S'), 'context':self.get('system.context')},**_args)
self._logs.append(_row)
def debug(self,**_args):
return self._logs,'application/json'
class Initialization (IOConfig):
def __init__(self,**_args):
super().__init__(**_args)
self._config = self.read_config(**_args)
self._args = _args
#
# Invoke initialization
self.reload()
def reload (self):
_args = self._args
self._caller = _args['caller'] if 'caller' in _args else None
if (self._caller):
self._config['system']['parentContext'] = ''
if not self.get('system.icon') :
self._config['system']['icon'] = None
self._config['layout']['location'] = None
if not self.get('layout.menu') :
self._config['layout']['menu'] = {}
# self.context(**_args)
self.locations(**_args)
self.menu()
self.plugins()
def read_config(self,**_args) :
_config = {}
if 'path' in _args :
f = open(_args['path'])
_config = json.loads(f.read())
f.close()
elif 'stream' in _args :
_stream = _args['stream']
if type(_stream) == 'str' :
_config = json.loads(_stream)
elif type(_stream) == io.StringIO :
_config = json.loads( _stream.read())
_name = self._caller.__name__ if self._caller else None
self.log(action='init.config',module='read_config',input={'caller':_name})
return _config
def context(self,**_args):
"""
Updating the context so that we can have a consistent representation
"""
if ('context' in _args):
self.set('system.context',_args['context'])
pass
_context = self.get('system.context')
if self._caller :
#
# There is a parent context we need to account and we are updating the current context to reflect the caller context
_parentContext = self._caller.get('system.context')
_context = '/'.join([self._caller.get('system.context'),_context])
#
# updating the configuratioin
_iconURI = '/'.join(["",_parentContext,self._caller.get('system.icon')])
# print ([self._caller.get('system.context'), _parentContext,_context])
if self._caller.get('system.context') != '':
_parentContext = "/"+_parentContext
_context = "/"+_context
self.set('system.onport',0)
self._config['system']['onport'] = 0
else:
_iconURI = _iconURI.replace("///","/")
self.set('system.onport',1)
self._config['system']['onport'] = 1
self.set('system.caller',{'icon':_iconURI,'context':self._caller.get('system.context')})
# _context = _context.replace('/','')
else:
#
# If we have no parent site, there should be no parent context (or empty string)
_parentContext = _context #@TODO: should be none ?
#
# Updating context so it is usable throughout the code base
if self._caller:
self.set('system.parentContext', _parentContext.strip())
self.set('system.context',_context.strip())
# self._config['system']['context'] = _context.strip()
self._config['system']['parentContext'] = _parentContext
p = {'has_caller':self._caller != None,'context':_context}
self.log(action='init.context',module='context',input=p)
#
# loosly context to a certain extent involves locations of icons and document root
#
self.locations(**_args)
#
# submit log of status
def locations(self,**_args):
"""
We are updating the icons, project location file and security key (if any), we need to make sure that context is updated first
"""
#
# updating location & path of the application
# if self.get('system.caller') :
# return
_context = self.get('system.context')
_logo = self.get('system.logo')
_root = self.get('layout.root')
if self.get('system.source.id') == 'cloud' :
_icon = f'{_context}/api/cloud/download?doc={_logo}'
else:
_icon = f'{_context}/api/disk/read?uri={_logo}'
# _root = f'{_context}/api/disk/read?uri={_root}'
# self.set('layout.root',_root)
self.set('system.icon',_icon)
self.set('system.logo',_icon)
#
# from the path provided we can determine the location of the project
_homefolder = os.sep.join(_args['path'].split(os.sep)[:-1])
if _homefolder and os.path.exists(os.sep.join([_homefolder,_root])) :
self.set('layout.location',_homefolder)
#
# updating the security key and trying to determine the location
if self.get('system.source.key') :
_path = self.get('system.source.key')
f = None
if os.path.exists(_path) :
f = open(_path)
elif os.path.exists(os.sep.join([self.get('layout.location'),_path])) :
f = open(os.sep.join([self.get('layout.location'),_path]))
if f :
self.set('system.source.key',f.read())
f.close()
def menu (self,**_args):
"""
This function will build the menu of the site (if need be)
"""
_handler = cloud if self.get('system.source.id') == 'cloud' else disk
_object = _handler.build(self._config)
_overwrite = self.get('layout.overwrite')
for _name in _object :
_submenu = _object[_name]
_index = 0
for _item in _submenu :
_text = _item['text'].strip()
if _text in _overwrite :
if 'uri' in _item and 'url' in _overwrite :
del _item['uri']
_item = dict(_item,**_overwrite[_text])
_submenu[_index] = _item
_index += 1
self.set('layout.menu',_object)
# self._config['layout']['menu'] = _object
self.routes() #-- other apps/sites integrated in case we are operating in portal mode
#
# At this point the entire menu is build and we need to have it sorted
self.order()
# _labels = list(self.get('layout.menu').keys())
# self.log(action='init.menu',module='menu',input=_labels)
# print (self.get('layout.menu'))
# print (_object)
def order(self,**_args):
if self.get('layout.order.menu') :
_sorted = {}
_menu = self.get('layout.menu')
_ordered = self.get('layout.order.menu')
for _name in _ordered :
if _name in _menu :
_sorted[_name] = _menu[_name]
if _sorted :
_menu = _sorted
_missing = list(set(_menu.keys()) - set(_sorted))
if _missing :
for _name in _missing :
_menu[_name] = _menu[_name]
self.set('layout.menu',_menu)
def routes (self,**_args):
"""
This method will update menu with dependent sites/apps and add them to the menu
"""
_overwrite = self.get('layout.overwrite')
_routes = self.get('system.routes')
_context = self.get('system.context')
_menu = self.get('layout.menu')
if _routes :
for _text in _routes :
_item = _routes[_text]
if 'menu' in _item :
_uri = f'{_context}/{_text}'
_label = _item['menu']
if _text in _overwrite :
_text = _overwrite[_text]['text']
if _label not in _menu :
_menu[_label] = []
_menu[_label].append({"text":_text,"uri":_uri,"type":"open"})
#
# updating menu ...
self.set('layout.menu',_menu)
# self._config['layout']['menu'] = _menu
else:
pass
def plugins (self,**_args):
"""
This function will load the plugins from disk (only)
"""
_folder = os.sep.join([self.get('layout.location'),self.get('layout.root'),'_plugins'])
_context = self.get('system.context')
_parentContext = self.get('system.parentContext')
_map = {}
_plugins = {}
if self.get('system.source.id') == 'cloud' :
_plugins = cloud.plugins(_context)
else:
_plugins = disk.plugins(context=_context)
_uri = 'api/system/debug'
_uri = _uri if not _context else f'{_context}/{_uri}'
_plugins[_uri] = self.debug
if os.path.exists(_folder) and self.get('plugins'):
_items = self.get('plugins')
for _filename in _items:
_path = os.sep.join([_folder,_filename+'.py'])
if os.path.exists(_path) :
for _module in _items[_filename] :
_pointer = disk.plugins(path=_path,name=_module,context=_context)
if _pointer :
_uri = f"api/{_filename}/{_module}"
_uri = f"{_context}/{_uri}" if _context else _uri
_map[_uri] = _pointer
if _parentContext :
# _uri = f"{_parentContext}/{_context}"
_map[_uri] = _pointer
self.log(action='load.plugin',module='plugins',input={'uri':_uri,'path':_path,'name':_module})
else:
self.log(action='missing.function',module='plugins',input={'name':_module,'path':_path})
else:
#
# log the error ...
self.log(action='missing.plugins',module='plugins',input=_path)
#
# Updating plugins from disk/cloud
_plugins = _map if not _plugins else dict(_plugins,**_map)
#
#
self.set('plugins',_plugins)
self.log(action='init.plugins',module='plugins',input=list(_plugins.keys()))
class Site(Initialization) :
def __init__(self,**_args):
super().__init__(**_args)
self._config['system']['portal'] = (self.get('system.routes')) == None
def html(self,_uri,_id) :
_handler = cloud if self.get('system.source.id') == 'cloud' else disk
_html = _handler.html(_uri, self.get(None))
return " ".join([f'<div id="{_id}"> ',_html,"</div>"])
class QCMS:
def __init__(self,**_args):
_app = Site(**_args)
self._id = _app.get('system.context') #if _app.get('system.context') else 'main'
self._sites = {self._id:_app}
if _app.get('system.routes') :
_routes = _app.get('system.routes')
for _name in _routes :
_path = _routes[_name]['path']
self._sites[_name] = Site(context=_name,path=_path,caller=_app)
def render(self,_uri,_id,_appid=None):
_site = self._sites[_appid] if _appid else self._sites[self._id]
_args = {'layout':_site.get('layout')}
_system = _site.get('system')
for k in ['source','app'] :
if k in _system :
del _system[k]
_args['system'] = _system
_html = _site.html(_uri,_id)
_env = Environment(loader=BaseLoader()).from_string(_html)
_args[_id] = str(_env.render(**_args))
return _args
def set(self,_id):
self._id = _id
def get(self,_id=None):
return self._sites[self._id] if not _id else self._sites[_id]

@ -196,6 +196,7 @@ jx.utils.patterns.observer = function(lobservers,init){
// let's fire the design pattern // let's fire the design pattern
// //
p.start() ; p.start() ;
return p
} }
/** /**

@ -281,7 +281,6 @@ var QCMSBasic= function(_layout,_context,_clickEvent) {
// Object.keys(this._layout.menu) // Object.keys(this._layout.menu)
_names.forEach(function(_name){ _names.forEach(function(_name){
var _div = _me._make(_layout.menu[_name]) ; var _div = _me._make(_layout.menu[_name]) ;

@ -15,6 +15,7 @@ Vanderbilt University Medical Center
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en"> <html lang="en">
<head > <head >
<title>{{layout.header.title}}</title> <title>{{layout.header.title}}</title>
<link rel="shortcut icon" href="{{system.icon}}"> <link rel="shortcut icon" href="{{system.icon}}">
@ -37,6 +38,7 @@ Vanderbilt University Medical Center
<link href="{{system.parentContext}}/static/css/dialog.css" rel="stylesheet" type="text/css"> <link href="{{system.parentContext}}/static/css/dialog.css" rel="stylesheet" type="text/css">
<link href="{{system.parentContext}}/static/css/dashboard.css" rel="stylesheet" type="text/css"> <link href="{{system.parentContext}}/static/css/dashboard.css" rel="stylesheet" type="text/css">
<!-- applying themes as can --> <!-- applying themes as can -->
<link href="{{system.context}}/api/disk/read?uri={{layout.root}}/_assets/themes/{{system.theme}}/layout.css" rel="stylesheet" type="text/css"> <link href="{{system.context}}/api/disk/read?uri={{layout.root}}/_assets/themes/{{system.theme}}/layout.css" rel="stylesheet" type="text/css">
<link href="{{system.context}}/api/disk/read?uri={{layout.root}}/_assets/themes/{{system.theme}}/header.css" rel="stylesheet" type="text/css"> <link href="{{system.context}}/api/disk/read?uri={{layout.root}}/_assets/themes/{{system.theme}}/header.css" rel="stylesheet" type="text/css">
@ -44,6 +46,7 @@ Vanderbilt University Medical Center
<link href="{{system.context}}/api/disk/read?uri={{layout.root}}/_assets/themes/{{system.theme}}/borders.css" rel="stylesheet" type="text/css"> <link href="{{system.context}}/api/disk/read?uri={{layout.root}}/_assets/themes/{{system.theme}}/borders.css" rel="stylesheet" type="text/css">
<link href="{{system.context}}/api/disk/read?uri={{layout.root}}/_assets/themes/{{system.theme}}/footer.css" rel="stylesheet" type="text/css"> <link href="{{system.context}}/api/disk/read?uri={{layout.root}}/_assets/themes/{{system.theme}}/footer.css" rel="stylesheet" type="text/css">
<link href="{{system.context}}/api/disk/read?uri={{layout.root}}/_assets/themes/{{system.theme}}/pane.css" rel="stylesheet" type="text/css"> <link href="{{system.context}}/api/disk/read?uri={{layout.root}}/_assets/themes/{{system.theme}}/pane.css" rel="stylesheet" type="text/css">
<link href="{{system.context}}/api/disk/read?uri={{layout.root}}/_assets/themes/{{system.theme}}/responsive.css" rel="stylesheet" type="text/css">
<!-- --> <!-- -->
<meta property="og:title" content="{{layout.header.title}}" /> <meta property="og:title" content="{{layout.header.title}}" />
@ -84,8 +87,9 @@ Vanderbilt University Medical Center
</script> </script>
<body> <body>
<div class="main {{system.theme}}">
<div id="header" class="header" onclick="window.location.href='{{system.parentContext}}'" style="cursor:pointer"> <div class="main {{system.theme}}" >
<div id="header" class="header" onclick="window.location.href='{{system.context}}'" style="cursor:pointer">
{%include "header.html" %} {%include "header.html" %}
</div> </div>

@ -1,8 +1,12 @@
{%if system.portal %} {%if system.caller %}
{% if system.parentContext == ""%}
{% set _backURI = "/" %}
{% else %}
{% set _backURI = system.parentContext%}
{% endif %}
<div class="icon active"> <div class="icon active">
<div align="center" class="button" onclick="window.open('{{system.parentContext}}/','_self')" style="display:grid; grid-template-columns:auto auto; gap:4px; align-items:center "> <div align="center" class="button" onclick="window.open('{{_backURI}}','_self')" style="display:grid; grid-template-columns:auto auto; gap:4px; align-items:center ">
<i class="fa-solid fa-chevron-left" style="color:darkgray; display:block"></i> <i class="fa-solid fa-chevron-left" style="color:darkgray; display:block"></i>
<img src="{{system.caller.icon}}" style="height:100%"/> <img src="{{system.caller.icon}}" style="height:100%"/>
</div> </div>
@ -11,4 +15,5 @@
<div class="icon"> <div class="icon">
<i class="fa-solid fa-home"></i> <i class="fa-solid fa-home"></i>
</div> </div>
{% endif %} {% endif %}

Loading…
Cancel
Save