diff --git a/docker/init.sh b/docker/init.sh index 060db24942ad10e1bb0f3abca96443d85f55d289..994a4d09a47ce1ac5609deed9b5edf23b68791e4 100755 --- a/docker/init.sh +++ b/docker/init.sh @@ -11,6 +11,9 @@ # 2022-12-20 v1.4 <axel.hahn@unibe.ch> replace fgrep with grep -F # 2023-03-06 v1.5 <www.axel-hahn.de> up with and without --build # 2023-08-17 v1.6 <www.axel-hahn.de> menu selection with single key (without return) +# 2023-11-10 v1.7 <axel.hahn@unibe.ch> replace docker-compose with "docker compose" +# 2023-11-13 v1.8 <axel.hahn@unibe.ch> UNDO "docker compose"; update infos +# 2023-11-15 v1.9 <axel.hahn@unibe.ch> add help; execute multiple actions by params; new menu item: open app # ====================================================================== cd $( dirname $0 ) @@ -19,7 +22,7 @@ cd $( dirname $0 ) # git@git-repo.iml.unibe.ch:iml-open-source/docker-php-starterkit.git selfgitrepo="docker-php-starterkit.git" -_version="1.6" +_version="1.9" # ---------------------------------------------------------------------- # FUNCTIONS @@ -37,6 +40,61 @@ function h3(){ echo -e "\e[34m----- $*\e[0m" } +# show help for param -h +function showMenu(){ + echo " $( _key g ) - remove git data of starterkit" + echo + echo " $( _key i ) - init application: set permissions" + echo " $( _key t ) - generate files from templates" + echo " $( _key T ) - remove generated files" + echo + echo " $( _key u ) - startup containers docker-compose ... up -d" + echo " $( _key U ) - startup containers docker-compose ... up -d --build" + echo " $( _key s ) - shutdown containers docker-compose stop" + echo " $( _key r ) - remove containers docker-compose rm -f" + echo + echo " $( _key m ) - more infos" + echo " $( _key o ) - open app [${APP_NAME}] $frontendurl" + echo " $( _key c ) - console (bash)" + echo + echo " $( _key q ) - quit" +} +function showHelp(){ + local _self=$( basename "$0" ) + cat <<EOH +INITIALIZER FOR DOCKER APP v$_version + +A helper script written in Bash to bring up a PHP+Mysql application in docker. + +Source : https://git-repo.iml.unibe.ch/iml-open-source/docker-php-starterkit +Docs : https://os-docs.iml.unibe.ch/docker-php-starterkit/ +License: GNU GPL 3.0 +(c) Institute for Medical Education; University of Bern + + +SYNTAX: + $_self [-h|-v] + $_self [menu key] + +OPTIONS: + -h show this help and exit + -v show version exit + +MENU KEYS: + In the interactive menu are some keys to init an action. + The same keys can be put as parameter to start this action. + You can add multiples keys to apply multiple actions. + +$( showMenu ) + +EXAMPLES: + + $_self starts interactive mode + $_self u bring up docker container(s) and stay in interactive mode + $_self i q set write permissions and quit + +EOH +} # function _gitinstall(){ # h2 "install/ update app from git repo ${gitrepo} in ${gittarget} ..." # test -d ${gittarget} && ( cd ${gittarget} && git pull ) @@ -189,6 +247,7 @@ function _removeGeneratedFiles(){ done } +# show running containers function _showContainers(){ local bLong=$1 h2 CONTAINERS @@ -200,7 +259,16 @@ function _showContainers(){ } -# a bit stupid ... i think I need to delete it. +# show urls for app container +function _showBrowserurl(){ + echo "In a web browser open:" + echo " $frontendurl" + if grep "${APP_NAME}-server" /etc/hosts >/dev/null; then + echo " https://${APP_NAME}-server/" + fi +} + +# detect + show ports and urls for app container and db container function _showInfos(){ _showContainers long h2 INFO @@ -212,19 +280,20 @@ function _showInfos(){ >/dev/tcp/localhost/${APP_PORT} 2>/dev/null && ( echo "OK, app port ${APP_PORT} is reachable" echo - echo "In a web browser open:" - echo " $frontendurl" + _showBrowserurl ) - h3 "Check database port" - >/dev/tcp/localhost/${DB_PORT} 2>/dev/null && ( - echo "OK, db port ${DB_PORT} is reachable" - echo + if [ "$DB_ADD" != "false" ]; then + h3 "Check database port" + >/dev/tcp/localhost/${DB_PORT} >/dev/null 2>&1 && ( + echo "OK, db port ${DB_PORT} is reachable" + echo + ) echo "In a local DB admin tool:" echo " host : localhost" echo " port : ${DB_PORT}" echo " user : root" echo " password: ${MYSQL_ROOT_PASS}" - ) + fi echo } @@ -235,39 +304,26 @@ function _key(){ # helper: wait for a return key function _wait(){ - echo -n "... press RETURN > "; read -r + echo -n "... press RETURN > "; read -r -t 15 } # ---------------------------------------------------------------------- # MAIN # ---------------------------------------------------------------------- -action=$1 +action=$1; shift 1 while true; do - echo - echo -e "\e[32m===== INITIALIZER FOR DOCKER APP [$APP_NAME] v$_version ===== \e[0m\n\r" if [ -z "$action" ]; then + echo + echo -e "\e[32m===== INITIALIZER FOR DOCKER APP [$APP_NAME] v$_version ===== \e[0m\n\r" + _showContainers - h2 MENU - echo " $( _key g ) - remove git data of starterkit" - echo - echo " $( _key i ) - init application: set permissions" - echo " $( _key t ) - generate files from templates" - echo " $( _key T ) - remove generated files" - echo - echo " $( _key u ) - startup containers docker-compose ... up -d" - echo " $( _key U ) - startup containers docker-compose ... up -d --build" - echo " $( _key s ) - shutdown containers docker-compose stop" - echo " $( _key r ) - remove containers docker-compose rm -f" - echo - echo " $( _key m ) - more infos" - echo " $( _key c ) - console (bash)" - echo - echo " $( _key q ) - quit" + h2 MENU + showMenu echo echo -n " select >" read -rn 1 action @@ -275,6 +331,8 @@ while true; do fi case "$action" in + "-h") showHelp; exit 0 ;; + "-v") echo $(basename $0) $_version; exit 0 ;; g) _removeGitdata ;; @@ -289,24 +347,19 @@ while true; do _removeGeneratedFiles rm -rf containers ;; - # not in the menu - # f) - # _removeGeneratedFiles - # _generateFiles - # _wait - # ;; m) _showInfos _wait ;; u|U) + h2 "Bring up..." dockerUp="docker-compose -p "$APP_NAME" --verbose up -d --remove-orphans" if [ "$action" = "U" ]; then dockerUp+=" --build" fi + echo "$dockerUp" if $dockerUp; then - echo "In a web browser:" - echo " $frontendurl" + _showBrowserurl else echo "ERROR: docker-compose up failed :-/" docker-compose -p "$APP_NAME" logs | tail @@ -316,24 +369,32 @@ while true; do _wait ;; s) + h2 "Stopping..." docker-compose -p "$APP_NAME" stop ;; r) + h2 "Removing..." docker-compose -p "$APP_NAME" rm -f ;; c) + h2 "Console" docker ps echo -n "id or name >" read dockerid test -z "$dockerid" || docker exec -it $dockerid /bin/bash ;; + o) + h2 "Open app ..." + xdg-open "$frontendurl" + ;; q) + h2 "Bye!" exit 0; ;; *) test -n "$action" && ( echo " ACTION FOR [$action] NOT IMPLEMENTED."; sleep 1 ) esac - action= + action=$1; shift 1 done diff --git a/docs/30_Page/10_Page_layout.md b/docs/30_Page/10_Page_layout.md index ddcfea6730841624b78076c9ecdcf21b1a22073a..055e8b88471762dce2869d00be7bd11e897d141c 100644 --- a/docs/30_Page/10_Page_layout.md +++ b/docs/30_Page/10_Page_layout.md @@ -34,6 +34,17 @@ Variable | Description {{PAGE_FOOTER_RIGHT}} | page: footer on the left | {{PAGE_FOOTER_LEFT}} | page: footer on the right | + +#### No left sidebar + +This shows the left sidebar: +`'{{PAGE_LAYOUT}}' =>'layout-navbar-fixed layout-fixed sidebar-mini',` + +This hides the left sidebar: +`'{{PAGE_LAYOUT}}' =>'layout-top-nav sidebar-collapse',` + +If you don't have any left sidebar then additionally remove the hampurger menu from the top menu. + ## Initial example ### Init Renderer class diff --git a/docs/30_Page/20_Navigation.md b/docs/30_Page/20_Navigation.md index 9ca7f4319423e4db94711448f4ac39517345a97f..2b4daa9ea14addb8e1bb774b28b98e3e69ccbfca 100644 --- a/docs/30_Page/20_Navigation.md +++ b/docs/30_Page/20_Navigation.md @@ -6,6 +6,7 @@ For the top navigation and left the basic array looks like this: ```php return [ + ['label'=>'='], ['href'=>'#', 'label'=>'Menu A', 'icon'=>'fa-solid fa-home' ], ['href'=>'#', 'label'=>'Menu B', 'icon'=>'fa-solid fa-tv'], ['href'=>'#', 'label'=>'Menu C', 'icon'=>'fa-solid fa-truck-pickup', 'class'=>'active', @@ -29,6 +30,8 @@ children | array that contains 2nd Level For top navigation in thwe 2nd level (below children) define a label value with a single minus character to draw a line: `['label'=>'-']` +The hamburger menu is rendered by `['label'=>'=']`. Remove this item when you don't want a left sidebar or it is static. + ### Show navigation on top The top navigation is for the placeholder `{{NAVI_TOP}}`. diff --git a/docs/40_Components/Tabbed_content.md b/docs/40_Components/Tabbed_content.md new file mode 100644 index 0000000000000000000000000000000000000000..7e0a3eb31a4a363747a03b3cd7b75582e7c623d9 --- /dev/null +++ b/docs/40_Components/Tabbed_content.md @@ -0,0 +1,41 @@ +## Tabbed content + +Show multiple horizontal tabs and a content container that switches its content by selecting a tab. + +### Syntax + +```php +$renderAdminLTE->getTabbedContent($aOptions, $asArray=false); +``` + +### Return + +{string} html code or {array} + +### Parameters + +* $aOptions - {array} options to describe the element + +Styling: + +Key | Description +--- | --- +asArray | boolean; if true it returns an array for tab list and container to draw them individually + +Content: + +Key | Description +--- | --- +tabs | tabs {array} key=tab label; value=content + +### Example + +```php +$renderAdminLTE->getTabbedContent(array ( + 'tabs' => array( + 'one'=>'content of tab one', + 'two'=>'content of 2nd tab', + 'three'=>'content of 3rd tab', + ) +)); +``` diff --git a/docs/style.css b/docs/style.css index 411c2b0c6a9d7e41dc8dc87fe24a39cfe0b6c2a0..45383c3288f17a74d88fc2ffca48307f794d4592 100644 --- a/docs/style.css +++ b/docs/style.css @@ -1,13 +1,14 @@ /* override css elements of daux.io blue theme - version 2022-11-30 + version 2023-11-10 */ :root { /* Axels Overrides */ - --color-text: #222; - --link-color: #822; - --brand-color: var(--color-secondary); + --color-text: #234; + --link-color: #228; + --brand-color: var(--color-text); --brand-background: var(--body-background); + --code-tag-border-color: #d8d8d8; --hr-color: none; --search-field-background: none; --search-field-border-color: none; @@ -46,9 +47,10 @@ .dark { /* Axels Overrides */ --color-text: #c0c0c0; - --link-color: #b44; + --link-color: #88e; --brand-color: var(--color-text); --brand-background: var(--body-background); + --body-background: #101418; --hr-color: none; --code-tag-background-color_: #bcc; --search-field-background: none; @@ -65,11 +67,11 @@ --axel_brand-pre-background-hover: rgb(255, 0, 51); ; --axel_h1_header: none; - --axel_h1: #777; + --axel_h1: #578; --axel_h1-bg: none; --axel_h1-bottom: none; --axel_h2: #467; - --axel_h2-bg: #202020; + --axel_h2-bg: none; --axel_h2-bottom: 0px solid #256; --axel_h2-hero-bottom: 2px solid #712; --axel_h3: #589; @@ -175,13 +177,15 @@ img{ .s-content .TableOfContentsContainer h4 { margin: 1em 0; - font-size: 100%; + font-size: 110%; text-align: center; - background-color: rgba(0, 0, 0, 0.05); + background-color: rgba(0, 0, 0, 0.1); padding: 0.3em; + font-weight: bold; + font-family: Arial; } ul.TableOfContents a{ - color: #666; + color: var(--color-text); } .s-content pre { background: var(--axel_pre-background); diff --git a/public_html/classes/render-adminlte.class.php b/public_html/classes/render-adminlte.class.php index 73254ba30feb9e236ddd518d31e85e1fb688e1e4..b62ed6166a95333baf2e37dbebcd88ba72bba580 100755 --- a/public_html/classes/render-adminlte.class.php +++ b/public_html/classes/render-adminlte.class.php @@ -582,6 +582,10 @@ class renderadminlte { if($aLink['label']=='-'){ return '<div class="dropdown-divider"></div>'; } + // special menu entry: hamburger menu item (label is "=") + if($aLink['label']=='='){ + return '<li class="nav-item"><a class="nav-link" data-widget="pushmenu" href="#" role="button"><i class="fas fa-bars"></i></a></li>'; + } $aChildren=isset($aLink['children']) && is_array($aLink['children']) && count($aLink['children']) ? $aLink['children'] : false; @@ -665,7 +669,7 @@ class renderadminlte { * @return string */ public function getTopNavigation($aNavItems, $aUlOptions=['class'=>'navbar-nav']){ - array_unshift($aNavItems, ['class'=>'nav-link', 'data-widget'=>'pushmenu', 'href'=>'#', 'role'=>'button', 'label'=>'<i class="fa-solid fa-bars"></i>']); + // array_unshift($aNavItems, ['class'=>'nav-link', 'data-widget'=>'pushmenu', 'href'=>'#', 'role'=>'button', 'label'=>'<i class="fa-solid fa-bars"></i>']); return $this->addWrapper('ul', $aUlOptions, $this->getNavItems($aNavItems)); } @@ -1224,6 +1228,11 @@ class renderadminlte { return $this->_tag('div', ['class'=>$sClass], $sContent.$sIcon.$sFooter); } + // ---------------------------------------------------------------------- + // + // PUBLIC FUNCTIONS :: CONTENT - FORM + // + // ---------------------------------------------------------------------- public function getHorizontalFormElement($sInput, $sLabel=false, $sId=false){ @@ -1345,4 +1354,66 @@ class renderadminlte { } + // ---------------------------------------------------------------------- + // + // PUBLIC FUNCTIONS :: CONTENT - TABBED CONTENT + // + // ---------------------------------------------------------------------- + + /** + * return a box with tabbed content + * @param array $aOptions hash with keys for all options + * - tabs {array} key=tab label; value=content + * @retunr string|array + */ + public function getTabbedContent($aOptions, $asArray=false){ + static $iTabCounter; + if( ! isset($aOptions['tabs']) || ! is_array($aOptions['tabs']) ){ + return false; + } + static $iTabCounter; + if (!isset($iTabCounter)){ + $iTabCounter=1; + } else { + $iTabCounter++; + } + + $id='tab-content-'.$iTabCounter; + $iCounter=0; + + $sTabs=''; + $sContent=''; + foreach($aOptions['tabs'] as $sLabel => $sTabContent){ + $iCounter++; + $sTabId=$id.'-tabitem-'.$iCounter.'-tab'; + $sContentId=$id.'-tabitem-'.$iCounter.'-content'; + + $sTabs.=$this->_tag('li', ['class'=>'nav-item'], + $this->_tag('a', [ + 'class'=>'nav-link'.($iCounter==1 ? ' active' : '' ), + 'id'=>$sTabId, + 'data-toggle'=>'tab', + 'href'=>'#'.$sContentId, + 'role'=>'tab', + 'aria-controls'=>'custom-tabs-one-profile', + 'aria-selected'=>($iCounter==1 ? true : false ), + ], + $sLabel) + ); + $sContent.=$this->_tag('div', [ + 'class'=>'tab-pane fade'.($iCounter==1 ? ' active show' : ''), + 'id'=>$sContentId, + 'role'=>'tabpanel', + 'aria-labelledby'=>$sTabId, + ], $sTabContent); + } + $sTabs=$this->_tag('ul', ['class'=>'nav nav-tabs', 'role'=>'tablist'], $sTabs); + $sContent=$this->_tag('div', ['class'=>'tab-content'], $sContent); + + return $asArray + ? ['tabs'=>$sTabs, 'content'=>$sContent] + : $sTabs . $sContent + ; + } + } diff --git a/public_html/config/navi_top.php b/public_html/config/navi_top.php index 55a294eafe14db13b074db271768e02b28ed2a53..6431da16391013e7aca5d373380124dc47a39f5a 100644 --- a/public_html/config/navi_top.php +++ b/public_html/config/navi_top.php @@ -1,8 +1,9 @@ <?php -// icons: https://fontawesome.com/v5/search?o=r&m=free +// icons: https://fontawesome.com/v6/search?o=r&m=free return [ + ['label'=>'='], ['href'=>'/index.php', 'label'=>'MyHome' , 'icon'=>'fa-solid fa-home', 'class'=>'bg-gray'], ['href'=>'#', 'label'=>'Contact' ], ['href'=>'#', 'label'=>'Help', diff --git a/public_html/config/navi_top.php.dist b/public_html/config/navi_top.php.dist index 55a294eafe14db13b074db271768e02b28ed2a53..718664275f0c5b88d868f2ab6e1dfc0eac8e5e43 100644 --- a/public_html/config/navi_top.php.dist +++ b/public_html/config/navi_top.php.dist @@ -3,6 +3,7 @@ // icons: https://fontawesome.com/v5/search?o=r&m=free return [ + ['label'=>'='], ['href'=>'/index.php', 'label'=>'MyHome' , 'icon'=>'fa-solid fa-home', 'class'=>'bg-gray'], ['href'=>'#', 'label'=>'Contact' ], ['href'=>'#', 'label'=>'Help',