partkeepr

fork of partkeepr
git clone https://git.e1e0.net/partkeepr.git
Log | Files | Refs | Submodules | README | LICENSE

commit 2edc04b4a1dee261516f21e08c5bbbb7bc4e0b0e
parent cfce05ce2cdc84ab8a556a55338d829ea10329c2
Author: Felicia Hummel <felicia@partkeepr.com>
Date:   Thu, 19 Jan 2017 18:05:22 +0100

Added theme selector

Diffstat:
Msrc/PartKeepr/FrontendBundle/Resources/public/css/PartKeepr.css | 118++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++---
Asrc/PartKeepr/FrontendBundle/Resources/public/images/partkeepr_loading.svg | 125+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/PartKeepr/FrontendBundle/Resources/public/js/Components/MenuBar.js | 46++++++++++++++++++++++++++++++++++++++++++++--
Msrc/PartKeepr/FrontendBundle/Resources/public/js/PartKeepr.js | 42+++++++++++++++++++++++++++++++++++++++---
Msrc/PartKeepr/FrontendBundle/Resources/views/index.html.twig | 30++++++++++++++++++++++++++++--
5 files changed, 350 insertions(+), 11 deletions(-)

diff --git a/src/PartKeepr/FrontendBundle/Resources/public/css/PartKeepr.css b/src/PartKeepr/FrontendBundle/Resources/public/css/PartKeepr.css @@ -23,13 +23,13 @@ text-align: center; } -.x-title-wrappable-text>div { +.x-title-wrappable-text > div { overflow: auto; white-space: normal; vertical-align: top; } -.x-title-wrappable-text>div>div { +.x-title-wrappable-text > div > div { font-size: 20px; line-height: normal; } @@ -74,7 +74,7 @@ .partkeepr-part-manager-compact { background-position: top left; background-repeat: no-repeat; - display:inline-block; + display: inline-block; width: 73px; height: 43px; line-height: 16px; @@ -85,7 +85,7 @@ .partkeepr-part-manager-standard { background-position: top left; background-repeat: no-repeat; - display:inline-block; + display: inline-block; width: 73px; height: 43px; line-height: 16px; @@ -93,3 +93,113 @@ background-image: url(../images/config/layout-standard.png); } + +#loader-wrapper { + display: flex; + justify-content: center; + align-items: center; + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + z-index: 1000; + background-color: white; +} + +#loader-message { + position: fixed; + top: 70%; + text-align: center; + font-size: 30px; +} + +#loader-logo { + background-image: url(../images/partkeepr_loading.svg); + background-repeat: no-repeat; + -webkit-background-size: 100%; + background-size: 100%; + height: 150px; + width: 150px; + position: fixed; + top: 50%; +left: 50%; +margin-top: -75px; +margin-left: -75px; + +} + +#loader { + display: block; + width: 200px; + height: 200px; + border-radius: 50%; + border: 3px solid transparent; + border-top-color: #0087b0; + background-position: center; + -webkit-animation: spin 2s linear infinite; /* Chrome, Opera 15+, Safari 5+ */ + animation: spin 2s linear infinite; /* Chrome, Firefox 16+, IE 10+, Opera */ + top: 50%; + left: 50%; + margin-top: -103px; + margin-left: -103px; + position: fixed; +} + +#loader:before { + content: ""; + position: absolute; + top: 5px; + left: 5px; + right: 5px; + bottom: 5px; + border-radius: 50%; + border: 3px solid transparent; + border-top-color: #007497; + + -webkit-animation: spin 3s linear infinite; /* Chrome, Opera 15+, Safari 5+ */ + animation: spin 3s linear infinite; /* Chrome, Firefox 16+, IE 10+, Opera */ +} + +#loader:after { + content: ""; + position: absolute; + top: 13px; + left: 13px; + right: 13px; + bottom: 13px; + border-radius: 50%; + border: 3px solid transparent; + border-top-color: #005d7a; + + -webkit-animation: spin 1.5s linear infinite; /* Chrome, Opera 15+, Safari 5+ */ + animation: spin 1.5s linear infinite; /* Chrome, Firefox 16+, IE 10+, Opera */ +} + +@-webkit-keyframes spin { + 0% { + -webkit-transform: rotate(0deg); /* Chrome, Opera 15+, Safari 3.1+ */ + -ms-transform: rotate(0deg); /* IE 9 */ + transform: rotate(0deg); /* Firefox 16+, IE 10+, Opera */ + } + 100% { + -webkit-transform: rotate(360deg); /* Chrome, Opera 15+, Safari 3.1+ */ + -ms-transform: rotate(360deg); /* IE 9 */ + transform: rotate(360deg); /* Firefox 16+, IE 10+, Opera */ + } +} + +@keyframes spin { + 0% { + -webkit-transform: rotate(0deg); /* Chrome, Opera 15+, Safari 3.1+ */ + -ms-transform: rotate(0deg); /* IE 9 */ + transform: rotate(0deg); /* Firefox 16+, IE 10+, Opera */ + } + 100% { + -webkit-transform: rotate(360deg); /* Chrome, Opera 15+, Safari 3.1+ */ + -ms-transform: rotate(360deg); /* IE 9 */ + transform: rotate(360deg); /* Firefox 16+, IE 10+, Opera */ + } +} + +s diff --git a/src/PartKeepr/FrontendBundle/Resources/public/images/partkeepr_loading.svg b/src/PartKeepr/FrontendBundle/Resources/public/images/partkeepr_loading.svg @@ -0,0 +1,125 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="128" + height="128" + id="svg2" + version="1.1" + inkscape:version="0.92.0 r15299" + sodipodi:docname="partkeepr_loading.svg"> + <defs + id="defs4"> + <linearGradient + id="linearGradient3935"> + <stop + style="stop-color:#ffffff;stop-opacity:1;" + offset="0" + id="stop3937" /> + <stop + style="stop-color:#000000;stop-opacity:1;" + offset="1" + id="stop3939" /> + </linearGradient> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient3935" + id="linearGradient3941" + x1="156.828" + y1="386.38205" + x2="671.87634" + y2="386.38205" + gradientUnits="userSpaceOnUse" + gradientTransform="translate(6.0630807,-15.157702)" /> + </defs> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="2.3325" + inkscape:cx="46.793106" + inkscape:cy="41.966372" + inkscape:document-units="px" + inkscape:current-layer="layer1" + showgrid="true" + inkscape:window-width="1920" + inkscape:window-height="1080" + inkscape:window-x="4480" + inkscape:window-y="0" + inkscape:window-maximized="0" + inkscape:snap-bbox="false" + inkscape:snap-bbox-midpoints="true" + inkscape:snap-nodes="true" + showguides="true" + inkscape:guide-bbox="true" + inkscape:snap-global="false" + fit-margin-top="0" + fit-margin-left="0" + fit-margin-right="0" + fit-margin-bottom="0"> + <inkscape:grid + type="xygrid" + id="grid4103" + empspacing="2" + visible="true" + enabled="true" + snapvisiblegridlinesonly="true" + spacingx="5.3333333" + spacingy="5.3333333" + originx="-20.147583" + originy="-652.55306" /> + </sodipodi:namedview> + <metadata + id="metadata7"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title></dc:title> + </cc:Work> + </rdf:RDF> + </metadata> + <g + inkscape:label="Layer 1" + inkscape:groupmode="layer" + id="layer1" + transform="translate(-20.147583,-341.96661)"> + <path + sodipodi:type="arc" + style="fill:#003849;fill-opacity:1;stroke:none;stroke-width:0.93659103" + id="path2985" + sodipodi:cx="84.147583" + sodipodi:cy="405.96661" + sodipodi:rx="64" + sodipodi:ry="64" + d="M 148.14758,405.96661 A 64,64 0 0 1 84.21127,469.96658 64,64 0 0 1 20.14771,406.09399 64,64 0 0 1 83.956524,341.9669 64,64 0 0 1 148.14708,405.71187" + sodipodi:start="0" + sodipodi:end="6.2792049" + sodipodi:open="true" + inkscape:export-filename="/home/felicitus/temp/test.png" + inkscape:export-xdpi="18" + inkscape:export-ydpi="18" /> + <path + style="fill:none;stroke:#ffffff;stroke-width:13.784688;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:0;stroke-dasharray:none;stroke-opacity:1" + d="m 63.896014,439.50084 3.685001,-18.09777 c 0.18712,-0.91898 0.879642,-4.32009 3.334954,-7.35191 12.619513,-12.87705 32.937431,-3.96758 37.347251,-25.09477 3.77325,-19.0299 -19.635283,-16.4008 -42.610035,-16.4008 h -0.636949" + id="path4101" + inkscape:connector-curvature="0" + sodipodi:nodetypes="cccccc" + inkscape:export-xdpi="18" + inkscape:export-ydpi="18" + inkscape:export-filename="/home/felicitus/temp/test.png" /> + </g> +</svg> diff --git a/src/PartKeepr/FrontendBundle/Resources/public/js/Components/MenuBar.js b/src/PartKeepr/FrontendBundle/Resources/public/js/Components/MenuBar.js @@ -6,7 +6,8 @@ Ext.define('PartKeepr.MenuBar', { menu: [] }, - createMenu: function (target, menuPath, root) { + createMenu: function (target, menuPath, root) + { var item = menuPath.shift(), newItem; if (item === undefined) { @@ -39,7 +40,8 @@ Ext.define('PartKeepr.MenuBar', { return root; }, - initComponent: function () { + initComponent: function () + { var target, menuItemIterator; this.ui = "mainmenu"; @@ -85,8 +87,48 @@ Ext.define('PartKeepr.MenuBar', { this.createMenu(target, target.menuPath, this.menu); } + this.themesMenu = []; + var checked; + + this.themesMenu.push({ + text: "Warning: Theme support is a beta-feature!", + disabled: true + }); + + for (var i in window.themes) { + if (window.theme == i) { + checked = true; + } else { + checked = false; + } + this.themesMenu.push({ + text: window.themes[i].themeName, + theme: i, + group: 'theme', + checked: checked + }); + } + this.menu.menu.push({text: i18n("Theme"), type: 'themes', menu: this.themesMenu}); + + this.items = this.menu.menu; this.callParent(); + }, + selectTheme: function (theme) { + var i,j,menuItem; + + for (i=0;i<this.items.getCount();i++) { + if (this.items.getAt(i).type == "themes") { + for (j=0;j<this.items.getAt(i).menu.items.getCount();j++) { + menuItem = this.items.getAt(i).menu.items.getAt(j); + + if (menuItem.theme === theme) { + menuItem.setChecked(true); + } + } + + } + } } }); diff --git a/src/PartKeepr/FrontendBundle/Resources/public/js/PartKeepr.js b/src/PartKeepr/FrontendBundle/Resources/public/js/PartKeepr.js @@ -14,7 +14,7 @@ Ext.application({ launch: function () { Ext.setGlyphFontFamily('FontAwesome'); - Ext.get("loading").hide(); + Ext.get("loader-wrapper").hide(); Ext.setLocale('en_US'); this.createLayout(); @@ -54,6 +54,10 @@ Ext.application({ if (typeof item.target === "function") { this.openAppItem(item.target["$className"]); } + + if (typeof(item.theme) === "string") { + this.switchTheme(item.theme); + } }, openAppItem: function (target) { @@ -102,12 +106,18 @@ Ext.application({ this.getUserPreferenceStore().loadRecords(records.records); + var preferredTheme = this.getUserPreference("partkeepr.user.theme", null); + this.createPartManager(); this.menuBar.enable(); this.doSystemStatusCheck(); + if (preferredTheme !== null && preferredTheme !== window.theme) { + this.switchTheme(preferredTheme); + } + this.unacknowledgedNoticesTask = Ext.TaskManager.start({ run: this.doUnacknowledgedNoticesCheck, scope: this, @@ -551,7 +561,7 @@ Ext.application({ this.menuBar = Ext.create("PartKeepr.MenuBar"); this.menuBar.disable(); - Ext.create('Ext.container.Viewport', { + this.viewPort = Ext.create('Ext.container.Viewport', { layout: 'fit', items: [ { @@ -660,7 +670,8 @@ Ext.application({ format.currencySign = PartKeepr.getApplication().getUserPreference("partkeepr.formatting.currency.symbol", "€"); if (code !== null) { - var currency = PartKeepr.getApplication().getCurrencyStore().findRecord("code", code, 0, false, false, true); + var currency = PartKeepr.getApplication().getCurrencyStore().findRecord("code", code, 0, false, false, + true); if (currency !== null) { format.currencySign = currency.get("symbol"); @@ -679,6 +690,31 @@ Ext.application({ } return format.currency(value); + }, + switchTheme: function (theme) + { + if (window.themes[theme]) { + window.theme = theme; + this.setUserPreference("partkeepr.user.theme", theme); + this.menuBar.selectTheme(theme); + Ext.util.CSS.swapStyleSheet("theme", window.themes[theme].themeUri); + Ext.util.CSS.swapStyleSheet("themeUx", window.themes[theme].themeUxUri); + + Ext.get("loader-wrapper").show(); + Ext.get("loader-message").setHtml(i18n("Applying theme…")); + + + Ext.defer(this.updateThemeLayout, 1000, this); + } + }, + updateThemeLayout: function () + { + Ext.get("loader-wrapper").hide(); + + Ext.defer(this.refreshLayout, 100, this); + }, + refreshLayout: function () { + this.viewPort.updateLayout(); } }); diff --git a/src/PartKeepr/FrontendBundle/Resources/views/index.html.twig b/src/PartKeepr/FrontendBundle/Resources/views/index.html.twig @@ -8,10 +8,18 @@ <base href="{{ app.request.getBaseURL() }}"/> + {% set themes = {"classic": "Classic", "crisp":"Crisp", "gray":"Gray", "neptune": "Neptune", "triton": "Triton", "aria": "Aria"} %} + {% set defaultTheme = "classic" %} + + {% set themeUri %}js/packages/extjs6/build/classic/theme-{{ defaultTheme }}/resources/theme-{{ defaultTheme }}-all.css{% endset %} + {% set themeUxUri %}js/packages/extjs6/build/packages/ux/classic/{{ defaultTheme }}/resources/ux-all.css{% endset %} + + <link id="theme" rel="stylesheet" href="{{ asset(themeUri) }}"/> + <link id="themeUx" rel="stylesheet" href="{{ asset(themeUxUri) }}"/> + <!-- Include the ExtJS CSS Theme --> {% stylesheets filter='cssrewrite' - 'js/packages/extjs6/build/classic/theme-classic/resources/theme-classic-all.css' 'js/packages/extjs6/build/packages/ux/classic/classic/resources/ux-all.css' 'js/packages/extjs6/build/packages/charts/classic/neptune/resources/charts-all.css' 'atelierspierrot/famfamfam-silk-sprite/silk-icons-sprite.css' @@ -306,7 +314,25 @@ {% endjavascripts %} </head> <body> -<div id="loading"><span class="logo"></span></div> +<div id="loader-wrapper"> + <div id="loader-logo"></div> + <div id="loader"></div> + <div id="loader-message"></div> +</div> + <script type="text/javascript"> + window.themes = {}; + window.theme = "{{ defaultTheme }}"; + {% for themeId, themeName in themes %} + {% set themeUri %}js/packages/extjs6/build/classic/theme-{{ themeId }}/resources/theme-{{ themeId }}-all.css{% endset %} + {% set themeUxUri %}js/packages/extjs6/build/packages/ux/classic/{{ themeId }}/resources/ux-all.css{% endset %} + + window.themes.{{ themeId }} = { + themeUri: '{{ asset(themeUri) }}', + themeUxUri: '{{ asset(themeUxUri) }}', + themeName: '{{ themeName }}' + }; + {% endfor %} + </script> <script type="text/javascript"> window.parameters = {{ parameters|json_encode|raw }}; </script>