From 0b69de332db4c253f58c592c15d97a24981c7d6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20B=C3=B6hmer?= Date: Sun, 13 Oct 2019 17:48:18 +0200 Subject: [PATCH] Implemented different themes for Part-DB. We use Bootswatch to provide different themed bootstrap CSS. --- assets/js/app.js | 7 ++- config/packages/twig.yaml | 1 + config/services.yaml | 5 +- package.json | 3 + src/Entity/UserSystem/User.php | 5 ++ src/Form/UserAdminForm.php | 5 ++ src/Form/UserSettingsType.php | 4 ++ templates/base.html.twig | 18 ++++++ webpack.config.js | 13 +++++ yarn.lock | 103 ++++++++++++++++++++++++++++++++- 10 files changed, 157 insertions(+), 7 deletions(-) diff --git a/assets/js/app.js b/assets/js/app.js index 99f05a3f..e4af039d 100644 --- a/assets/js/app.js +++ b/assets/js/app.js @@ -12,8 +12,9 @@ require('../css/app.css'); // Need jQuery? Install it with "yarn add jquery", then uncomment to require it. const $ = require('jquery'); -import 'bootstrap'; -import 'bootstrap/dist/css/bootstrap.min.css'; +//Only include javascript + + import '@fortawesome/fontawesome-free/css/all.css' @@ -27,6 +28,8 @@ import "patternfly-bootstrap-treeview/src/css/bootstrap-treeview.css" import "bootstrap-fileinput/css/fileinput.css" +require('bootstrap'); + //require( 'jszip' ); //#require( 'pdfmake' ); require( 'datatables.net-bs4' ); diff --git a/config/packages/twig.yaml b/config/packages/twig.yaml index a6e9458c..e19beb18 100644 --- a/config/packages/twig.yaml +++ b/config/packages/twig.yaml @@ -7,3 +7,4 @@ twig: globals: partdb_title: '%partdb_title%' default_currency: '%default_currency%' + global_theme: '%global_theme%' diff --git a/config/services.yaml b/config/services.yaml index 643ffecd..3a037bd8 100644 --- a/config/services.yaml +++ b/config/services.yaml @@ -11,8 +11,9 @@ parameters: banner: '' # The info text shown in the homepage use_gravatar: true # Set to false, if no Gravatar images should be used for user profiles. default_currency: 'EUR' # The currency that should be used - media_directory: 'public/media/' - db_version_fallback: '5.6' # Be sure to override this, in your .env with your real DB version + media_directory: 'public/media/' # The folder where uploaded attachment files are saved + db_version_fallback: '5.6' # Be sure to override this, in your .env with your real DB version + global_theme: '' # The theme to use globally (see public/build/themes/ for choices). Set to '' for default bootstrap theme services: # default configuration for services in *this* file diff --git a/package.json b/package.json index 145f64d0..a2b6b305 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,8 @@ "bootbox": "^5.1.0", "bootstrap-fileinput": "^5.0.1", "bootstrap-select": "^1.13.8", + "bootswatch": "^4.3.1", + "copy-webpack-plugin": "^5.0.4", "corejs-typeahead": "^1.2.1", "datatables.net-bs4": "^1.10.19", "datatables.net-buttons-bs4": "^1.5.4", @@ -34,6 +36,7 @@ "datatables.net-fixedheader-bs4": "^3.1.5", "datatables.net-select-bs4": "^1.2.7", "dompurify": "^2.0.6", + "exports-loader": "^0.7.0", "jquery-form": "^4.2.2", "jszip": "^3.2.0", "marked": "^0.7.0", diff --git a/src/Entity/UserSystem/User.php b/src/Entity/UserSystem/User.php index 6557bd99..265141ad 100644 --- a/src/Entity/UserSystem/User.php +++ b/src/Entity/UserSystem/User.php @@ -88,6 +88,10 @@ class User extends AttachmentContainingDBElement implements UserInterface, HasPe /** The User id of the anonymous user */ public const ID_ANONYMOUS = 1; + public const AVAILABLE_THEMES = ['bootstrap', 'cerulean', 'cosmo', 'cyborg', 'darkly', 'flatly', 'journal', + 'litera', 'lumen', 'lux', 'materia', 'minty', 'pulse', 'sandstone', 'simplex', 'sketchy', 'slate', 'solar', + 'spacelab', 'united', 'yeti']; + /** * @var Collection|UserAttachment[] * @ORM\OneToMany(targetEntity="App\Entity\Attachments\UserAttachment", mappedBy="element", cascade={"persist", "remove"}, orphanRemoval=true) @@ -166,6 +170,7 @@ class User extends AttachmentContainingDBElement implements UserInterface, HasPe /** * @var string|null The theme * @ORM\Column(type="string", name="config_theme", nullable=true) + * @Assert\Choice(choices=User::AVAILABLE_THEMES) */ protected $theme = ''; diff --git a/src/Form/UserAdminForm.php b/src/Form/UserAdminForm.php index 9a978943..3dd30ed3 100644 --- a/src/Form/UserAdminForm.php +++ b/src/Form/UserAdminForm.php @@ -35,6 +35,7 @@ namespace App\Form; use App\Entity\UserSystem\Group; use App\Entity\Base\NamedDBElement; use App\Entity\Base\StructuralDBElement; +use App\Entity\UserSystem\User; use App\Form\Permissions\PermissionsType; use App\Form\Permissions\PermissionType; use App\Form\Type\CurrencyEntityType; @@ -147,6 +148,10 @@ class UserAdminForm extends AbstractType ]) ->add('theme', ChoiceType::class, [ 'required' => false, + 'choices' => User::AVAILABLE_THEMES, + 'choice_label' => function ($entity, $key, $value) { + return $value; + }, 'placeholder' => $this->trans->trans('user_settings.theme.placeholder'), 'label' => $this->trans->trans('user.theme.label'), 'disabled' => !$this->security->isGranted('change_user_settings', $entity) diff --git a/src/Form/UserSettingsType.php b/src/Form/UserSettingsType.php index f559b22b..13177402 100644 --- a/src/Form/UserSettingsType.php +++ b/src/Form/UserSettingsType.php @@ -75,6 +75,10 @@ class UserSettingsType extends AbstractType ]) ->add('theme', ChoiceType::class, [ 'required' => false, + 'choices' => User::AVAILABLE_THEMES, + 'choice_label' => function ($entity, $key, $value) { + return $value; + }, 'placeholder' => $this->trans->trans('user_settings.theme.placeholder'), 'label' => $this->trans->trans('user.theme.label'), ]) diff --git a/templates/base.html.twig b/templates/base.html.twig index 89319e2b..5187fb42 100644 --- a/templates/base.html.twig +++ b/templates/base.html.twig @@ -15,7 +15,25 @@ {% apply trim %}{% block title %}{{ partdb_title}}{% endblock %}{% endapply %} {% block stylesheets %} + {# Include the main bootstrap theme based on user/global setting #} + + + + {% if not app.user.theme %} + {% set theme = global_theme %} + {% else %} + {% set theme = app.user.theme %} + {% endif %} + + {% if theme %} + + {% else %} + + {% endif %} + {{ encore_entry_link_tags('app') }} + + {% endblock %} diff --git a/webpack.config.js b/webpack.config.js index 172795e6..b6290e31 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -1,4 +1,5 @@ var Encore = require('@symfony/webpack-encore'); +const CopyPlugin = require('copy-webpack-plugin'); Encore // directory where compiled assets will be stored @@ -51,6 +52,18 @@ Encore // uncomment if you're having problems with a jQuery plugin .autoProvidejQuery() + .addPlugin(new CopyPlugin([ + { + from: 'node_modules/bootswatch/dist/*/*.min.css', + to: 'themes/[2].[ext]', + test: /.*([\/\\])(.+)([\/\\]).*\.css$/ + }, + { + from: 'node_modules/bootstrap/dist/css/bootstrap.min.css', + to: 'themes/bootstrap.css' + } + ])) + // uncomment if you use API Platform Admin (composer req api-admin) //.enableReactPreset() //.addEntry('admin', './assets/js/admin.js') diff --git a/yarn.lock b/yarn.lock index f6d6aadc..30f6f247 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1381,6 +1381,11 @@ bootstrap@^3.4.1: resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-3.4.1.tgz#c3a347d419e289ad11f4033e3c4132b87c081d72" integrity sha512-yN5oZVmRCwe5aKwzRj6736nSmKDX7pLYwsXiCj/EYmo16hODaBiT4En5btW/jhBF/seV+XMx3aYwukYC3A49DA== +bootswatch@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/bootswatch/-/bootswatch-4.3.1.tgz#be54748b420a1962dbcf9782605aac092f842e38" + integrity sha512-kNdpo/TnhO++aic1IODLIe1V0lx6pXwHMpwXMacpANDnuVDtgU1MUgUbVMC3rSWm4UcbImfwPraNYgjKDT0BtA== + brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" @@ -1565,6 +1570,26 @@ bytes@3.1.0: resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6" integrity sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg== +cacache@^11.3.3: + version "11.3.3" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-11.3.3.tgz#8bd29df8c6a718a6ebd2d010da4d7972ae3bbadc" + integrity sha512-p8WcneCytvzPxhDvYp31PD039vi77I12W+/KfR9S8AZbaiARFBCpsPJS+9uhWfeBfeAtW7o/4vt3MUqLkbY6nA== + dependencies: + bluebird "^3.5.5" + chownr "^1.1.1" + figgy-pudding "^3.5.1" + glob "^7.1.4" + graceful-fs "^4.1.15" + lru-cache "^5.1.1" + mississippi "^3.0.0" + mkdirp "^0.5.1" + move-concurrently "^1.0.1" + promise-inflight "^1.0.1" + rimraf "^2.6.3" + ssri "^6.0.1" + unique-filename "^1.1.1" + y18n "^4.0.0" + cacache@^12.0.2: version "12.0.3" resolved "https://registry.yarnpkg.com/cacache/-/cacache-12.0.3.tgz#be99abba4e1bf5df461cd5a2c1071fc432573390" @@ -1936,6 +1961,24 @@ copy-descriptor@^0.1.0: resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= +copy-webpack-plugin@^5.0.4: + version "5.0.4" + resolved "https://registry.yarnpkg.com/copy-webpack-plugin/-/copy-webpack-plugin-5.0.4.tgz#c78126f604e24f194c6ec2f43a64e232b5d43655" + integrity sha512-YBuYGpSzoCHSSDGyHy6VJ7SHojKp6WHT4D7ItcQFNAYx2hrwkMe56e97xfVR0/ovDuMTrMffXUiltvQljtAGeg== + dependencies: + cacache "^11.3.3" + find-cache-dir "^2.1.0" + glob-parent "^3.1.0" + globby "^7.1.1" + is-glob "^4.0.1" + loader-utils "^1.2.3" + minimatch "^3.0.4" + normalize-path "^3.0.0" + p-limit "^2.2.0" + schema-utils "^1.0.0" + serialize-javascript "^1.7.0" + webpack-log "^2.0.0" + core-js-compat@^3.1.1: version "3.2.1" resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.2.1.tgz#0cbdbc2e386e8e00d3b85dc81c848effec5b8150" @@ -2486,6 +2529,13 @@ diffie-hellman@^5.0.0: miller-rabin "^4.0.0" randombytes "^2.0.0" +dir-glob@^2.0.0: + version "2.2.2" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-2.2.2.tgz#fa09f0694153c8918b18ba0deafae94769fc50c4" + integrity sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw== + dependencies: + path-type "^3.0.0" + dns-equal@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/dns-equal/-/dns-equal-1.0.0.tgz#b39e7f1da6eb0a75ba9c17324b34753c47e0654d" @@ -2939,6 +2989,14 @@ expand-tilde@^2.0.0, expand-tilde@^2.0.2: dependencies: homedir-polyfill "^1.0.1" +exports-loader@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/exports-loader/-/exports-loader-0.7.0.tgz#84881c784dea6036b8e1cd1dac3da9b6409e21a5" + integrity sha512-RKwCrO4A6IiKm0pG3c9V46JxIHcDplwwGJn6+JJ1RcVnh/WSGJa0xkmk5cRVtgOPzCAtTMGj2F7nluh9L0vpSA== + dependencies: + loader-utils "^1.1.0" + source-map "0.5.0" + express@^4.17.1: version "4.17.1" resolved "https://registry.yarnpkg.com/express/-/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134" @@ -3307,7 +3365,7 @@ glob-parent@^3.1.0: is-glob "^3.1.0" path-dirname "^1.0.0" -glob@^7.0.3, glob@^7.1.3, glob@^7.1.4: +glob@^7.0.3, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4: version "7.1.4" resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.4.tgz#aa608a2f6c577ad357e1ae5a5c26d9a8d1969255" integrity sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A== @@ -3371,6 +3429,18 @@ globby@^6.1.0: pify "^2.0.0" pinkie-promise "^2.0.0" +globby@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/globby/-/globby-7.1.1.tgz#fb2ccff9401f8600945dfada97440cca972b8680" + integrity sha1-+yzP+UAfhgCUXfral0QMypcrhoA= + dependencies: + array-union "^1.0.1" + dir-glob "^2.0.0" + glob "^7.1.2" + ignore "^3.3.5" + pify "^3.0.0" + slash "^1.0.0" + graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6: version "4.2.2" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.2.tgz#6f0952605d0140c1cfdb138ed005775b92d67b02" @@ -3639,6 +3709,11 @@ ignore-walk@^3.0.1: dependencies: minimatch "^3.0.4" +ignore@^3.3.5: + version "3.3.10" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.10.tgz#0a97fb876986e8081c631160f8f9f389157f0043" + integrity sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug== + immediate@~3.0.5: version "3.0.6" resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.0.6.tgz#9db1dbd0faf8de6fbe0f5dd5e56bb606280de69b" @@ -3899,7 +3974,7 @@ is-glob@^3.1.0: dependencies: is-extglob "^2.1.0" -is-glob@^4.0.0: +is-glob@^4.0.0, is-glob@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== @@ -5062,7 +5137,7 @@ p-limit@^1.1.0: dependencies: p-try "^1.0.0" -p-limit@^2.0.0: +p-limit@^2.0.0, p-limit@^2.2.0: version "2.2.1" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.2.1.tgz#aa07a788cc3151c939b5131f63570f0dd2009537" integrity sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg== @@ -5220,6 +5295,13 @@ path-type@^2.0.0: dependencies: pify "^2.0.0" +path-type@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" + integrity sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg== + dependencies: + pify "^3.0.0" + patternfly-bootstrap-treeview@^2.1.8: version "2.1.10" resolved "https://registry.yarnpkg.com/patternfly-bootstrap-treeview/-/patternfly-bootstrap-treeview-2.1.10.tgz#f96043734bb4ecac951783e2745e3f9a8873ffd4" @@ -5264,6 +5346,11 @@ pify@^2.0.0: resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw= +pify@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" + integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY= + pify@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" @@ -6320,6 +6407,11 @@ simple-swizzle@^0.2.2: dependencies: is-arrayish "^0.3.1" +slash@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" + integrity sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU= + snapdragon-node@^2.0.1: version "2.1.1" resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" @@ -6399,6 +6491,11 @@ source-map-url@^0.4.0: resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM= +source-map@0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.0.tgz#0fe96503ac86a5adb5de63f4e412ae4872cdbe86" + integrity sha1-D+llA6yGpa213mP05BKuSHLNvoY= + source-map@^0.5.0, source-map@^0.5.3, source-map@^0.5.6, source-map@^0.5.7: version "0.5.7" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"