Baseline: plugin butterfly v2.1.0 como recebido (pré-fixes GLPI 11)
Estado original vindo do servidor de origem via tar.gz, antes da rodada de conformidade com a knowledge-base e fixes de GLPI 11. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
22
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
# Dependências
|
||||
vendor/
|
||||
node_modules/
|
||||
|
||||
# macOS
|
||||
.DS_Store
|
||||
**/.DS_Store
|
||||
|
||||
# IDE
|
||||
.idea/
|
||||
.vscode/
|
||||
|
||||
# Logs
|
||||
*.log
|
||||
|
||||
# Build artifacts
|
||||
*.zip
|
||||
*.tar.gz
|
||||
|
||||
# Arquivos de teste (não publicar)
|
||||
front/test*.php
|
||||
ajax/test*.php
|
||||
339
LICENSE.md
Normal file
|
|
@ -0,0 +1,339 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The licenses for most software are designed to take away your
|
||||
freedom to share and change it. By contrast, the GNU General Public
|
||||
License is intended to guarantee your freedom to share and change free
|
||||
software--to make sure the software is free for all its users. This
|
||||
General Public License applies to most of the Free Software
|
||||
Foundation's software and to any other program whose authors commit to
|
||||
using it. (Some other Free Software Foundation software is covered by
|
||||
the GNU Lesser General Public License instead.) You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
this service if you wish), that you receive source code or can get it
|
||||
if you want it, that you can change the software or use pieces of it
|
||||
in new free programs; and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to make restrictions that forbid
|
||||
anyone to deny you these rights or to ask you to surrender the rights.
|
||||
These restrictions translate to certain responsibilities for you if you
|
||||
distribute copies of the software, or if you modify it.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must give the recipients all the rights that
|
||||
you have. You must make sure that they, too, receive or can get the
|
||||
source code. And you must show them these terms so they know their
|
||||
rights.
|
||||
|
||||
We protect your rights with two steps: (1) copyright the software, and
|
||||
(2) offer you this license which gives you legal permission to copy,
|
||||
distribute and/or modify the software.
|
||||
|
||||
Also, for each author's protection and ours, we want to make certain
|
||||
that everyone understands that there is no warranty for this free
|
||||
software. If the software is modified by someone else and passed on, we
|
||||
want its recipients to know that what they have is not the original, so
|
||||
that any problems introduced by others will not reflect on the original
|
||||
authors' reputations.
|
||||
|
||||
Finally, any free program is threatened constantly by software
|
||||
patents. We wish to avoid the danger that redistributors of a free
|
||||
program will individually obtain patent licenses, in effect making the
|
||||
program proprietary. To prevent this, we have made it clear that any
|
||||
patent must be licensed for everyone's free use or not licensed at all.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. This License applies to any program or other work which contains
|
||||
a notice placed by the copyright holder saying it may be distributed
|
||||
under the terms of this General Public License. The "Program", below,
|
||||
refers to any such program or work, and a "work based on the Program"
|
||||
means either the Program or any derivative work under copyright law:
|
||||
that is to say, a work containing the Program or a portion of it,
|
||||
either verbatim or with modifications and/or translated into another
|
||||
language. (Hereinafter, translation is included without limitation in
|
||||
the term "modification".) Each licensee is addressed as "you".
|
||||
|
||||
Activities other than copying, distribution and modification are not
|
||||
covered by this License; they are outside its scope. The act of
|
||||
running the Program is not restricted, and the output from the Program
|
||||
is covered only if its contents constitute a work based on the
|
||||
Program (independent of having been made by running the Program).
|
||||
Whether that is true depends on what the Program does.
|
||||
|
||||
1. You may copy and distribute verbatim copies of the Program's
|
||||
source code as you receive it, in any medium, provided that you
|
||||
conspicuously and appropriately publish on each copy an appropriate
|
||||
copyright notice and disclaimer of warranty; keep intact all the
|
||||
notices that refer to this License and to the absence of any warranty;
|
||||
and give any other recipients of the Program a copy of this License
|
||||
along with the Program.
|
||||
|
||||
You may charge a fee for the physical act of transferring a copy, and
|
||||
you may at your option offer warranty protection in exchange for a fee.
|
||||
|
||||
2. You may modify your copy or copies of the Program or any portion
|
||||
of it, thus forming a work based on the Program, and copy and
|
||||
distribute such modifications or work under the terms of Section 1
|
||||
above, provided that you also meet all of these conditions:
|
||||
|
||||
a) You must cause the modified files to carry prominent notices
|
||||
stating that you changed the files and the date of any change.
|
||||
|
||||
b) You must cause any work that you distribute or publish, that in
|
||||
whole or in part contains or is derived from the Program or any
|
||||
part thereof, to be licensed as a whole at no charge to all third
|
||||
parties under the terms of this License.
|
||||
|
||||
c) If the modified program normally reads commands interactively
|
||||
when run, you must cause it, when started running for such
|
||||
interactive use in the most ordinary way, to print or display an
|
||||
announcement including an appropriate copyright notice and a
|
||||
notice that there is no warranty (or else, saying that you provide
|
||||
a warranty) and that users may redistribute the program under
|
||||
these conditions, and telling the user how to view a copy of this
|
||||
License. (Exception: if the Program itself is interactive but
|
||||
does not normally print such an announcement, your work based on
|
||||
the Program is not required to print an announcement.)
|
||||
|
||||
These requirements apply to the modified work as a whole. If
|
||||
identifiable sections of that work are not derived from the Program,
|
||||
and can be reasonably considered independent and separate works in
|
||||
themselves, then this License, and its terms, do not apply to those
|
||||
sections when you distribute them as separate works. But when you
|
||||
distribute the same sections as part of a whole which is a work based
|
||||
on the Program, the distribution of the whole must be on the terms of
|
||||
this License, whose permissions for other licensees extend to the
|
||||
entire whole, and thus to each and every part regardless of who wrote it.
|
||||
|
||||
Thus, it is not the intent of this section to claim rights or contest
|
||||
your rights to work written entirely by you; rather, the intent is to
|
||||
exercise the right to control the distribution of derivative or
|
||||
collective works based on the Program.
|
||||
|
||||
In addition, mere aggregation of another work not based on the Program
|
||||
with the Program (or with a work based on the Program) on a volume of
|
||||
a storage or distribution medium does not bring the other work under
|
||||
the scope of this License.
|
||||
|
||||
3. You may copy and distribute the Program (or a work based on it,
|
||||
under Section 2) in object code or executable form under the terms of
|
||||
Sections 1 and 2 above provided that you also do one of the following:
|
||||
|
||||
a) Accompany it with the complete corresponding machine-readable
|
||||
source code, which must be distributed under the terms of Sections
|
||||
1 and 2 above on a medium customarily used for software interchange; or,
|
||||
|
||||
b) Accompany it with a written offer, valid for at least three
|
||||
years, to give any third party, for a charge no more than your
|
||||
cost of physically performing source distribution, a complete
|
||||
machine-readable copy of the corresponding source code, to be
|
||||
distributed under the terms of Sections 1 and 2 above on a medium
|
||||
customarily used for software interchange; or,
|
||||
|
||||
c) Accompany it with the information you received as to the offer
|
||||
to distribute corresponding source code. (This alternative is
|
||||
allowed only for noncommercial distribution and only if you
|
||||
received the program in object code or executable form with such
|
||||
an offer, in accord with Subsection b above.)
|
||||
|
||||
The source code for a work means the preferred form of the work for
|
||||
making modifications to it. For an executable work, complete source
|
||||
code means all the source code for all modules it contains, plus any
|
||||
associated interface definition files, plus the scripts used to
|
||||
control compilation and installation of the executable. However, as a
|
||||
special exception, the source code distributed need not include
|
||||
anything that is normally distributed (in either source or binary
|
||||
form) with the major components (compiler, kernel, and so on) of the
|
||||
operating system on which the executable runs, unless that component
|
||||
itself accompanies the executable.
|
||||
|
||||
If distribution of executable or object code is made by offering
|
||||
access to copy from a designated place, then offering equivalent
|
||||
access to copy the source code from the same place counts as
|
||||
distribution of the source code, even though third parties are not
|
||||
compelled to copy the source along with the object code.
|
||||
|
||||
4. You may not copy, modify, sublicense, or distribute the Program
|
||||
except as expressly provided under this License. Any attempt
|
||||
otherwise to copy, modify, sublicense or distribute the Program is
|
||||
void, and will automatically terminate your rights under this License.
|
||||
However, parties who have received copies, or rights, from you under
|
||||
this License will not have their licenses terminated so long as such
|
||||
parties remain in full compliance.
|
||||
|
||||
5. You are not required to accept this License, since you have not
|
||||
signed it. However, nothing else grants you permission to modify or
|
||||
distribute the Program or its derivative works. These actions are
|
||||
prohibited by law if you do not accept this License. Therefore, by
|
||||
modifying or distributing the Program (or any work based on the
|
||||
Program), you indicate your acceptance of this License to do so, and
|
||||
all its terms and conditions for copying, distributing or modifying
|
||||
the Program or works based on it.
|
||||
|
||||
6. Each time you redistribute the Program (or any work based on the
|
||||
Program), the recipient automatically receives a license from the
|
||||
original licensor to copy, distribute or modify the Program subject to
|
||||
these terms and conditions. You may not impose any further
|
||||
restrictions on the recipients' exercise of the rights granted herein.
|
||||
You are not responsible for enforcing compliance by third parties to
|
||||
this License.
|
||||
|
||||
7. If, as a consequence of a court judgment or allegation of patent
|
||||
infringement or for any other reason (not limited to patent issues),
|
||||
conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot
|
||||
distribute so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you
|
||||
may not distribute the Program at all. For example, if a patent
|
||||
license would not permit royalty-free redistribution of the Program by
|
||||
all those who receive copies directly or indirectly through you, then
|
||||
the only way you could satisfy both it and this License would be to
|
||||
refrain entirely from distribution of the Program.
|
||||
|
||||
If any portion of this section is held invalid or unenforceable under
|
||||
any particular circumstance, the balance of the section is intended to
|
||||
apply and the section as a whole is intended to apply in other
|
||||
circumstances.
|
||||
|
||||
It is not the purpose of this section to induce you to infringe any
|
||||
patents or other property right claims or to contest validity of any
|
||||
such claims; this section has the sole purpose of protecting the
|
||||
integrity of the free software distribution system, which is
|
||||
implemented by public license practices. Many people have made
|
||||
generous contributions to the wide range of software distributed
|
||||
through that system in reliance on consistent application of that
|
||||
system; it is up to the author/donor to decide if he or she is willing
|
||||
to distribute software through any other system and a licensee cannot
|
||||
impose that choice.
|
||||
|
||||
This section is intended to make thoroughly clear what is believed to
|
||||
be a consequence of the rest of this License.
|
||||
|
||||
8. If the distribution and/or use of the Program is restricted in
|
||||
certain countries either by patents or by copyrighted interfaces, the
|
||||
original copyright holder who places the Program under this License
|
||||
may add an explicit geographical distribution limitation excluding
|
||||
those countries, so that distribution is permitted only in or among
|
||||
countries not thus excluded. In such case, this License incorporates
|
||||
the limitation as if written in the body of this License.
|
||||
|
||||
9. The Free Software Foundation may publish revised and/or new versions
|
||||
of the General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the Program
|
||||
specifies a version number of this License which applies to it and "any
|
||||
later version", you have the option of following the terms and conditions
|
||||
either of that version or of any later version published by the Free
|
||||
Software Foundation. If the Program does not specify a version number of
|
||||
this License, you may choose any version ever published by the Free Software
|
||||
Foundation.
|
||||
|
||||
10. If you wish to incorporate parts of the Program into other free
|
||||
programs whose distribution conditions are different, write to the author
|
||||
to ask for permission. For software which is copyrighted by the Free
|
||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||
make exceptions for this. Our decision will be guided by the two goals
|
||||
of preserving the free status of all derivatives of our free software and
|
||||
of promoting the sharing and reuse of software generally.
|
||||
|
||||
NO WARRANTY
|
||||
|
||||
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||
REPAIR OR CORRECTION.
|
||||
|
||||
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGES.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
convey the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program is interactive, make it output a short notice like this
|
||||
when it starts in an interactive mode:
|
||||
|
||||
Gnomovision version 69, Copyright (C) year name of author
|
||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, the commands you use may
|
||||
be called something other than `show w' and `show c'; they could even be
|
||||
mouse-clicks or menu items--whatever suits your program.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or your
|
||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||
necessary. Here is a sample; alter the names:
|
||||
|
||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||
|
||||
<signature of Ty Coon>, 1 April 1989
|
||||
Ty Coon, President of Vice
|
||||
|
||||
This General Public License does not permit incorporating your program into
|
||||
proprietary programs. If your program is a subroutine library, you may
|
||||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
||||
8
README.md
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
# Butterfly for GLPI >= 10.0 (Compatible with GLPI 11.x)
|
||||
|
||||
Allow customization of logos, background and custom CSSs
|
||||
|
||||
# Installation
|
||||
* Uncompress the archive to the `<GLPI_ROOT>/plugins/butterfly` directory
|
||||
* Navigate to the Configuration > Plugins page,
|
||||
* Install and activate the plugin.
|
||||
199
RoboFile.php
Normal file
|
|
@ -0,0 +1,199 @@
|
|||
<?php
|
||||
|
||||
use Symfony\Component\Finder\Finder;
|
||||
|
||||
/**
|
||||
* This is project's console commands configuration for Robo task runner.
|
||||
*
|
||||
* @see http://robo.li/
|
||||
*/
|
||||
class RoboFile extends \Robo\Tasks {
|
||||
|
||||
protected $name = "butterfly";
|
||||
protected $issues = "https://github.com/rodolpholopes/glpi-butterfly/issues";
|
||||
protected $locale_keywords = "t_butterfly";
|
||||
|
||||
protected function getLocaleFiles() {
|
||||
$finder = new Finder();
|
||||
$finder
|
||||
->files()
|
||||
->name('*.po')
|
||||
->in('locales');
|
||||
|
||||
$files = [];
|
||||
foreach ($finder as $file) {
|
||||
$files[] = str_replace('\\', '/', $file->getRelativePathname());
|
||||
}
|
||||
|
||||
return $files;
|
||||
}
|
||||
|
||||
public function compile_locales() {
|
||||
$files = $this->getLocaleFiles();
|
||||
|
||||
foreach ($files as $file) {
|
||||
$lang = basename($file, ".po");
|
||||
|
||||
$this->taskExec('msgfmt')->args([
|
||||
"locales/$lang.po",
|
||||
"-o",
|
||||
"locales/$lang.mo",
|
||||
])->run();
|
||||
}
|
||||
}
|
||||
|
||||
public function update_locales() {
|
||||
$finder = new Finder();
|
||||
$finder
|
||||
->files()
|
||||
->name('*.php')
|
||||
->in(__DIR__)
|
||||
->exclude([
|
||||
'vendor'
|
||||
])
|
||||
->sortByName();
|
||||
|
||||
if (!$finder->hasResults()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$args = [];
|
||||
|
||||
foreach ($finder as $file) {
|
||||
$args[] = str_replace('\\', '/', $file->getRelativePathname());
|
||||
}
|
||||
|
||||
$args[] = '-D';
|
||||
$args[] = '.';
|
||||
$args[] = '-o';
|
||||
$args[] = "locales/{$this->name}.pot";
|
||||
$args[] = '-L';
|
||||
$args[] = 'PHP';
|
||||
$args[] = '--add-comments=TRANS';
|
||||
$args[] = '--from-code=UTF-8';
|
||||
$args[] = '--force-po';
|
||||
$args[] = "--keyword={$this->locale_keywords}";
|
||||
$args[] = "--package-name={$this->name}";
|
||||
|
||||
if ($this->issues) {
|
||||
$args[] = "--msgid-bugs-address={$this->issues}";
|
||||
}
|
||||
|
||||
try {
|
||||
$content = file_get_contents('setup.php');
|
||||
$name = 'PLUGIN_' . strtoupper($this->name) . '_VERSION';
|
||||
preg_match("/'$name',\s*'([\w\.]+)'/", $content, $matches);
|
||||
$args[] = '--package-version=' . $matches[1];
|
||||
} catch (\Exception $ex) {
|
||||
echo $ex->getMessage();
|
||||
}
|
||||
|
||||
putenv("LANG=C");
|
||||
|
||||
$this->taskExec('xgettext')->args($args)->run();
|
||||
|
||||
$this->taskReplaceInFile("locales/{$this->name}.pot")
|
||||
->from('CHARSET')
|
||||
->to('UTF-8')
|
||||
->run();
|
||||
|
||||
$this->taskExec('msginit')->args([
|
||||
'--no-translator',
|
||||
'-i',
|
||||
"locales/{$this->name}.pot",
|
||||
'-l',
|
||||
'en_GB.UTF8',
|
||||
'-o',
|
||||
'locales/en_GB.po',
|
||||
])->run();
|
||||
|
||||
$files = $this->getLocaleFiles();
|
||||
|
||||
foreach ($files as $file) {
|
||||
$lang = basename($file, ".po");
|
||||
|
||||
if ($lang === "en_GB") {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->taskExec('msgmerge')->args([
|
||||
"--update",
|
||||
"locales/$lang.po",
|
||||
"locales/{$this->name}.pot",
|
||||
"--lang=$lang",
|
||||
"--backup=off",
|
||||
])->run();
|
||||
}
|
||||
|
||||
$this->compile_locales();
|
||||
}
|
||||
|
||||
public function build() {
|
||||
$this->_remove(["$this->name.zip", "$this->name.tgz"]);
|
||||
|
||||
$this->compile_locales();
|
||||
$this->compile_themes();
|
||||
|
||||
$tmpPath = $this->_tmpDir();
|
||||
|
||||
$exclude = glob(__DIR__ . '/.*');
|
||||
$exclude[] = 'plugin.xml';
|
||||
$exclude[] = 'screenshots';
|
||||
$exclude[] = 'tools';
|
||||
$exclude[] = 'vendor';
|
||||
$exclude[] = "$this->name.zip";
|
||||
$exclude[] = "$this->name.tgz";
|
||||
|
||||
$this->taskCopyDir([__DIR__ => $tmpPath])
|
||||
->exclude($exclude)
|
||||
->run();
|
||||
|
||||
$composer_file = "$tmpPath/composer.json";
|
||||
if (file_exists($composer_file)) {
|
||||
$hasDep = false;
|
||||
try {
|
||||
$data = json_decode(file_get_contents($composer_file), true);
|
||||
$hasDep = isset($data['require']) && count($data['require']) > 0;
|
||||
} catch (\Exception $ex) {
|
||||
$hasDep = true;
|
||||
}
|
||||
|
||||
if ($hasDep) {
|
||||
$this->taskComposerInstall()
|
||||
->workingDir($tmpPath)
|
||||
->noDev()
|
||||
->run();
|
||||
}
|
||||
}
|
||||
|
||||
$this->_remove("$tmpPath/composer.lock");
|
||||
|
||||
// Pack
|
||||
$this->taskPack("$this->name.zip")
|
||||
->addDir($this->name, $tmpPath)
|
||||
->run();
|
||||
|
||||
$this->taskPack("$this->name.tgz")
|
||||
->addDir($this->name, $tmpPath)
|
||||
->run();
|
||||
}
|
||||
|
||||
public function compile_themes() {
|
||||
$finder = new Finder();
|
||||
$finder
|
||||
->files()
|
||||
->name('*.scss')
|
||||
->in('themes');
|
||||
|
||||
$files = [];
|
||||
foreach ($finder as $file) {
|
||||
$fullPath = $file->getPath();
|
||||
// var_dump($fullPath);die;
|
||||
$fullPath .= '/' . $file->getFilenameWithoutExtension();
|
||||
$fullPath .= '.css';
|
||||
$files[$file->getRealPath()] = $fullPath;
|
||||
}
|
||||
|
||||
$this->taskScss($files)->run();
|
||||
}
|
||||
}
|
||||
27
composer.json
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
{
|
||||
"name": "rodolpholopes/glpi-butterfly",
|
||||
"description": "Customize GLPI login branding with themes, logos, and CSS.",
|
||||
"license": "GPL v2+",
|
||||
"require-dev": {
|
||||
"consolidation/robo": "^2.2",
|
||||
"glpi-project/coding-standard": "^0.8",
|
||||
"pear/archive_tar": "^1.4",
|
||||
"phpcompatibility/php-compatibility": "^9.3",
|
||||
"scssphp/scssphp": "^1.10",
|
||||
"squizlabs/php_codesniffer": "^3.5"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "robo build",
|
||||
"lint": "phpcs",
|
||||
"lint:fix": "phpcbf"
|
||||
},
|
||||
"config": {
|
||||
"allow-plugins": {
|
||||
"dealerdirect/phpcodesniffer-composer-installer": true
|
||||
},
|
||||
"platform": {
|
||||
"php": "7.4.0"
|
||||
},
|
||||
"sort-packages": true
|
||||
}
|
||||
}
|
||||
11
css/login.base.css
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
#logo_login {
|
||||
background: none;
|
||||
margin: 0;
|
||||
padding: 38px 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#logo_login img {
|
||||
display: block;
|
||||
margin: 0 auto;
|
||||
}
|
||||
84
front/internal.css.php
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
<?php
|
||||
|
||||
$_GET["donotcheckversion"] = true;
|
||||
$dont_check_maintenance_mode = true;
|
||||
|
||||
define('GLPI_AJAX', true);
|
||||
include('../../../inc/includes.php');
|
||||
|
||||
// FIX: Prevent this script from being stored as the "Return URL" after login
|
||||
if (isset($_SESSION['glpi_currentpage']) && strpos($_SESSION['glpi_currentpage'], basename(__FILE__)) !== false) {
|
||||
unset($_SESSION['glpi_currentpage']);
|
||||
}
|
||||
|
||||
// Redirect if is a not cached URL
|
||||
if (!isset($_GET['_'])) {
|
||||
$timestamp = PluginButterflyToolbox::getTimestamp();
|
||||
|
||||
// Disable cache and redirect to cached URL
|
||||
header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0");
|
||||
header("Cache-Control: post-check=0, pre-check=0", false);
|
||||
header("Pragma: no-cache");
|
||||
|
||||
$file = basename(__FILE__);
|
||||
$url = "$file?_=$timestamp";
|
||||
if (isset($_GET['v'])) {
|
||||
$url .= '&v=' . $_GET['v'];
|
||||
}
|
||||
header("Location: " . $url);
|
||||
die;
|
||||
}
|
||||
|
||||
$name = 'internal';
|
||||
$css = "";
|
||||
|
||||
$picture = PluginButterflyConfig::getConfig("{$name}_picture", '');
|
||||
if ($picture) {
|
||||
$css .= ".page .glpi-logo {";
|
||||
$css .= " width: " . PluginButterflyConfig::getConfig("{$name}_picture_width", '100px') . " !important;";
|
||||
$css .= " height: " . PluginButterflyConfig::getConfig("{$name}_picture_height", '55px') . " !important;";
|
||||
$css .= " background-size: contain !important;";
|
||||
$css .= " background-repeat: no-repeat !important;";
|
||||
$css .= " background-position: center !important;";
|
||||
$css .= " background-image: url(\"" . PluginButterflyToolbox::getPictureUrl($picture) . "\") !important;";
|
||||
$css .= "}";
|
||||
}
|
||||
|
||||
$css_type = PluginButterflyConfig::getConfig("{$name}_css_type", 'scss');
|
||||
$css_custom = PluginButterflyConfig::getConfig("{$name}_css_custom", '');
|
||||
|
||||
$css_custom = html_entity_decode($css_custom);
|
||||
|
||||
if ($css_type === 'scss' && $css_custom && PluginButterflyScss::hasScssSuport()) {
|
||||
try {
|
||||
$variables = [];
|
||||
$variables['butterfly_timestamp'] = PluginButterflyToolbox::getTimestamp();
|
||||
|
||||
$css .= PluginButterflyScss::compileScss($css_custom, $variables);
|
||||
} catch (\Throwable $th) {
|
||||
// Log error safely - check if ErrorHandler class exists
|
||||
$errorHandlerClass = '\Glpi\Application\ErrorHandler';
|
||||
if (class_exists($errorHandlerClass)) {
|
||||
$errorHandlerClass::getInstance()->handleException($th);
|
||||
} else {
|
||||
// Fallback error logging
|
||||
error_log('Butterfly Plugin SCSS Error: ' . $th->getMessage());
|
||||
}
|
||||
}
|
||||
} else if ($css_type === 'css') {
|
||||
$css .= $css_custom;
|
||||
}
|
||||
|
||||
header('Content-Type: text/css');
|
||||
|
||||
$is_cacheable = !isset($_GET['debug']) && !isset($_GET['nocache']);
|
||||
if ($is_cacheable) {
|
||||
// Makes CSS cacheable by browsers and proxies
|
||||
$max_age = WEEK_TIMESTAMP;
|
||||
header_remove('Pragma');
|
||||
header('Cache-Control: public');
|
||||
header('Cache-Control: max-age=' . $max_age);
|
||||
header('Expires: ' . gmdate('D, d M Y H:i:s \G\M\T', time() + $max_age));
|
||||
}
|
||||
|
||||
echo $css;
|
||||
90
front/internal.js.php
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
<?php
|
||||
|
||||
$_GET["donotcheckversion"] = true;
|
||||
$dont_check_maintenance_mode = true;
|
||||
|
||||
define('GLPI_AJAX', true);
|
||||
include('../../../inc/includes.php');
|
||||
|
||||
// FIX: Prevent this script from being stored as the "Return URL" after login
|
||||
if (isset($_SESSION['glpi_currentpage']) && strpos($_SESSION['glpi_currentpage'], basename(__FILE__)) !== false) {
|
||||
unset($_SESSION['glpi_currentpage']);
|
||||
}
|
||||
|
||||
// Redirect if is a not cached URL
|
||||
if (!isset($_GET['_'])) {
|
||||
$timestamp = PluginButterflyToolbox::getTimestamp();
|
||||
|
||||
// Disable cache and redirect to cached URL
|
||||
header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0");
|
||||
header("Cache-Control: post-check=0, pre-check=0", false);
|
||||
header("Pragma: no-cache");
|
||||
|
||||
$file = basename(__FILE__);
|
||||
$url = "$file?_=$timestamp";
|
||||
if (isset($_GET['v'])) {
|
||||
$url .= '&v=' . $_GET['v'];
|
||||
}
|
||||
header("Location: " . $url);
|
||||
die;
|
||||
}
|
||||
|
||||
header('Content-Type: application/javascript');
|
||||
|
||||
$is_cacheable = !isset($_GET['debug']) && !isset($_GET['nocache']);
|
||||
if ($is_cacheable) {
|
||||
// Makes CSS cacheable by browsers and proxies
|
||||
$max_age = WEEK_TIMESTAMP;
|
||||
header_remove('Pragma');
|
||||
header('Cache-Control: public');
|
||||
header('Cache-Control: max-age=' . $max_age);
|
||||
header('Expires: ' . gmdate('D, d M Y H:i:s \G\M\T', time() + $max_age));
|
||||
}
|
||||
|
||||
if (false) {
|
||||
?>
|
||||
<script>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
<?php echo "$(function () {"; ?>
|
||||
$('link[href*="butterfly/front/internal.css.php"]').appendTo($('head'))
|
||||
<?php
|
||||
$favicon = PluginButterflyConfig::getConfig('favicon_picture');
|
||||
if ($favicon):
|
||||
$faviconUrl = PluginButterflyToolbox::getPictureUrl($favicon);
|
||||
?>
|
||||
var $icon = $('link[rel*=icon]');
|
||||
$icon.attr('type', null);
|
||||
$icon.attr('href', <?php echo json_encode($faviconUrl) ?>);
|
||||
<?php
|
||||
endif;
|
||||
$pageTitle = PluginButterflyConfig::getConfig('page_title');
|
||||
if ($pageTitle):
|
||||
?>
|
||||
var $title = $('title');
|
||||
var newTitle = $title.text().replace('GLPI', <?php echo json_encode($pageTitle) ?>);
|
||||
$title.text(newTitle);
|
||||
<?php
|
||||
endif;
|
||||
|
||||
$footerDisplay = PluginButterflyConfig::getConfig('page_footer_display', 'original');
|
||||
$footerText = PluginButterflyConfig::getConfig('page_footer_text', '');
|
||||
if ($footerDisplay === 'hide'):
|
||||
?>
|
||||
$('a[id^=show_about_modal_]').hide();
|
||||
<?php
|
||||
endif;
|
||||
if ($footerDisplay === 'custom'):
|
||||
$footerText = \Glpi\RichText\RichText::getEnhancedHtml($footerText);
|
||||
?>
|
||||
$('div[id^=about_modal_] .copyright').parent().parent().html(<?php echo json_encode($footerText) ?>);
|
||||
<?php
|
||||
endif;
|
||||
|
||||
echo "});";
|
||||
if (false) {
|
||||
?>
|
||||
</script>
|
||||
<?php
|
||||
}
|
||||
8
front/login.css.php
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
<?php
|
||||
// Deprecated endpoint kept for backward compatibility.
|
||||
// All login styles are now injected inline from the display_login hook.
|
||||
|
||||
header('Content-Type: text/css');
|
||||
header('Cache-Control: public, max-age=60');
|
||||
|
||||
echo "/* Butterfly plugin: login.css.php is deprecated. */\n";
|
||||
66
front/picture.send.php
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
<?php
|
||||
/**
|
||||
* Lightweight public endpoint to serve plugin pictures.
|
||||
* Works without authentication and is compatible with GLPI 11 routing.
|
||||
*/
|
||||
|
||||
$_GET['donotcheckversion'] = true;
|
||||
$dont_check_maintenance_mode = true;
|
||||
|
||||
require_once '../../../inc/includes.php';
|
||||
|
||||
$rawPath = $_GET['path'] ?? '';
|
||||
if ($rawPath === '') {
|
||||
http_response_code(400);
|
||||
die('Missing path parameter');
|
||||
}
|
||||
|
||||
$theme = $_GET['theme'] ?? '';
|
||||
|
||||
// Basic sanitization while keeping subdirectories (needed for storage layout)
|
||||
$path = preg_replace('/[^a-zA-Z0-9._\\-\\/]/', '', $rawPath);
|
||||
$path = str_replace(['../', '..\\'], '', $path);
|
||||
$theme = preg_replace('/[^a-zA-Z0-9_\\-]/', '', $theme);
|
||||
|
||||
if ($path === '') {
|
||||
http_response_code(400);
|
||||
die('Invalid path');
|
||||
}
|
||||
|
||||
if ($theme !== '') {
|
||||
$baseDir = PluginButterflyTheme::getThemeFolder() . '/' . $theme;
|
||||
} else {
|
||||
$baseDir = PluginButterflyToolbox::getStorageBasePath();
|
||||
}
|
||||
|
||||
$fullPath = $baseDir . '/' . ltrim($path, '/');
|
||||
$realBase = is_dir($baseDir) ? realpath($baseDir) : false;
|
||||
$realPath = realpath($fullPath);
|
||||
|
||||
if ($realBase === false || $realPath === false) {
|
||||
http_response_code(404);
|
||||
die('File not found');
|
||||
}
|
||||
|
||||
$realBase = rtrim($realBase, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
|
||||
if (strpos($realPath, $realBase) !== 0) {
|
||||
http_response_code(403);
|
||||
die('Access denied');
|
||||
}
|
||||
|
||||
if (!is_file($realPath) || !is_readable($realPath)) {
|
||||
http_response_code(404);
|
||||
die('File not found');
|
||||
}
|
||||
|
||||
$mimeType = mime_content_type($realPath) ?: 'application/octet-stream';
|
||||
$fileSize = filesize($realPath);
|
||||
$fileName = basename($realPath);
|
||||
|
||||
header('Content-Type: ' . $mimeType);
|
||||
header('Content-Length: ' . $fileSize);
|
||||
header('Content-Disposition: inline; filename="' . $fileName . '"');
|
||||
header('Cache-Control: public, max-age=3600');
|
||||
header('Last-Modified: ' . gmdate('D, d M Y H:i:s', filemtime($realPath)) . ' GMT');
|
||||
|
||||
readfile($realPath);
|
||||
138
hook.php
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
<?php
|
||||
|
||||
function plugin_butterfly_display_login() {
|
||||
|
||||
$themeInfo = null;
|
||||
if (isset($_GET['theme'])) {
|
||||
$themeInfo = PluginButterflyTheme::getThemeInfo($_GET['theme']);
|
||||
}
|
||||
if (!$themeInfo) {
|
||||
$theme = PluginButterflyConfig::getConfig("login_theme", '');
|
||||
$themeInfo = PluginButterflyTheme::getThemeInfo($theme);
|
||||
}
|
||||
|
||||
$loginPicture = PluginButterflyConfig::getConfig('login_picture');
|
||||
|
||||
if (!$loginPicture && $themeInfo && !empty($themeInfo['login-logo'])) {
|
||||
$loginPicture = $themeInfo['login-logo'] . '&theme=' . $themeInfo['id'];
|
||||
}
|
||||
|
||||
if ($loginPicture && version_compare(GLPI_VERSION, '9.5.0', '<')) {
|
||||
echo Html::css("/plugins/butterfly/css/login.base.css", [
|
||||
'version' => PLUGIN_BUTTERFLY_VERSION,
|
||||
]);
|
||||
}
|
||||
|
||||
$loginCss = PluginButterflyScss::getLoginCSS($_GET['theme'] ?? null);
|
||||
if (!empty($loginCss)) {
|
||||
echo "<style id='plugin-butterfly-login-css'>\n" . $loginCss . "\n</style>";
|
||||
}
|
||||
|
||||
?>
|
||||
<?php if ($loginPicture) : ?>
|
||||
<?php
|
||||
$pictureUrl = PluginButterflyToolbox::getPictureUrl($loginPicture);
|
||||
$maxWidth = Html::cleanInputText(PluginButterflyConfig::getConfig('login_picture_max_width', '145px'));
|
||||
$maxHeight = Html::cleanInputText(PluginButterflyConfig::getConfig('login_picture_max_height', '80px'));
|
||||
?>
|
||||
<style>
|
||||
.page-anonymous .glpi-logo {
|
||||
--logo: url(<?php echo $pictureUrl ?>);
|
||||
content: url(<?php echo $pictureUrl ?>);
|
||||
width: auto;
|
||||
height: auto;
|
||||
max-width: <?php echo $maxWidth ?>;
|
||||
max-height: <?php echo $maxHeight ?>;
|
||||
}
|
||||
</style>
|
||||
<?php endif; ?>
|
||||
<script type="text/javascript">
|
||||
$(function() {
|
||||
var $loginInputs = $('#login_name, #inputUsername');
|
||||
if ($loginInputs.length) {
|
||||
$loginInputs.attr('placeholder', <?php echo json_encode(__('Login')) ?>);
|
||||
}
|
||||
|
||||
var $passwordInputs = $('input[type=password], input[name=password]');
|
||||
if ($passwordInputs.length) {
|
||||
$passwordInputs.attr('placeholder', <?php echo json_encode(__('Password')) ?>);
|
||||
$passwordInputs.each(function() {
|
||||
var $input = $(this);
|
||||
var $description = $input.siblings('.form-label-description').first();
|
||||
if ($description.length) {
|
||||
$input.after($description);
|
||||
}
|
||||
});
|
||||
}
|
||||
<?php
|
||||
$favicon = PluginButterflyConfig::getConfig('favicon_picture');
|
||||
if ($favicon) :
|
||||
$faviconUrl = PluginButterflyToolbox::getPictureUrl($favicon);
|
||||
?>
|
||||
var $icon = $('link[rel*=icon]');
|
||||
$icon.attr('type', null);
|
||||
$icon.attr('href', <?php echo json_encode($faviconUrl) ?>);
|
||||
<?php
|
||||
endif;
|
||||
$pageTitle = PluginButterflyConfig::getConfig('page_title');
|
||||
if ($pageTitle) :
|
||||
?>
|
||||
var $title = $('title');
|
||||
var newTitle = $title.text().replace('GLPI', <?php echo json_encode($pageTitle) ?>);
|
||||
$title.text(newTitle);
|
||||
<?php
|
||||
endif;
|
||||
$footerDisplay = PluginButterflyConfig::getConfig('page_footer_display', 'original');
|
||||
$footerText = PluginButterflyConfig::getConfig('page_footer_text', '');
|
||||
if ($footerDisplay === 'hide') :
|
||||
?>
|
||||
$('#footer-login, .login-footer').hide();
|
||||
<?php
|
||||
endif;
|
||||
if ($footerDisplay === 'custom') :
|
||||
$footerText = \Glpi\RichText\RichText::getEnhancedHtml($footerText);
|
||||
?>
|
||||
var $footerTarget = $('#footer-login, .login-footer').first();
|
||||
if ($footerTarget.length) {
|
||||
$footerTarget.html(<?php echo json_encode($footerText) ?>);
|
||||
} else {
|
||||
$('a.copyright').parent().html(<?php echo json_encode($footerText) ?>);
|
||||
}
|
||||
<?php
|
||||
endif;
|
||||
if ($loginPicture) :
|
||||
?>
|
||||
var pictureUrl = <?php echo json_encode($pictureUrl); ?>;
|
||||
var maxWidth = <?php echo json_encode($maxWidth); ?>;
|
||||
var maxHeight = <?php echo json_encode($maxHeight); ?>;
|
||||
|
||||
$('.page-anonymous .glpi-logo').css({
|
||||
'background-image': 'url(' + pictureUrl + ')',
|
||||
'background-position': 'center',
|
||||
'background-repeat': 'no-repeat',
|
||||
'background-size': 'contain'
|
||||
});
|
||||
|
||||
$('.login-header img, .glpi-login__logo img, .login-logo img')
|
||||
.attr('src', pictureUrl)
|
||||
.css({
|
||||
'width': 'auto',
|
||||
'height': 'auto',
|
||||
'max-width': maxWidth,
|
||||
'max-height': maxHeight
|
||||
});
|
||||
<?php
|
||||
endif;
|
||||
?>
|
||||
});
|
||||
</script>
|
||||
<?php
|
||||
}
|
||||
|
||||
function plugin_butterfly_install() {
|
||||
return true;
|
||||
}
|
||||
|
||||
function plugin_butterfly_uninstall() {
|
||||
return true;
|
||||
}
|
||||
623
inc/config.class.php
Normal file
|
|
@ -0,0 +1,623 @@
|
|||
<?php
|
||||
|
||||
class PluginButterflyConfig extends CommonDBTM {
|
||||
|
||||
private static $_cache = null;
|
||||
private static $_i = 1;
|
||||
|
||||
static function getConfig($name, $defaultValue = null) {
|
||||
|
||||
if (self::$_cache === null) {
|
||||
$config = new self();
|
||||
$config->getEmpty();
|
||||
$config->fields = array_merge($config->fields, Config::getConfigurationValues('butterfly'));
|
||||
|
||||
self::$_cache = $config->fields;
|
||||
}
|
||||
|
||||
if (isset(self::$_cache[$name]) && self::$_cache[$name] !== '') {
|
||||
return self::$_cache[$name];
|
||||
}
|
||||
return $defaultValue;
|
||||
}
|
||||
|
||||
function getTabNameForItem(CommonGLPI $item, $withtemplate = 0) {
|
||||
switch (get_class($item)) {
|
||||
case 'Config':
|
||||
return [1 => t_butterfly('Butterfly')];
|
||||
default:
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
static function displayTabContentForItem(CommonGLPI $item, $tabnum = 1, $withtemplate = 0) {
|
||||
switch (get_class($item)) {
|
||||
case 'Config':
|
||||
$config = new self();
|
||||
$config->showFormDisplay();
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
protected static function checkPicture($name, $input, $old, $width = 0, $height = 0, $max_size = 500) {
|
||||
|
||||
$blank = "_blank_$name";
|
||||
$new = "_$name";
|
||||
|
||||
if (isset($input[$blank]) && $input[$blank]) {
|
||||
unset($input[$blank]);
|
||||
if (isset($old[$name]) && $old[$name]) {
|
||||
PluginButterflyToolbox::deletePicture($old[$name]);
|
||||
}
|
||||
$input[$name] = '';
|
||||
} else if (isset($input[$new]) && !empty($input[$new]) && !empty($input[$new][0])) {
|
||||
$picName = array_shift($input[$new]);
|
||||
// Use GLPI temp directory if available, fallback to system temp
|
||||
$glpiTmpConstant = 'GLPI_TMP_DIR';
|
||||
$tmpDir = (defined($glpiTmpConstant) && constant($glpiTmpConstant)) ? constant($glpiTmpConstant) : sys_get_temp_dir();
|
||||
$picPath = $tmpDir . '/' . $picName;
|
||||
$picResizedPath = $tmpDir . '/resized_' . $picName;
|
||||
|
||||
if ($width || $height) {
|
||||
if (PluginButterflyToolbox::resizePicture($picPath, $picResizedPath, $width, $height, 0, 0, 0, 0, $max_size)) {
|
||||
$picPath = $picResizedPath;
|
||||
}
|
||||
}
|
||||
|
||||
if ($dest = PluginButterflyToolbox::savePicture($picPath)) {
|
||||
$input[$name] = $dest;
|
||||
} else {
|
||||
Session::addMessageAfterRedirect(__('Unable to save picture file.'), true, ERROR);
|
||||
}
|
||||
|
||||
if (isset($old[$name]) && $old[$name]) {
|
||||
PluginButterflyToolbox::deletePicture($old[$name]);
|
||||
}
|
||||
}
|
||||
|
||||
unset($input["_$name"]);
|
||||
unset($input["_prefix_$name"]);
|
||||
unset($input["_prefix_new_$name"]);
|
||||
unset($input["_tag_$name"]);
|
||||
unset($input["_tag_new_$name"]);
|
||||
unset($input["_uploader_$name"]);
|
||||
unset($input["new_$name"]);
|
||||
unset($input[$blank]);
|
||||
unset($input[$new]);
|
||||
|
||||
return $input;
|
||||
}
|
||||
|
||||
protected static function checkCSS($name, $label, $input, $old) {
|
||||
$fullName = "{$name}_css_custom";
|
||||
$type = "{$name}_css_type";
|
||||
|
||||
if (!isset($input[$type])) {
|
||||
$input[$type] = 'css';
|
||||
}
|
||||
|
||||
if (isset($input[$fullName])) {
|
||||
$input[$fullName] = html_entity_decode($input[$fullName]);
|
||||
$input[$fullName] = preg_replace('/\\\\r\\\\n/', "\n", $input[$fullName]);
|
||||
$input[$fullName] = preg_replace('/\\\\n/', "\n", $input[$fullName]);
|
||||
|
||||
if ($input[$type] === 'scss' && PluginButterflyScss::hasScssSuport()) {
|
||||
try {
|
||||
$variables = [];
|
||||
$variables['butterfly_timestamp'] = PluginButterflyToolbox::getTimestamp();
|
||||
|
||||
PluginButterflyScss::compileScss($input[$fullName], $variables);
|
||||
} catch (\Throwable $th) {
|
||||
$message = sprintf(t_butterfly('Unable to compile the SCSS (%1$s). Message: '), $label);
|
||||
Session::addMessageAfterRedirect($message . $th->getMessage(), true, ERROR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $input;
|
||||
}
|
||||
|
||||
static function configUpdate($input) {
|
||||
$old = Config::getConfigurationValues('butterfly');
|
||||
|
||||
unset($input['_no_history']);
|
||||
|
||||
$input = self::checkPicture('favicon_picture', $input, $old, 192, 192, 192);
|
||||
$input = self::checkPicture('login_picture', $input, $old, 145, 80, 300);
|
||||
$input = self::checkPicture('internal_picture', $input, $old, 100, 55, 300);
|
||||
$input = self::checkPicture('login_background_picture', $input, $old);
|
||||
|
||||
$input = self::checkCSS('login', t_butterfly('Login Page'), $input, $old);
|
||||
$input = self::checkCSS('internal', t_butterfly('Internal Page'), $input, $old);
|
||||
|
||||
foreach ($input as $key => $value) {
|
||||
if ($value && strpos($key, '_blank_') === 0) {
|
||||
$name = substr($key, 7);
|
||||
$input[$name] = '';
|
||||
}
|
||||
}
|
||||
|
||||
$input['timestamp'] = time();
|
||||
|
||||
PluginButterflyToolbox::setTimestamp($input['timestamp']);
|
||||
|
||||
Session::addMessageAfterRedirect(__('Item successfully updated'), false, INFO);
|
||||
|
||||
return $input;
|
||||
}
|
||||
|
||||
function getEmpty() {
|
||||
|
||||
$defaultCss = 'css';
|
||||
|
||||
if (PluginButterflyScss::hasScssSuport()) {
|
||||
$defaultCss = 'scss';
|
||||
}
|
||||
|
||||
$this->fields = [
|
||||
'favicon_picture' => '',
|
||||
'page_title' => '',
|
||||
'page_footer_display' => 'original',
|
||||
'page_footer_text' => '',
|
||||
'login_picture' => '',
|
||||
'login_picture_max_width' => '240px',
|
||||
'login_picture_max_height' => '130px',
|
||||
'login_css_custom' => '',
|
||||
'login_css_type' => $defaultCss,
|
||||
'login_theme' => '',
|
||||
'internal_picture' => '',
|
||||
'internal_picture_width' => '100px',
|
||||
'internal_picture_height' => '55px',
|
||||
'internal_css_custom' => '',
|
||||
'internal_css_type' => $defaultCss,
|
||||
];
|
||||
}
|
||||
|
||||
protected function buildPictureLine($name, $recommendedSize = null) {
|
||||
if (!empty($this->fields[$name])) {
|
||||
echo '<td>';
|
||||
echo Html::image(PluginButterflyToolbox::getPictureUrl($this->fields[$name]), [
|
||||
'style' => '
|
||||
max-width: 100px;
|
||||
max-height: 100px;
|
||||
background-image: linear-gradient(45deg, #b0b0b0 25%, transparent 25%), linear-gradient(-45deg, #b0b0b0 25%, transparent 25%), linear-gradient(45deg, transparent 75%, #b0b0b0 75%), linear-gradient(-45deg, transparent 75%, #b0b0b0 75%);
|
||||
background-size: 10px 10px;
|
||||
background-position: 0 0, 0 5px, 5px -5px, -5px 0px;',
|
||||
'class' => 'picture_square'
|
||||
]);
|
||||
echo " ";
|
||||
echo Html::getCheckbox([
|
||||
'title' => t_butterfly('Reset'),
|
||||
'name' => "_blank_$name"
|
||||
]);
|
||||
echo " " . t_butterfly('Reset');
|
||||
echo '</td>';
|
||||
echo '<td colspan="2">';
|
||||
} else {
|
||||
echo '<td colspan="3">';
|
||||
}
|
||||
Html::file([
|
||||
'name' => $name,
|
||||
'onlyimages' => true,
|
||||
'min_file_size' => 1,
|
||||
]);
|
||||
if ($recommendedSize) {
|
||||
echo '<small>';
|
||||
echo sprintf(t_butterfly('Recommended size: %1$s'), $recommendedSize);
|
||||
echo '</small>';
|
||||
}
|
||||
echo '</td>';
|
||||
}
|
||||
|
||||
protected function buildCssLine($name, $label) {
|
||||
$fullName = "{$name}_css_custom";
|
||||
$type = "{$name}_css_type";
|
||||
|
||||
echo "<tr><th colspan='4'>" . sprintf(t_butterfly('Custom CSS for %1$s'), $label) . "</th></tr>";
|
||||
echo "<tr class='tab_bg_1'>";
|
||||
echo "<td>";
|
||||
echo t_butterfly('CSS Type') . ':';
|
||||
echo "</td>";
|
||||
echo "<td colspan='3'>";
|
||||
|
||||
$css_type = [
|
||||
'off' => __('Disabled'),
|
||||
'css' => 'CSS',
|
||||
];
|
||||
|
||||
if (PluginButterflyScss::hasScssSuport()) {
|
||||
$css_type['scss'] = 'SCSS';
|
||||
}
|
||||
Dropdown::showFromArray($type, $css_type, ['value' => $this->fields[$type]]);
|
||||
echo "</td>";
|
||||
echo "</tr>";
|
||||
echo "<tr class='tab_bg_1'>";
|
||||
echo "<td colspan='4' style='max-width: 1000px'>";
|
||||
$rand = mt_rand();
|
||||
|
||||
echo sprintf(
|
||||
'<textarea %1$s>',
|
||||
Html::parseAttributes([
|
||||
'id' => $fullName . '_' . $rand,
|
||||
'name' => $fullName,
|
||||
'class' => 'butterfly-codemirror',
|
||||
])
|
||||
);
|
||||
echo rtrim($this->fields[$fullName]);
|
||||
echo str_repeat("\n", 10);
|
||||
echo '</textarea>';
|
||||
|
||||
echo Html::scriptBlock('
|
||||
$(function() {
|
||||
var textarea = document.getElementById("' . $fullName . '_' . $rand . '");
|
||||
var editorCode = CodeMirror.fromTextArea(textarea, {
|
||||
mode: "text/x-scss",
|
||||
lineNumbers: true,
|
||||
viewportMargin: Infinity,
|
||||
extraKeys: {
|
||||
"Ctrl-Space": "autocomplete"
|
||||
},
|
||||
foldGutter: true,
|
||||
gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter"]
|
||||
});
|
||||
$("#' . $fullName . '_' . $rand . '").data("CodeMirrorInstance", editorCode);
|
||||
|
||||
// Fix bad display of gutter (see https://github.com/codemirror/CodeMirror/issues/3098 )
|
||||
setTimeout(function () {editorCode.refresh();}, ' . (500 + self::$_i++ * 100) . ');
|
||||
});
|
||||
');
|
||||
echo "</td>";
|
||||
echo "</tr>\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Print the config form for display
|
||||
*
|
||||
* @return Nothing (display)
|
||||
* */
|
||||
function showFormDisplay() {
|
||||
global $CFG_GLPI;
|
||||
if (!Config::canView()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$this->getEmpty();
|
||||
|
||||
$this->fields = array_merge($this->fields, Config::getConfigurationValues('butterfly'));
|
||||
|
||||
$canedit = Session::haveRight(Config::$rightname, UPDATE);
|
||||
if ($canedit) {
|
||||
echo "<form name='form' action=\"" . Toolbox::getItemTypeFormURL('Config') . "\" method='post'>";
|
||||
}
|
||||
echo Html::hidden('config_context', ['value' => 'butterfly']);
|
||||
echo Html::hidden('config_class', ['value' => __CLASS__]);
|
||||
|
||||
echo "<div class='center' id='tabsbody'>";
|
||||
|
||||
$rand = mt_rand();
|
||||
echo "<style>
|
||||
#tabs$rand .ui-tabs-nav {
|
||||
width: auto;
|
||||
}
|
||||
#tabs$rand .ui-tabs-nav li {
|
||||
clear: none;
|
||||
width: auto;
|
||||
margin-right: 5px;
|
||||
}
|
||||
#tabs$rand .ui-tabs-nav li a {
|
||||
width: auto;
|
||||
}
|
||||
#tabs$rand .ui-tabs-panel {
|
||||
margin-left: 0;
|
||||
}
|
||||
.CodeMirror {
|
||||
border: 1px solid #eee;
|
||||
height: auto;
|
||||
}
|
||||
.butterfly-themeselect-container .select2-selection__rendered,
|
||||
.butterfly-themeselect-dropdown .select2-results__option {
|
||||
height: 80px !important;
|
||||
line-height: 80px !important;
|
||||
}
|
||||
.butterfly-themeselect-container .select2-selection__rendered img,
|
||||
.butterfly-themeselect-dropdown .select2-results__option img {
|
||||
width: 170px;
|
||||
height: 80px;
|
||||
object-fit:cover;
|
||||
float: right;
|
||||
}
|
||||
.butterfly-themeselect-container.select2-selection--single {
|
||||
min-width: 350px;
|
||||
max-width: 350px;
|
||||
height: 80px !important;
|
||||
}
|
||||
.butterfly-themeselect-container.select2-selection--single:before {
|
||||
line-height: 80px !important;
|
||||
}
|
||||
.butterfly-themeselect-container .select2-selection__arrow {
|
||||
height: 79px !important;
|
||||
}
|
||||
</style>";
|
||||
|
||||
// echo "<div id='tabs$rand' class='center tab_cadre_fixe horizontal butterfly ui-tabs ui-corner-all ui-widget ui-widget-content'>";
|
||||
// echo "<ul role='tablist' class='ui-tabs-nav ui-corner-all ui-helper-reset ui-helper-clearfix ui-widget-header'>";
|
||||
// echo "<li><a href='#tab_butterfly_favicon'>" . t_butterfly('Favicon and Title') . "</a></li>";
|
||||
// echo "<li><a href='#tab_butterfly_login'>" . t_butterfly('Login Page') . "</a></li>";
|
||||
// echo "<li><a href='#tab_butterfly_internal'>" . t_butterfly('Internal Page') . "</a></li>";
|
||||
// echo "</ul>";
|
||||
|
||||
// General
|
||||
echo "<div id='tab_butterfly_favicon'>";
|
||||
echo "<table class='tab_cadre_fixe'>";
|
||||
|
||||
echo "<tr class='noHover'><th colspan='4' >" . t_butterfly('Favicon and Title') . "</th></tr>";
|
||||
echo "<tr class='tab_bg_1'>";
|
||||
echo "<td>" . __('Picture') . "</td>";
|
||||
$this->buildPictureLine('favicon_picture', '192px x 192px');
|
||||
echo "</tr>\n";
|
||||
|
||||
echo "<tr class='tab_bg_1'>";
|
||||
echo "<td>" . __('Title') . "</td>";
|
||||
echo "<td colspan='3'>";
|
||||
echo sprintf(
|
||||
'<input type="text" %1$s />',
|
||||
Html::parseAttributes([
|
||||
'name' => 'page_title',
|
||||
'value' => $this->fields['page_title'],
|
||||
'style' => 'width: 98%',
|
||||
])
|
||||
);
|
||||
echo "</td>";
|
||||
echo "</tr>\n";
|
||||
|
||||
echo "<tr class='tab_bg_1'>";
|
||||
echo "<td>" . t_butterfly('Footer') . "</td>";
|
||||
echo "<td colspan='3'>";
|
||||
Dropdown::showFromArray('page_footer_display', [
|
||||
'original' => __('Original'),
|
||||
'hide' => t_butterfly('Hide'),
|
||||
'custom' => t_butterfly('Custom'),
|
||||
], ['value' => $this->fields['page_footer_display']]);
|
||||
echo "</td>";
|
||||
echo "</tr>\n";
|
||||
|
||||
echo "<tr class='tab_bg_1'>";
|
||||
echo "<td>" . t_butterfly('Footer text') . "</td>";
|
||||
echo "<td colspan='3'>";
|
||||
Html::textarea([
|
||||
'rand' => $rand,
|
||||
'editor_id' => 'text' . $rand,
|
||||
'name' => 'page_footer_text',
|
||||
'value' => $this->fields['page_footer_text'],
|
||||
'style' => 'width: 98%',
|
||||
'rows' => 1,
|
||||
'enable_richtext' => true,
|
||||
'enable_fileupload' => false,
|
||||
'enable_images' => false,
|
||||
]);
|
||||
?>
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function() {
|
||||
var editor = tinyMCE.get(<?php echo json_encode('text' . $rand) ?>);
|
||||
editor.settings.force_br_newlines = true;
|
||||
editor.settings.force_p_newlines = false;
|
||||
editor.settings.forced_root_block = '';
|
||||
});
|
||||
</script>
|
||||
<?php
|
||||
echo "</td>";
|
||||
echo "</tr>\n";
|
||||
|
||||
echo "</table>";
|
||||
echo "</div>";
|
||||
|
||||
// Login
|
||||
echo "<div id='tab_butterfly_login'>";
|
||||
echo "<table class='tab_cadre_fixe'>";
|
||||
|
||||
echo "<tr class='noHover'><th colspan='4' >" . t_butterfly('Login Page') . "</th></tr>";
|
||||
echo "<tr class='tab_bg_1'>";
|
||||
echo "<td>" . t_butterfly('Theme') . "</td>";
|
||||
echo "<td colspan='2'>";
|
||||
echo sprintf(
|
||||
'<select %1$s>',
|
||||
Html::parseAttributes([
|
||||
'name' => 'login_theme',
|
||||
])
|
||||
);
|
||||
|
||||
echo '<option value="">GLPI (' . __('Original') . ')</option>';
|
||||
foreach (PluginButterflyTheme::getLoginThemes() as $id => $theme) {
|
||||
$attrs = [
|
||||
'name' => 'login_theme',
|
||||
'value' => $id,
|
||||
];
|
||||
|
||||
if (isset($theme['login-preview']) && $theme['login-preview']) {
|
||||
$attrs['data-preview'] = $theme['login-preview'];
|
||||
}
|
||||
|
||||
if ($id === $this->fields['login_theme']) {
|
||||
$attrs['selected'] = 'selected';
|
||||
}
|
||||
|
||||
echo sprintf(
|
||||
'<option %1$s>%2$s</option>',
|
||||
Html::parseAttributes($attrs),
|
||||
htmlentities($theme['name'])
|
||||
);
|
||||
}
|
||||
echo '</select>';
|
||||
?>
|
||||
<script type="text/javascript">
|
||||
function butterflyFormatThemes(theme) {
|
||||
var data = theme && theme.element && theme.element.dataset || {};
|
||||
if (!theme.id || !data.preview) {
|
||||
return $('<span></span>', {
|
||||
html: '<img src="../plugins/butterfly/pics/login.preview.png"/> ' + theme.text
|
||||
});
|
||||
}
|
||||
|
||||
return $('<span></span>', {
|
||||
html: '<img src="../plugins/butterfly/front/picture.send.php?theme=' + theme.id + '&path=' + data.preview + '"/> ' + theme.text
|
||||
});
|
||||
}
|
||||
$("select[name=login_theme]").select2({
|
||||
templateResult: butterflyFormatThemes,
|
||||
templateSelection: butterflyFormatThemes,
|
||||
width: '100%',
|
||||
containerCssClass: 'butterfly-themeselect-container',
|
||||
dropdownCssClass: 'butterfly-themeselect-dropdown',
|
||||
escapeMarkup: function(m) {
|
||||
return m;
|
||||
}
|
||||
});
|
||||
</script>
|
||||
<?php
|
||||
echo "</td>";
|
||||
echo "<td>";
|
||||
echo '<a id="butterfly-preview" href="#">' . __('Preview') . '</a>';
|
||||
?>
|
||||
<script type="text/javascript">
|
||||
$('#butterfly-preview').on('click', function() {
|
||||
var url = <?php echo json_encode($CFG_GLPI['root_doc'] . "/index.php") ?>;
|
||||
url += '?noAUTO=1';
|
||||
var theme = $("select[name=login_theme]").val() || 'original';
|
||||
url += '&theme=' + theme;
|
||||
window.open(url, 'butterfly_preview', 'titlebar=0&status=0');
|
||||
});
|
||||
</script>
|
||||
<?php
|
||||
echo "</td>";
|
||||
echo "</tr>\n";
|
||||
|
||||
$themeInfo = PluginButterflyTheme::getThemeInfo($this->fields['login_theme']);
|
||||
if ($themeInfo && isset($themeInfo['variables'])) {
|
||||
foreach ($themeInfo['variables'] as $k => $v) {
|
||||
$themeId = $themeInfo['id'];
|
||||
$fieldName = "login_theme-$themeId-$k";
|
||||
$fieldValue = $v['default'];
|
||||
if (isset($this->fields[$fieldName]) && $this->fields[$fieldName]) {
|
||||
$fieldValue = $this->fields[$fieldName];
|
||||
}
|
||||
echo "<tr class='tab_bg_1'>";
|
||||
echo "<td>" . t_butterfly($v['name']) . "</td>";
|
||||
echo "<td>";
|
||||
Html::showColorField($fieldName, [
|
||||
'value' => $fieldValue
|
||||
]);
|
||||
echo " ";
|
||||
echo Html::getCheckbox([
|
||||
'title' => t_butterfly('Reset'),
|
||||
'name' => "_blank_$fieldName"
|
||||
]);
|
||||
echo " " . t_butterfly('Reset');
|
||||
echo "</td>";
|
||||
echo "<td></td>";
|
||||
echo "<td></td>";
|
||||
echo "</tr>\n";
|
||||
}
|
||||
}
|
||||
|
||||
echo "<tr class='tab_bg_1'>";
|
||||
echo "<td>" . __('Picture') . "</td>";
|
||||
$this->buildPictureLine('login_picture', '145px x 80px');
|
||||
echo "</tr>\n";
|
||||
|
||||
echo "<tr class='tab_bg_1'>";
|
||||
echo "<td>" . __('Width') . "</td>";
|
||||
echo "<td>";
|
||||
echo sprintf(
|
||||
'<input type="text" %1$s />',
|
||||
Html::parseAttributes([
|
||||
'name' => 'login_picture_max_width',
|
||||
'value' => $this->fields['login_picture_max_width'],
|
||||
])
|
||||
);
|
||||
echo "</td>";
|
||||
echo "<td>" . __('Height') . "</td>";
|
||||
echo "<td>";
|
||||
echo sprintf(
|
||||
'<input type="text" %1$s />',
|
||||
Html::parseAttributes([
|
||||
'name' => 'login_picture_max_height',
|
||||
'value' => $this->fields['login_picture_max_height'],
|
||||
])
|
||||
);
|
||||
echo "</td>";
|
||||
echo "</tr>\n";
|
||||
|
||||
echo "<tr class='tab_bg_1'>";
|
||||
echo "<td>" . t_butterfly('Background picture') . "</td>";
|
||||
$this->buildPictureLine('login_background_picture', '1920px x 1080px');
|
||||
echo "</tr>\n";
|
||||
|
||||
// Custom CSS Login
|
||||
$this->buildCssLine('login', t_butterfly('Login Page'));
|
||||
echo "</table>";
|
||||
echo "</div>";
|
||||
|
||||
// Internal Page
|
||||
echo "<div id='tab_butterfly_internal'>";
|
||||
echo "<table class='tab_cadre_fixe'>";
|
||||
|
||||
echo "<tr class='noHover'><th colspan='4' >" . t_butterfly('Internal Page') . "</th></tr>";
|
||||
echo "<tr class='tab_bg_1'>";
|
||||
echo "<td>" . __('Picture') . "</td>";
|
||||
$this->buildPictureLine('internal_picture', '100px x 55px');
|
||||
echo "</tr>\n";
|
||||
|
||||
echo "<tr class='tab_bg_1'>";
|
||||
echo "<td>" . __('Width') . "</td>";
|
||||
echo "<td>";
|
||||
echo sprintf(
|
||||
'<input type="text" %1$s />',
|
||||
Html::parseAttributes([
|
||||
'name' => 'internal_picture_width',
|
||||
'value' => $this->fields['internal_picture_width'],
|
||||
])
|
||||
);
|
||||
echo "</td>";
|
||||
echo "<td>" . __('Height') . "</td>";
|
||||
echo "<td>";
|
||||
echo sprintf(
|
||||
'<input type="text" %1$s />',
|
||||
Html::parseAttributes([
|
||||
'name' => 'internal_picture_height',
|
||||
'value' => $this->fields['internal_picture_height'],
|
||||
])
|
||||
);
|
||||
echo "</td>";
|
||||
echo "</tr>\n";
|
||||
|
||||
// Custom CSS Internal
|
||||
$this->buildCssLine('internal', t_butterfly('Internal Page'));
|
||||
echo "</table>";
|
||||
echo "</div>";
|
||||
|
||||
// echo "</div>";
|
||||
|
||||
echo Html::scriptBlock("$('#tabs$rand').tabs({
|
||||
activate: function(event, ui) {
|
||||
localStorage['butterfly_last_tab'] = $('#tabs$rand').tabs('option', 'active');
|
||||
var editor = ui.newPanel.find('.butterfly-codemirror').data('CodeMirrorInstance');
|
||||
if (editor) {
|
||||
editor.refresh();
|
||||
}
|
||||
},
|
||||
active: localStorage['butterfly_last_tab']
|
||||
});");
|
||||
|
||||
if ($canedit) {
|
||||
echo "<table class='tab_cadre_fixe'>";
|
||||
echo "<tr class='tab_bg_2'>";
|
||||
echo "<td colspan='4' class='center'>";
|
||||
echo "<input type='submit' name='update' class='submit' value=\"" . _sx('button', 'Save') . "\">";
|
||||
echo "</td></tr>";
|
||||
echo "</table>";
|
||||
}
|
||||
|
||||
Html::closeForm();
|
||||
}
|
||||
}
|
||||
25
inc/fileversion.class.php
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
<?php
|
||||
|
||||
class PluginButterflyFileVersion {
|
||||
|
||||
private $_file = "";
|
||||
private $_initialized = false;
|
||||
|
||||
public function __construct($file = "") {
|
||||
$this->_file = $file;
|
||||
}
|
||||
|
||||
public function __toString() {
|
||||
// First call is inside of "file_exists", so it is necessary to return a valid file
|
||||
if (!$this->_initialized) {
|
||||
$this->_initialized = true;
|
||||
return $this->_file;
|
||||
}
|
||||
|
||||
// Second call is inside concatenation
|
||||
|
||||
$timestamp = PluginButterflyToolbox::getTimestamp();
|
||||
|
||||
return $this->_file . "?_=" . $timestamp;
|
||||
}
|
||||
}
|
||||
193
inc/scss.class.php
Normal file
|
|
@ -0,0 +1,193 @@
|
|||
<?php
|
||||
|
||||
class PluginButterflyScss {
|
||||
|
||||
static function hasScssSuport() {
|
||||
return class_exists(\ScssPhp\ScssPhp\Compiler::class);
|
||||
}
|
||||
|
||||
static function compileScss($content, $variables = []) {
|
||||
global $GLPI_CACHE;
|
||||
|
||||
$scss = new \ScssPhp\ScssPhp\Compiler();
|
||||
$scss->setOutputStyle(\ScssPhp\ScssPhp\OutputStyle::COMPRESSED);
|
||||
$scss->setSourceMap(\ScssPhp\ScssPhp\Compiler::SOURCE_MAP_NONE);
|
||||
|
||||
// Convert variables using ValueConverter
|
||||
if (!empty($variables)) {
|
||||
$convertedVariables = [];
|
||||
foreach ($variables as $key => $value) {
|
||||
$convertedVariables[$key] = \ScssPhp\ScssPhp\ValueConverter::fromPhp($value);
|
||||
}
|
||||
$scss->addVariables($convertedVariables);
|
||||
}
|
||||
|
||||
$scss->addImportPath(GLPI_ROOT);
|
||||
|
||||
$scss->addImportPath(
|
||||
function ($path) {
|
||||
$file_chunks = [];
|
||||
if (!preg_match('/^~@?(?<directory>.*)\/(?<file>[^\/]+)(?:(\.scss)?)/', $path, $file_chunks)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$possible_filenames = [
|
||||
sprintf('%s/css/lib/%s/%s.scss', GLPI_ROOT, $file_chunks['directory'], $file_chunks['file']),
|
||||
sprintf('%s/css/lib/%s/_%s.scss', GLPI_ROOT, $file_chunks['directory'], $file_chunks['file']),
|
||||
];
|
||||
foreach ($possible_filenames as $filename) {
|
||||
if (file_exists($filename)) {
|
||||
return $filename;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
);
|
||||
|
||||
$content = str_replace('\"', '"', $content);
|
||||
|
||||
$ckey = md5($content . json_encode($variables));
|
||||
|
||||
if ($GLPI_CACHE->has($ckey) && !isset($_GET['reload']) && !isset($_GET['nocache'])) {
|
||||
$css = $GLPI_CACHE->get($ckey);
|
||||
} else {
|
||||
$css = $scss->compileString($content, GLPI_ROOT . '/butterfly.scss')->getCss();
|
||||
if (!isset($_GET['nocache'])) {
|
||||
$GLPI_CACHE->set($ckey, $css);
|
||||
}
|
||||
}
|
||||
|
||||
return $css;
|
||||
}
|
||||
|
||||
static function getLoginCSS($theme = null, $variables = []) {
|
||||
if (!$theme) {
|
||||
$theme = PluginButterflyConfig::getConfig("login_theme", '');
|
||||
}
|
||||
$themeInfo = null;
|
||||
if ($theme) {
|
||||
$themeInfo = PluginButterflyTheme::getThemeInfo($theme);
|
||||
}
|
||||
|
||||
$picture = PluginButterflyConfig::getConfig("login_background_picture", '');
|
||||
|
||||
if (!$picture && $themeInfo && !empty($themeInfo['login-background'])) {
|
||||
$picture = $themeInfo['login-background'] . '&theme=' . $themeInfo['id'];
|
||||
}
|
||||
|
||||
$css = '';
|
||||
if ($picture) {
|
||||
$pictureUrl = PluginButterflyToolbox::getPictureUrl($picture);
|
||||
|
||||
$css .= "#firstboxlogin, #text-login, #logo_login, .login-container, .login-card, .glpi-login__wrapper, .main-content-card {";
|
||||
$css .= " background-color: transparent !important;";
|
||||
$css .= "}";
|
||||
$css .= "html, body {";
|
||||
$css .= " height: 100%;";
|
||||
$css .= "}";
|
||||
$css .= "body, body.login-page, body.welcome-anonymous {";
|
||||
$css .= " background-size: cover;";
|
||||
$css .= " background-repeat: no-repeat;";
|
||||
$css .= " background-position: center;";
|
||||
$css .= " background-image: url(\"" . $pictureUrl . "\");";
|
||||
$css .= "}";
|
||||
$css .= ".login-page__container::before, .login-page__illustration, .welcome-layout__background {";
|
||||
$css .= " background-image: none !important;";
|
||||
$css .= "}";
|
||||
}
|
||||
|
||||
$css_type = PluginButterflyConfig::getConfig("login_css_type", 'scss');
|
||||
$css_custom = PluginButterflyConfig::getConfig("login_css_custom", '');
|
||||
|
||||
$themeVariables = [];
|
||||
|
||||
$css_custom = html_entity_decode($css_custom);
|
||||
|
||||
if ($css_type === 'scss' && PluginButterflyScss::hasScssSuport()) {
|
||||
$variables = [];
|
||||
if ($themeInfo && isset($themeInfo['variables'])) {
|
||||
foreach ($themeInfo['variables'] as $k => $v) {
|
||||
$themeId = $themeInfo['id'];
|
||||
$fieldName = "login_theme-$themeId-$k";
|
||||
$fieldValue = PluginButterflyConfig::getConfig($fieldName, $v['default']);
|
||||
$variables[$k] = $fieldValue;
|
||||
$themeVariables[$k] = $fieldValue;
|
||||
}
|
||||
}
|
||||
|
||||
if ($themeInfo && $themeInfo['login-scss']) {
|
||||
$scssPath = str_replace('\\', '/', $themeInfo['path'] . '/' . $themeInfo['login-scss']);
|
||||
$css_custom = "@import '" . $scssPath . "';\n" . $css_custom;
|
||||
}
|
||||
|
||||
$variables['butterfly_timestamp'] = PluginButterflyToolbox::getTimestamp();
|
||||
|
||||
try {
|
||||
$css .= PluginButterflyScss::compileScss($css_custom, $variables);
|
||||
} catch (\Throwable $th) {
|
||||
// Log error and continue with basic CSS
|
||||
error_log("SCSS compilation error: " . $th->getMessage());
|
||||
}
|
||||
} else {
|
||||
if ($themeInfo && $themeInfo['login-css']) {
|
||||
$css .= file_get_contents($themeInfo['path'] . '/' . $themeInfo['login-css']) . "\n";
|
||||
}
|
||||
|
||||
if ($css_type === 'css') {
|
||||
$css .= $css_custom;
|
||||
}
|
||||
|
||||
if ($themeInfo && isset($themeInfo['variables'])) {
|
||||
foreach ($themeInfo['variables'] as $k => $v) {
|
||||
$themeId = $themeInfo['id'];
|
||||
$fieldName = "login_theme-$themeId-$k";
|
||||
$fieldValue = PluginButterflyConfig::getConfig($fieldName, $v['default']);
|
||||
$themeVariables[$k] = $fieldValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$cardBg = null;
|
||||
|
||||
if (!empty($themeVariables)) {
|
||||
$btnBg = $themeVariables['btn-background-color'] ?? null;
|
||||
$btnFg = $themeVariables['btn-foreground-color'] ?? null;
|
||||
if (isset($themeVariables['card-background-color']) && $themeVariables['card-background-color'] !== '') {
|
||||
$cardBg = Html::cleanInputText($themeVariables['card-background-color']);
|
||||
}
|
||||
|
||||
if ($btnBg) {
|
||||
$btnBg = Html::cleanInputText($btnBg);
|
||||
$css .= ".form-footer .btn.btn-primary, .form-footer .btn-primary.w-100, .glpi-login__wrapper .btn.btn-primary {";
|
||||
$css .= " background-color: {$btnBg} !important;";
|
||||
$css .= " border-color: {$btnBg} !important;";
|
||||
$css .= "}";
|
||||
$css .= ".form-footer .btn.btn-primary:hover, .glpi-login__wrapper .btn.btn-primary:hover {";
|
||||
$css .= " filter: brightness(0.9);";
|
||||
$css .= "}";
|
||||
}
|
||||
if ($btnFg) {
|
||||
$btnFg = Html::cleanInputText($btnFg);
|
||||
$css .= ".form-footer .btn.btn-primary, .glpi-login__wrapper .btn.btn-primary {";
|
||||
$css .= " color: {$btnFg} !important;";
|
||||
$css .= "}";
|
||||
}
|
||||
if ($cardBg) {
|
||||
$css .= ".page-anonymous .main-content-card {";
|
||||
$css .= " background-color: {$cardBg} !important;";
|
||||
$css .= "}";
|
||||
}
|
||||
}
|
||||
|
||||
if (!$cardBg && ($themeInfo || $picture)) {
|
||||
$css .= ".page-anonymous .main-content-card {";
|
||||
$css .= " background-color: transparent !important;";
|
||||
$css .= " border: 0;";
|
||||
$css .= " box-shadow: none;";
|
||||
$css .= "}";
|
||||
}
|
||||
|
||||
return $css;
|
||||
}
|
||||
}
|
||||
78
inc/theme.class.php
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
<?php
|
||||
|
||||
class PluginButterflyTheme {
|
||||
|
||||
public static function getThemeFolder() {
|
||||
return dirname(__DIR__) . '/themes';
|
||||
}
|
||||
|
||||
public static function isLoginTheme($dir) {
|
||||
$path = static::getThemeFolder() . '/' . $dir . '/login.scss';
|
||||
return file_exists($path);
|
||||
}
|
||||
|
||||
public static function getThemePath($dir, $type) {
|
||||
$path = static::getThemeFolder() . '/' . $dir . '/' . $type;
|
||||
if (!file_exists($path)) {
|
||||
return false;
|
||||
}
|
||||
return $dir . '/' . $type;
|
||||
}
|
||||
|
||||
public static function getThemeInfo($dir) {
|
||||
$dirPath = static::getThemeFolder() . '/' . $dir;
|
||||
$path = $dirPath . '/theme.json';
|
||||
if (!file_exists($path)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$json = file_get_contents($path);
|
||||
|
||||
if (!$json) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$info = @json_decode($json, true);
|
||||
|
||||
if (!$info) {
|
||||
return false;
|
||||
}
|
||||
$info['id'] = $dir;
|
||||
$info['path'] = $dirPath;
|
||||
|
||||
if (static::getThemePath($dir, 'login.background.jpg')) {
|
||||
$info['login-background'] = 'login.background.jpg';
|
||||
}
|
||||
if (static::getThemePath($dir, 'login.logo.png')) {
|
||||
$info['login-logo'] = 'login.logo.png';
|
||||
}
|
||||
if (static::getThemePath($dir, 'login.preview.jpg')) {
|
||||
$info['login-preview'] = 'login.preview.jpg';
|
||||
}
|
||||
if (static::getThemePath($dir, 'login.scss')) {
|
||||
$info['login-scss'] = 'login.scss';
|
||||
} else if (static::getThemePath($dir, 'login.css')) {
|
||||
$info['login-css'] = 'login.css';
|
||||
}
|
||||
|
||||
return $info;
|
||||
}
|
||||
|
||||
public static function getLoginThemes() {
|
||||
$themes = [];
|
||||
$dirs = scandir(static::getThemeFolder());
|
||||
|
||||
foreach ($dirs as $dir) {
|
||||
if (!static::isLoginTheme($dir)) {
|
||||
continue;
|
||||
}
|
||||
$info = static::getThemeInfo($dir);
|
||||
if (!$info) {
|
||||
continue;
|
||||
}
|
||||
$themes[$dir] = $info;
|
||||
}
|
||||
|
||||
return $themes;
|
||||
}
|
||||
}
|
||||
259
inc/toolbox.class.php
Normal file
|
|
@ -0,0 +1,259 @@
|
|||
<?php
|
||||
|
||||
class PluginButterflyToolbox {
|
||||
|
||||
static public function getTimestamp() {
|
||||
global $GLPI_CACHE;
|
||||
|
||||
if (!$GLPI_CACHE) {
|
||||
return PluginButterflyConfig::getConfig('timestamp', time());
|
||||
}
|
||||
|
||||
$timestamp = $GLPI_CACHE->get('butterfly_timestamp');
|
||||
if (!$timestamp) {
|
||||
$timestamp = time();
|
||||
$GLPI_CACHE->set('butterfly_timestamp', $timestamp);
|
||||
}
|
||||
return $timestamp;
|
||||
}
|
||||
|
||||
static public function setTimestamp($timestamp = null) {
|
||||
global $GLPI_CACHE;
|
||||
|
||||
if (!$timestamp) {
|
||||
$timestamp = time();
|
||||
}
|
||||
|
||||
if (!$GLPI_CACHE) {
|
||||
Config::setConfigurationValues('butterfly', [
|
||||
'timestamp' => $timestamp,
|
||||
]);
|
||||
return;
|
||||
}
|
||||
|
||||
$GLPI_CACHE->set('butterfly_timestamp', $timestamp);
|
||||
}
|
||||
|
||||
static public function startsWith($haystack, $needle) {
|
||||
$length = strlen($needle);
|
||||
return (substr($haystack, 0, $length) === $needle);
|
||||
}
|
||||
|
||||
static function getPictureUrl($path) {
|
||||
$rawPath = trim((string)$path);
|
||||
|
||||
if ($rawPath === '') {
|
||||
return null;
|
||||
}
|
||||
|
||||
// If the value already looks like an URL just return it untouched
|
||||
if (preg_match('#^(https?:)?//#', $rawPath)) {
|
||||
return $rawPath;
|
||||
}
|
||||
|
||||
if (strpos($rawPath, '.php?') !== false) {
|
||||
$normalized = (strpos($rawPath, '/') === 0) ? $rawPath : '/' . $rawPath;
|
||||
return Html::getPrefixedUrl($normalized);
|
||||
}
|
||||
|
||||
$endpoint = '/plugins/butterfly/front/picture.send.php';
|
||||
|
||||
// Check if this is a theme image (contains &theme= parameter)
|
||||
if (strpos($rawPath, '&theme=') !== false) {
|
||||
[$filePath, $theme] = explode('&theme=', $rawPath, 2);
|
||||
$filePath = trim($filePath);
|
||||
$theme = trim($theme);
|
||||
|
||||
if ($filePath !== '' && $theme !== '') {
|
||||
return Html::getPrefixedUrl(
|
||||
$endpoint . '?path=' . rawurlencode($filePath) . '&theme=' . rawurlencode($theme)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return Html::getPrefixedUrl($endpoint . '?path=' . rawurlencode($rawPath));
|
||||
}
|
||||
|
||||
public static function getStorageBasePath() {
|
||||
if (defined('GLPI_PLUGIN_DOC_DIR')) {
|
||||
return rtrim(constant('GLPI_PLUGIN_DOC_DIR'), '/') . "/butterfly";
|
||||
}
|
||||
if (defined('GLPI_VAR_DIR')) {
|
||||
return rtrim(constant('GLPI_VAR_DIR'), '/') . "/_plugins/butterfly";
|
||||
}
|
||||
|
||||
return dirname(dirname(dirname(__DIR__))) . "/glpi_data/_plugins/butterfly";
|
||||
}
|
||||
|
||||
static public function savePicture($src, $uniq_prefix = null) {
|
||||
$basePath = static::getStorageBasePath();
|
||||
|
||||
if (class_exists('Document') && method_exists('Document', 'isPicture') && !Document::isPicture($src)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$filename = uniqid($uniq_prefix);
|
||||
$ext = pathinfo($src, PATHINFO_EXTENSION);
|
||||
$subdirectory = substr($filename, -2); // subdirectory based on last 2 hex digit
|
||||
|
||||
$i = 0;
|
||||
do {
|
||||
// Iterate on possible suffix while dest exists.
|
||||
// This case will almost never exists as dest is based on an unique id.
|
||||
$dest = $basePath
|
||||
. '/' . $subdirectory
|
||||
. '/' . $filename . ($i > 0 ? '_' . $i : '') . '.' . $ext;
|
||||
$i++;
|
||||
} while (file_exists($dest));
|
||||
|
||||
if (!is_dir($basePath . '/' . $subdirectory) && !mkdir($basePath . '/' . $subdirectory, 0777, true)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!rename($src, $dest)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return substr($dest, strlen($basePath . '/')); // Return dest relative to GLPI_PICTURE_DIR
|
||||
}
|
||||
|
||||
public static function deletePicture($path) {
|
||||
$basePath = static::getStorageBasePath();
|
||||
$fullpath = $basePath . '/' . $path;
|
||||
|
||||
if (!file_exists($fullpath)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$fullpath = realpath($fullpath);
|
||||
if (!static::startsWith($fullpath, realpath($basePath))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return @unlink($fullpath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resize a picture to the new size
|
||||
* Always produce a JPG file!
|
||||
*
|
||||
* @since 0.85
|
||||
*
|
||||
* @param string $source_path path of the picture to be resized
|
||||
* @param string $dest_path path of the new resized picture
|
||||
* @param integer $new_width new width after resized (default 71)
|
||||
* @param integer $new_height new height after resized (default 71)
|
||||
* @param integer $img_y y axis of picture (default 0)
|
||||
* @param integer $img_x x axis of picture (default 0)
|
||||
* @param integer $img_width width of picture (default 0)
|
||||
* @param integer $img_height height of picture (default 0)
|
||||
* @param integer $max_size max size of the picture (default 500, is set to 0 no resize)
|
||||
*
|
||||
* @return boolean
|
||||
**/
|
||||
static function resizePicture(
|
||||
$source_path,
|
||||
$dest_path,
|
||||
$new_width = 71,
|
||||
$new_height = 71,
|
||||
$img_y = 0,
|
||||
$img_x = 0,
|
||||
$img_width = 0,
|
||||
$img_height = 0,
|
||||
$max_size = 500
|
||||
) {
|
||||
|
||||
//get img informations (dimensions and extension)
|
||||
$img_infos = getimagesize($source_path);
|
||||
if (empty($img_width)) {
|
||||
$img_width = $img_infos[0];
|
||||
}
|
||||
if (empty($img_height)) {
|
||||
$img_height = $img_infos[1];
|
||||
}
|
||||
if (empty($new_width)) {
|
||||
$new_width = $img_infos[0];
|
||||
}
|
||||
if (empty($new_height)) {
|
||||
$new_height = $img_infos[1];
|
||||
}
|
||||
|
||||
// Image max size is 500 pixels : is set to 0 no resize
|
||||
if ($max_size > 0) {
|
||||
if (($img_width > $max_size)
|
||||
|| ($img_height > $max_size)
|
||||
) {
|
||||
$source_aspect_ratio = $img_width / $img_height;
|
||||
if ($source_aspect_ratio < 1) {
|
||||
$new_width = $max_size * $source_aspect_ratio;
|
||||
$new_height = $max_size;
|
||||
} else {
|
||||
$new_width = $max_size;
|
||||
$new_height = $max_size / $source_aspect_ratio;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$img_type = $img_infos[2];
|
||||
|
||||
switch ($img_type) {
|
||||
case IMAGETYPE_BMP:
|
||||
$source_res = imagecreatefromwbmp($source_path);
|
||||
break;
|
||||
|
||||
case IMAGETYPE_GIF:
|
||||
$source_res = imagecreatefromgif($source_path);
|
||||
break;
|
||||
|
||||
case IMAGETYPE_JPEG:
|
||||
$source_res = imagecreatefromjpeg($source_path);
|
||||
break;
|
||||
|
||||
case IMAGETYPE_PNG:
|
||||
$source_res = imagecreatefrompng($source_path);
|
||||
break;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
//create new img resource for store thumbnail
|
||||
$source_dest = imagecreatetruecolor($new_width, $new_height);
|
||||
|
||||
// set transparent background for PNG/GIF
|
||||
if ($img_type === IMAGETYPE_GIF || $img_type === IMAGETYPE_PNG) {
|
||||
imagecolortransparent($source_dest, imagecolorallocatealpha($source_dest, 0, 0, 0, 127));
|
||||
imagealphablending($source_dest, false);
|
||||
imagesavealpha($source_dest, true);
|
||||
}
|
||||
|
||||
//resize image
|
||||
imagecopyresampled(
|
||||
$source_dest,
|
||||
$source_res,
|
||||
0,
|
||||
0,
|
||||
$img_x,
|
||||
$img_y,
|
||||
$new_width,
|
||||
$new_height,
|
||||
$img_width,
|
||||
$img_height
|
||||
);
|
||||
|
||||
//output img
|
||||
$result = null;
|
||||
switch ($img_type) {
|
||||
case IMAGETYPE_GIF:
|
||||
case IMAGETYPE_PNG:
|
||||
$result = imagepng($source_dest, $dest_path);
|
||||
break;
|
||||
|
||||
case IMAGETYPE_JPEG:
|
||||
default:
|
||||
$result = imagejpeg($source_dest, $dest_path, 90);
|
||||
break;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
82
locales/butterfly.pot
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the butterfly package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Butterfly\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-02-17 13:42-0300\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: \n"
|
||||
"Language: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: inc/config.class.php:27 setup.php:53
|
||||
msgid "Butterfly"
|
||||
msgstr ""
|
||||
|
||||
#: inc/config.class.php:105
|
||||
#, php-format
|
||||
msgid "Unable to compile the SCSS (%1$s). Message: "
|
||||
msgstr ""
|
||||
|
||||
#: inc/config.class.php:124 inc/config.class.php:338 inc/config.class.php:545
|
||||
msgid "Login Page"
|
||||
msgstr ""
|
||||
|
||||
#: inc/config.class.php:125 inc/config.class.php:339 inc/config.class.php:582
|
||||
msgid "Internal Page"
|
||||
msgstr ""
|
||||
|
||||
#: inc/config.class.php:184 inc/config.class.php:187 inc/config.class.php:500
|
||||
#: inc/config.class.php:503
|
||||
msgid "Reset"
|
||||
msgstr ""
|
||||
|
||||
#: inc/config.class.php:199
|
||||
#, php-format
|
||||
msgid "Recommended size: %1$s"
|
||||
msgstr ""
|
||||
|
||||
#: inc/config.class.php:209
|
||||
#, php-format
|
||||
msgid "Custom CSS for %1$s"
|
||||
msgstr ""
|
||||
|
||||
#: inc/config.class.php:212
|
||||
msgid "CSS Type"
|
||||
msgstr ""
|
||||
|
||||
#: inc/config.class.php:337
|
||||
msgid "Favicon and Title"
|
||||
msgstr ""
|
||||
|
||||
#: inc/config.class.php:366
|
||||
msgid "Footer"
|
||||
msgstr ""
|
||||
|
||||
#: inc/config.class.php:370
|
||||
msgid "Hide"
|
||||
msgstr ""
|
||||
|
||||
#: inc/config.class.php:371
|
||||
msgid "Custom"
|
||||
msgstr ""
|
||||
|
||||
#: inc/config.class.php:377
|
||||
msgid "Footer text"
|
||||
msgstr ""
|
||||
|
||||
#: inc/config.class.php:409
|
||||
msgid "Theme"
|
||||
msgstr ""
|
||||
|
||||
#: inc/config.class.php:540
|
||||
msgid "Background picture"
|
||||
msgstr ""
|
||||
BIN
locales/en_GB.mo
Normal file
82
locales/en_GB.po
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
# English translations for butterfly package.
|
||||
# Copyright (C) 2021 THE butterfly'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the butterfly package.
|
||||
# Automatically generated, 2021.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Butterfly\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-02-17 13:42-0300\n"
|
||||
"PO-Revision-Date: 2021-02-17 13:42-0300\n"
|
||||
"Last-Translator: Automatically generated\n"
|
||||
"Language-Team: \n"
|
||||
"Language: en_GB\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#: inc/config.class.php:27 setup.php:53
|
||||
msgid "Butterfly"
|
||||
msgstr "Butterfly"
|
||||
|
||||
#: inc/config.class.php:105
|
||||
#, php-format
|
||||
msgid "Unable to compile the SCSS (%1$s). Message: "
|
||||
msgstr "Unable to compile the SCSS (%1$s). Message: "
|
||||
|
||||
#: inc/config.class.php:124 inc/config.class.php:338 inc/config.class.php:545
|
||||
msgid "Login Page"
|
||||
msgstr "Login Page"
|
||||
|
||||
#: inc/config.class.php:125 inc/config.class.php:339 inc/config.class.php:582
|
||||
msgid "Internal Page"
|
||||
msgstr "Internal Page"
|
||||
|
||||
#: inc/config.class.php:184 inc/config.class.php:187 inc/config.class.php:500
|
||||
#: inc/config.class.php:503
|
||||
msgid "Reset"
|
||||
msgstr "Reset"
|
||||
|
||||
#: inc/config.class.php:199
|
||||
#, php-format
|
||||
msgid "Recommended size: %1$s"
|
||||
msgstr "Recommended size: %1$s"
|
||||
|
||||
#: inc/config.class.php:209
|
||||
#, php-format
|
||||
msgid "Custom CSS for %1$s"
|
||||
msgstr "Custom CSS for %1$s"
|
||||
|
||||
#: inc/config.class.php:212
|
||||
msgid "CSS Type"
|
||||
msgstr "CSS Type"
|
||||
|
||||
#: inc/config.class.php:337
|
||||
msgid "Favicon and Title"
|
||||
msgstr "Favicon and Title"
|
||||
|
||||
#: inc/config.class.php:366
|
||||
msgid "Footer"
|
||||
msgstr "Footer"
|
||||
|
||||
#: inc/config.class.php:370
|
||||
msgid "Hide"
|
||||
msgstr "Hide"
|
||||
|
||||
#: inc/config.class.php:371
|
||||
msgid "Custom"
|
||||
msgstr "Custom"
|
||||
|
||||
#: inc/config.class.php:377
|
||||
msgid "Footer text"
|
||||
msgstr "Footer text"
|
||||
|
||||
#: inc/config.class.php:409
|
||||
msgid "Theme"
|
||||
msgstr "Theme"
|
||||
|
||||
#: inc/config.class.php:540
|
||||
msgid "Background picture"
|
||||
msgstr "Background picture"
|
||||
BIN
locales/pt_BR.mo
Normal file
82
locales/pt_BR.po
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
# Tradução em português para o pacote butterfly.
|
||||
# Copyright (C) 2021 THE butterfly'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the butterfly package.
|
||||
# Automatically generated, 2021.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Butterfly\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2021-02-17 13:42-0300\n"
|
||||
"PO-Revision-Date: 2021-01-30 16:27-0300\n"
|
||||
"Last-Translator: Automatically generated\n"
|
||||
"Language-Team: \n"
|
||||
"Language: pt_BR\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#: inc/config.class.php:27 setup.php:53
|
||||
msgid "Butterfly"
|
||||
msgstr "Butterfly"
|
||||
|
||||
#: inc/config.class.php:105
|
||||
#, php-format
|
||||
msgid "Unable to compile the SCSS (%1$s). Message: "
|
||||
msgstr "Incapaz de compilar o SCSS (%1$s). Mensagem: "
|
||||
|
||||
#: inc/config.class.php:124 inc/config.class.php:338 inc/config.class.php:545
|
||||
msgid "Login Page"
|
||||
msgstr "Página de Login"
|
||||
|
||||
#: inc/config.class.php:125 inc/config.class.php:339 inc/config.class.php:582
|
||||
msgid "Internal Page"
|
||||
msgstr "Página Interna"
|
||||
|
||||
#: inc/config.class.php:184 inc/config.class.php:187 inc/config.class.php:500
|
||||
#: inc/config.class.php:503
|
||||
msgid "Reset"
|
||||
msgstr "Redefinir"
|
||||
|
||||
#: inc/config.class.php:199
|
||||
#, php-format
|
||||
msgid "Recommended size: %1$s"
|
||||
msgstr "Tamanho recomendado: %1$s"
|
||||
|
||||
#: inc/config.class.php:209
|
||||
#, php-format
|
||||
msgid "Custom CSS for %1$s"
|
||||
msgstr "CSS personalizado para %1$s"
|
||||
|
||||
#: inc/config.class.php:212
|
||||
msgid "CSS Type"
|
||||
msgstr "Tipo de CSS"
|
||||
|
||||
#: inc/config.class.php:337
|
||||
msgid "Favicon and Title"
|
||||
msgstr "Favicon e Título"
|
||||
|
||||
#: inc/config.class.php:366
|
||||
msgid "Footer"
|
||||
msgstr "Rodapé"
|
||||
|
||||
#: inc/config.class.php:370
|
||||
msgid "Hide"
|
||||
msgstr "Ocultar"
|
||||
|
||||
#: inc/config.class.php:371
|
||||
msgid "Custom"
|
||||
msgstr "Personalizado"
|
||||
|
||||
#: inc/config.class.php:377
|
||||
msgid "Footer text"
|
||||
msgstr "Texto do rodapé"
|
||||
|
||||
#: inc/config.class.php:409
|
||||
msgid "Theme"
|
||||
msgstr "Tema"
|
||||
|
||||
#: inc/config.class.php:540
|
||||
msgid "Background picture"
|
||||
msgstr "Imagem de fundo"
|
||||
BIN
pics/login.preview.png
Normal file
|
After Width: | Height: | Size: 243 KiB |
BIN
plugin.png
Normal file
|
After Width: | Height: | Size: 22 KiB |
BIN
public/themes/aurora-boreal/login.background.jpg
Normal file
|
After Width: | Height: | Size: 301 KiB |
108
public/themes/aurora-boreal/login.css
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
@charset "UTF-8";
|
||||
/*Tema 7 - Aurora Boreal*/
|
||||
body .card {
|
||||
border: 0;
|
||||
background: transparent;
|
||||
}
|
||||
.flex-fill.d-flex.flex-column.justify-content-center.py-4.mt-4 {
|
||||
width: 525px;
|
||||
background: transparent;
|
||||
margin: 0px auto !important;
|
||||
}
|
||||
.col-md-5 {
|
||||
margin: 0 !important;
|
||||
width: 100%;
|
||||
}
|
||||
h2.card-header.text-center.mb-4, div.card-header:has(.mx-auto) {
|
||||
display: none;
|
||||
}
|
||||
.flex-fill.d-flex.flex-column.justify-content-center.py-4.mt-4 {
|
||||
min-height: 711px;
|
||||
width: 525px;
|
||||
background: transparent;
|
||||
border-radius: 0;
|
||||
box-shadow: 0 4px 30pxrgba 0, 0, 0, 0.1;
|
||||
-webkit-backdrop-filter: blur(5px);
|
||||
border: 1pxsolidrgba 255, 255, 255, 0.3;
|
||||
margin: 0px auto !important;
|
||||
height: 100% !important;
|
||||
}
|
||||
span.glpi-logo.mb-4 {
|
||||
margin: 0 !important;
|
||||
}
|
||||
.btn-primary, .btn-outline-primary, .btn-ghost-primary {
|
||||
--tblr-btn-color: #71090e;
|
||||
--tblr-btn-color-interactive: #8d0a10;
|
||||
--tblr-btn-color-text: #1e293b;
|
||||
}
|
||||
body .form-control:focus {
|
||||
color: inherit;
|
||||
background-color: #fdfdfd;
|
||||
border-color: #1b5ca3c2;
|
||||
outline: 0;
|
||||
box-shadow: 0 0 0 0.25rem #1b5ca3c2;
|
||||
}
|
||||
.mb-3, .mb-4 {
|
||||
position: relative;
|
||||
}
|
||||
.mb-3:after {
|
||||
font-family: "Font Awesome 5 Free";
|
||||
font-weight: 900;
|
||||
content: "";
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
color: #6a696982;
|
||||
top: 12px;
|
||||
}
|
||||
.mb-4:before {
|
||||
font-family: "Font Awesome 5 Free";
|
||||
font-weight: 900;
|
||||
content: "";
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
color: #6a696982;
|
||||
top: 12px;
|
||||
}
|
||||
.col-md-5 {
|
||||
margin: 0 !important;
|
||||
width: 100%;
|
||||
max-width: 289px;
|
||||
}
|
||||
body .form-control {
|
||||
display: block;
|
||||
width: 100%;
|
||||
padding: 0.7375rem 0.75rem;
|
||||
font-size: 0.875rem;
|
||||
font-weight: 400;
|
||||
line-height: 1.4285714286;
|
||||
color: inherit;
|
||||
background-color: #fdfdfd;
|
||||
background-clip: padding-box;
|
||||
border: 1px solid #d9dbde;
|
||||
appearance: none;
|
||||
border-radius: 34px;
|
||||
transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
|
||||
}
|
||||
button.btn.btn-primary.w-100 {
|
||||
background: transparent;
|
||||
color: #ffffff;
|
||||
padding: 11px;
|
||||
border-radius: 30px;
|
||||
border: 1px solid #fff;
|
||||
}
|
||||
label.form-label {
|
||||
color: #fff;
|
||||
}
|
||||
a {
|
||||
color: #73fff9 !important;
|
||||
text-decoration: none;
|
||||
}
|
||||
label.form-label {
|
||||
display: none;
|
||||
color: #fff;
|
||||
}
|
||||
.card-body {
|
||||
margin: 0 auto;
|
||||
width: 350px;
|
||||
max-width: 100%;
|
||||
}
|
||||
BIN
public/themes/aurora-boreal/login.logo.png
Normal file
|
After Width: | Height: | Size: 3.5 KiB |
BIN
public/themes/aurora-boreal/login.preview.jpg
Normal file
|
After Width: | Height: | Size: 190 KiB |
129
public/themes/aurora-boreal/login.scss
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
/*Tema 7 - Aurora Boreal*/
|
||||
|
||||
$btn-foreground-color: #ffffff !default;
|
||||
|
||||
body .card {
|
||||
border: 0;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.flex-fill.d-flex.flex-column.justify-content-center.py-4.mt-4 {
|
||||
width: 525px;
|
||||
background: transparent;
|
||||
margin: 0px auto !important;
|
||||
}
|
||||
|
||||
.col-md-5 {
|
||||
margin: 0 !important;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
h2.card-header.text-center.mb-4,
|
||||
div.card-header:has(.mx-auto) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.flex-fill.d-flex.flex-column.justify-content-center.py-4.mt-4 {
|
||||
min-height: 711px;
|
||||
width: 525px;
|
||||
background: transparent;
|
||||
border-radius: 0;
|
||||
box-shadow: 0 4px 30pxrgba (0, 0, 0, 0.1);
|
||||
-webkit-backdrop-filter: blur(5px);
|
||||
border: 1pxsolidrgba (255, 255, 255, 0.3);
|
||||
margin: 0px auto !important;
|
||||
height: 100% !important;
|
||||
}
|
||||
|
||||
span.glpi-logo.mb-4 {
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
.btn-primary,
|
||||
.btn-outline-primary,
|
||||
.btn-ghost-primary {
|
||||
--tblr-btn-color: #71090e;
|
||||
--tblr-btn-color-interactive: #8d0a10;
|
||||
--tblr-btn-color-text: #1e293b;
|
||||
}
|
||||
|
||||
body .form-control:focus {
|
||||
color: inherit;
|
||||
background-color: #fdfdfd;
|
||||
border-color: #1b5ca3c2;
|
||||
outline: 0;
|
||||
box-shadow: 0 0 0 0.25rem #1b5ca3c2;
|
||||
}
|
||||
|
||||
.mb-3,
|
||||
.mb-4 {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.mb-3:after {
|
||||
font-family: "Font Awesome 5 Free";
|
||||
font-weight: 900;
|
||||
content: "\f007";
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
color: #6a696982;
|
||||
top: 12px;
|
||||
}
|
||||
|
||||
.mb-4:before {
|
||||
font-family: "Font Awesome 5 Free";
|
||||
font-weight: 900;
|
||||
content: "\f023";
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
color: #6a696982;
|
||||
top: 12px;
|
||||
}
|
||||
|
||||
.col-md-5 {
|
||||
margin: 0 !important;
|
||||
width: 100%;
|
||||
max-width: 289px;
|
||||
}
|
||||
|
||||
body .form-control {
|
||||
display: block;
|
||||
width: 100%;
|
||||
padding: 0.7375rem 0.75rem;
|
||||
font-size: 0.875rem;
|
||||
font-weight: 400;
|
||||
line-height: 1.4285714286;
|
||||
color: inherit;
|
||||
background-color: #fdfdfd;
|
||||
background-clip: padding-box;
|
||||
border: 1px solid #d9dbde;
|
||||
appearance: none;
|
||||
border-radius: 34px;
|
||||
transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
|
||||
}
|
||||
|
||||
button.btn.btn-primary.w-100 {
|
||||
background: transparent;
|
||||
color: $btn-foreground-color;
|
||||
padding: 11px;
|
||||
border-radius: 30px;
|
||||
border: 1px solid #fff;
|
||||
}
|
||||
|
||||
label.form-label {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #73fff9 !important;
|
||||
text-decoration: none;
|
||||
}
|
||||
label.form-label {
|
||||
display: none;
|
||||
color: #fff;
|
||||
}
|
||||
.card-body {
|
||||
margin: 0 auto;
|
||||
width: 350px;
|
||||
max-width: 100%;
|
||||
}
|
||||
14
public/themes/aurora-boreal/theme.json
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"name": "Aurora Boreal",
|
||||
"description": "Aurora Boreal Theme",
|
||||
"variables": {
|
||||
"btn-foreground-color": {
|
||||
"name": "Cor do texto dos Botões",
|
||||
"default": "#ffffff"
|
||||
},
|
||||
"card-background-color": {
|
||||
"name": "Cor do cartão",
|
||||
"default": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
public/themes/baloons/login.background.jpg
Normal file
|
After Width: | Height: | Size: 141 KiB |
114
public/themes/baloons/login.css
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
@charset "UTF-8";
|
||||
/*Tema 9 - Baloons*/
|
||||
body .card {
|
||||
border: 0;
|
||||
background: transparent;
|
||||
}
|
||||
.col-md-5 {
|
||||
margin: 0 !important;
|
||||
width: 100%;
|
||||
}
|
||||
h2.card-header.text-center.mb-4, div.card-header:has(.mx-auto) {
|
||||
display: none;
|
||||
}
|
||||
span.glpi-logo.mb-4 {
|
||||
margin: 0 !important;
|
||||
}
|
||||
.btn-primary, .btn-outline-primary, .btn-ghost-primary {
|
||||
--tblr-btn-color: #71090e;
|
||||
--tblr-btn-color-interactive: #8d0a10;
|
||||
--tblr-btn-color-text: #1e293b;
|
||||
}
|
||||
.mb-3, .mb-4 {
|
||||
position: relative;
|
||||
}
|
||||
.mb-3:after {
|
||||
font-family: "Font Awesome 5 Free";
|
||||
font-weight: 900;
|
||||
content: "";
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
color: #6a696982;
|
||||
top: 12px;
|
||||
}
|
||||
.mb-4:before {
|
||||
font-family: "Font Awesome 5 Free";
|
||||
font-weight: 900;
|
||||
content: "";
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
color: #6a696982;
|
||||
top: 12px;
|
||||
}
|
||||
.col-md-5 {
|
||||
margin: 0 !important;
|
||||
width: 100%;
|
||||
max-width: 289px;
|
||||
}
|
||||
label.form-label {
|
||||
color: #a6abb1;
|
||||
}
|
||||
.flex-fill.d-flex.flex-column.justify-content-center.py-4.mt-4 {
|
||||
width: 383px;
|
||||
background: #e6eef8;
|
||||
border-radius: 0;
|
||||
margin: 114px auto !important;
|
||||
outline: 28px solid #ffffff30;
|
||||
outline-offset: 0;
|
||||
box-shadow: 0px 6px 13px 1px #00000047;
|
||||
height: 100% !important;
|
||||
}
|
||||
button.btn.btn-primary.w-100 {
|
||||
background: transparent;
|
||||
color: #ffffff;
|
||||
padding: 11px;
|
||||
border-radius: 30px;
|
||||
border: 1px solid #fff;
|
||||
background: #593a90;
|
||||
background: linear-gradient(0deg, #593a90 0%, #7551b5 48%, 1 100%);
|
||||
}
|
||||
a {
|
||||
color: #7551b5 !important;
|
||||
text-decoration: none;
|
||||
}
|
||||
body .form-control {
|
||||
display: block;
|
||||
width: 100%;
|
||||
padding: 0.7375rem 0.75rem;
|
||||
font-size: 0.875rem;
|
||||
font-weight: 400;
|
||||
line-height: 1.4285714286;
|
||||
color: inherit;
|
||||
background-color: #fdfdfd;
|
||||
background-clip: padding-box;
|
||||
border: 0;
|
||||
appearance: none;
|
||||
border-radius: 34px;
|
||||
transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
|
||||
background: linear-gradient(0deg, #e6eef8, #e6eef8), #cfd8dc;
|
||||
box-shadow: inset -4px -4px 12px rgba(253, 255, 255, 0.8), inset 4px 4px 12px rgba(187, 195, 206, 0.6);
|
||||
border-radius: 16px;
|
||||
}
|
||||
label.form-label {
|
||||
display: none;
|
||||
color: #fff;
|
||||
}
|
||||
span.form-label-description {
|
||||
margin-top: 10px;
|
||||
margin-bottom: 10px;
|
||||
text-align: left;
|
||||
width: 100%;
|
||||
display: block;
|
||||
}
|
||||
.card-body {
|
||||
margin: 0 auto;
|
||||
width: 350px;
|
||||
max-width: 100%;
|
||||
}
|
||||
.form-control:focus {
|
||||
color: inherit;
|
||||
background-color: #fdfdfd;
|
||||
border-color: #673ab7;
|
||||
outline: 0;
|
||||
box-shadow: 0 0 0 0.25rem rgba(103, 58, 183, 0.26);
|
||||
}
|
||||
BIN
public/themes/baloons/login.logo.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
BIN
public/themes/baloons/login.preview.jpg
Normal file
|
After Width: | Height: | Size: 118 KiB |
137
public/themes/baloons/login.scss
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
/*Tema 9 - Baloons*/
|
||||
|
||||
$btn-background-color1: #593a90 !default;
|
||||
$btn-background-color2: #7551b5 !default;
|
||||
$btn-foreground-color: #ffffff !default;
|
||||
|
||||
body .card {
|
||||
border: 0;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.col-md-5 {
|
||||
margin: 0 !important;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
h2.card-header.text-center.mb-4,
|
||||
div.card-header:has(.mx-auto) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
span.glpi-logo.mb-4 {
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
.btn-primary,
|
||||
.btn-outline-primary,
|
||||
.btn-ghost-primary {
|
||||
--tblr-btn-color: #71090e;
|
||||
--tblr-btn-color-interactive: #8d0a10;
|
||||
--tblr-btn-color-text: #1e293b;
|
||||
}
|
||||
|
||||
.mb-3,
|
||||
.mb-4 {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.mb-3:after {
|
||||
font-family: "Font Awesome 5 Free";
|
||||
font-weight: 900;
|
||||
content: "\f007";
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
color: #6a696982;
|
||||
top: 12px;
|
||||
}
|
||||
|
||||
.mb-4:before {
|
||||
font-family: "Font Awesome 5 Free";
|
||||
font-weight: 900;
|
||||
content: "\f023";
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
color: #6a696982;
|
||||
top: 12px;
|
||||
}
|
||||
|
||||
.col-md-5 {
|
||||
margin: 0 !important;
|
||||
width: 100%;
|
||||
max-width: 289px;
|
||||
}
|
||||
|
||||
label.form-label {
|
||||
color: #a6abb1;
|
||||
}
|
||||
|
||||
.flex-fill.d-flex.flex-column.justify-content-center.py-4.mt-4 {
|
||||
width: 383px;
|
||||
background: rgb(230 238 248);
|
||||
border-radius: 0;
|
||||
margin: 114px auto !important;
|
||||
outline: 28px solid #ffffff30;
|
||||
outline-offset: 0;
|
||||
box-shadow: 0px 6px 13px 1px #00000047;
|
||||
height: 100% !important;
|
||||
}
|
||||
|
||||
button.btn.btn-primary.w-100 {
|
||||
background: transparent;
|
||||
color: $btn-foreground-color;
|
||||
padding: 11px;
|
||||
border-radius: 30px;
|
||||
border: 1px solid #fff;
|
||||
background: $btn-background-color1;
|
||||
background: linear-gradient(0deg, $btn-background-color1 0%, $btn-background-color2 48%, 1 100%);
|
||||
}
|
||||
|
||||
a {
|
||||
color: #7551b5 !important;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
body .form-control {
|
||||
display: block;
|
||||
width: 100%;
|
||||
padding: 0.7375rem 0.75rem;
|
||||
font-size: 0.875rem;
|
||||
font-weight: 400;
|
||||
line-height: 1.4285714286;
|
||||
color: inherit;
|
||||
background-color: #fdfdfd;
|
||||
background-clip: padding-box;
|
||||
border: 0;
|
||||
appearance: none;
|
||||
border-radius: 34px;
|
||||
transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
|
||||
background: linear-gradient(0deg, #e6eef8, #e6eef8), #cfd8dc;
|
||||
box-shadow: inset -4px -4px 12px rgb(253 255 255 / 80%),
|
||||
inset 4px 4px 12px rgb(187 195 206 / 60%);
|
||||
border-radius: 16px;
|
||||
}
|
||||
|
||||
label.form-label {
|
||||
display: none;
|
||||
color: #fff;
|
||||
}
|
||||
span.form-label-description {
|
||||
margin-top: 10px;
|
||||
margin-bottom: 10px;
|
||||
text-align: left;
|
||||
width: 100%;
|
||||
display: block;
|
||||
}
|
||||
.card-body {
|
||||
margin: 0 auto;
|
||||
width: 350px;
|
||||
max-width: 100%;
|
||||
}
|
||||
.form-control:focus {
|
||||
color: inherit;
|
||||
background-color: #fdfdfd;
|
||||
border-color: #673ab7;
|
||||
outline: 0;
|
||||
box-shadow: 0 0 0 0.25rem rgb(103 58 183 / 26%);
|
||||
}
|
||||
22
public/themes/baloons/theme.json
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"name": "Ballons",
|
||||
"description": "Ballons Theme",
|
||||
"variables": {
|
||||
"btn-background-color1": {
|
||||
"name": "Cor de fundo 1 dos Botões",
|
||||
"default": "#593a90"
|
||||
},
|
||||
"btn-background-color2": {
|
||||
"name": "Cor de fundo 2 dos Botões",
|
||||
"default": "#7551b5"
|
||||
},
|
||||
"btn-foreground-color": {
|
||||
"name": "Cor do texto dos Botões",
|
||||
"default": "#ffffff"
|
||||
},
|
||||
"card-background-color": {
|
||||
"name": "Cor do cartão",
|
||||
"default": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
public/themes/cloud/login.background.jpg
Normal file
|
After Width: | Height: | Size: 183 KiB |
119
public/themes/cloud/login.css
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
@charset "UTF-8";
|
||||
/*Tema 3 - Cloud*/
|
||||
body .card {
|
||||
border: 0;
|
||||
background: transparent;
|
||||
}
|
||||
.col-md-5 {
|
||||
margin: 0 !important;
|
||||
width: 100%;
|
||||
}
|
||||
h2.card-header.text-center.mb-4, div.card-header:has(.mx-auto) {
|
||||
display: none;
|
||||
}
|
||||
span.glpi-logo.mb-4 {
|
||||
margin: 0 !important;
|
||||
}
|
||||
.btn-primary, .btn-outline-primary, .btn-ghost-primary {
|
||||
--tblr-btn-color: #71090e;
|
||||
--tblr-btn-color-interactive: #8d0a10;
|
||||
--tblr-btn-color-text: #1e293b;
|
||||
}
|
||||
.mb-3, .mb-4 {
|
||||
position: relative;
|
||||
}
|
||||
.mb-3:after {
|
||||
font-family: "Font Awesome 5 Free";
|
||||
font-weight: 900;
|
||||
content: "";
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
color: #6a696982;
|
||||
top: 12px;
|
||||
}
|
||||
.mb-4:before {
|
||||
font-family: "Font Awesome 5 Free";
|
||||
font-weight: 900;
|
||||
content: "";
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
color: #6a696982;
|
||||
top: 12px;
|
||||
}
|
||||
.col-md-5 {
|
||||
margin: 0 !important;
|
||||
width: 100%;
|
||||
max-width: 289px;
|
||||
}
|
||||
label.form-label {
|
||||
color: #a6abb1;
|
||||
}
|
||||
.card-body {
|
||||
padding: 0px !important;
|
||||
margin: auto;
|
||||
}
|
||||
.flex-fill.d-flex.flex-column.justify-content-center.py-4.mt-4 {
|
||||
width: 383px;
|
||||
background: #ffffff;
|
||||
border-radius: 30px;
|
||||
margin: 114px auto !important;
|
||||
outline-offset: 0;
|
||||
box-shadow: 0px 6px 13px 1px #00000047;
|
||||
height: 100% !important;
|
||||
}
|
||||
button.btn.btn-primary.w-100 {
|
||||
color: #ffffff;
|
||||
padding: 11px;
|
||||
border-radius: 30px;
|
||||
border: 1px solid #fff;
|
||||
background: #000000;
|
||||
}
|
||||
a {
|
||||
color: #000000 !important;
|
||||
text-decoration: underline;
|
||||
}
|
||||
body .form-control {
|
||||
display: block;
|
||||
width: 100%;
|
||||
min-width: 250px;
|
||||
padding: 0.7375rem 0.75rem;
|
||||
font-size: 0.875rem;
|
||||
font-weight: 400;
|
||||
line-height: 1.4285714286;
|
||||
color: inherit;
|
||||
background-color: #fdfdfd;
|
||||
background-clip: padding-box;
|
||||
border: 0;
|
||||
appearance: none;
|
||||
border-radius: 34px;
|
||||
transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
|
||||
background: #fff;
|
||||
border-radius: 0;
|
||||
border-bottom: 1px solid;
|
||||
}
|
||||
label.form-label {
|
||||
display: none;
|
||||
color: #fff;
|
||||
}
|
||||
span.form-label-description {
|
||||
margin-top: 10px;
|
||||
margin-bottom: 10px;
|
||||
text-align: left;
|
||||
width: 100%;
|
||||
display: block;
|
||||
}
|
||||
.card-body {
|
||||
margin: 0 auto;
|
||||
width: 350px;
|
||||
max-width: 100%;
|
||||
}
|
||||
.col-auto.offset-md-1.p-2.text-center {
|
||||
display: none;
|
||||
}
|
||||
.form-control:focus {
|
||||
color: inherit;
|
||||
background-color: #fdfdfd;
|
||||
border-color: #013453;
|
||||
outline: 0;
|
||||
box-shadow: 0 0 0 0.25rem #5e5e5e3b;
|
||||
}
|
||||
BIN
public/themes/cloud/login.logo.png
Normal file
|
After Width: | Height: | Size: 2.9 KiB |
BIN
public/themes/cloud/login.preview.jpg
Normal file
|
After Width: | Height: | Size: 126 KiB |
140
public/themes/cloud/login.scss
Normal file
|
|
@ -0,0 +1,140 @@
|
|||
/*Tema 3 - Cloud*/
|
||||
|
||||
$btn-background-color: #000000 !default;
|
||||
$btn-foreground-color: #ffffff !default;
|
||||
|
||||
body .card {
|
||||
border: 0;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.col-md-5 {
|
||||
margin: 0 !important;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
h2.card-header.text-center.mb-4,
|
||||
div.card-header:has(.mx-auto) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
span.glpi-logo.mb-4 {
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
.btn-primary,
|
||||
.btn-outline-primary,
|
||||
.btn-ghost-primary {
|
||||
--tblr-btn-color: #71090e;
|
||||
--tblr-btn-color-interactive: #8d0a10;
|
||||
--tblr-btn-color-text: #1e293b;
|
||||
}
|
||||
|
||||
.mb-3,
|
||||
.mb-4 {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.mb-3:after {
|
||||
font-family: "Font Awesome 5 Free";
|
||||
font-weight: 900;
|
||||
content: "\f007";
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
color: #6a696982;
|
||||
top: 12px;
|
||||
}
|
||||
|
||||
.mb-4:before {
|
||||
font-family: "Font Awesome 5 Free";
|
||||
font-weight: 900;
|
||||
content: "\f023";
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
color: #6a696982;
|
||||
top: 12px;
|
||||
}
|
||||
|
||||
.col-md-5 {
|
||||
margin: 0 !important;
|
||||
width: 100%;
|
||||
max-width: 289px;
|
||||
}
|
||||
|
||||
label.form-label {
|
||||
color: #a6abb1;
|
||||
}
|
||||
|
||||
.card-body {
|
||||
padding: 0px !important;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.flex-fill.d-flex.flex-column.justify-content-center.py-4.mt-4 {
|
||||
width: 383px;
|
||||
background: #ffffff;
|
||||
border-radius: 30px;
|
||||
margin: 114px auto !important;
|
||||
outline-offset: 0;
|
||||
box-shadow: 0px 6px 13px 1px #00000047;
|
||||
height: 100% !important;
|
||||
}
|
||||
|
||||
button.btn.btn-primary.w-100 {
|
||||
color: $btn-foreground-color;
|
||||
padding: 11px;
|
||||
border-radius: 30px;
|
||||
border: 1px solid #fff;
|
||||
background: $btn-background-color;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #000000 !important;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
body .form-control {
|
||||
display: block;
|
||||
width: 100%;
|
||||
min-width: 250px;
|
||||
padding: 0.7375rem 0.75rem;
|
||||
font-size: 0.875rem;
|
||||
font-weight: 400;
|
||||
line-height: 1.4285714286;
|
||||
color: inherit;
|
||||
background-color: #fdfdfd;
|
||||
background-clip: padding-box;
|
||||
border: 0;
|
||||
appearance: none;
|
||||
border-radius: 34px;
|
||||
transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
|
||||
background: #fff;
|
||||
border-radius: 0;
|
||||
border-bottom: 1px solid;
|
||||
}
|
||||
label.form-label {
|
||||
display: none;
|
||||
color: #fff;
|
||||
}
|
||||
span.form-label-description {
|
||||
margin-top: 10px;
|
||||
margin-bottom: 10px;
|
||||
text-align: left;
|
||||
width: 100%;
|
||||
display: block;
|
||||
}
|
||||
.card-body {
|
||||
margin: 0 auto;
|
||||
width: 350px;
|
||||
max-width: 100%;
|
||||
}
|
||||
.col-auto.offset-md-1.p-2.text-center {
|
||||
display: none;
|
||||
}
|
||||
.form-control:focus {
|
||||
color: inherit;
|
||||
background-color: #fdfdfd;
|
||||
border-color: #013453;
|
||||
outline: 0;
|
||||
box-shadow: 0 0 0 0.25rem #5e5e5e3b;
|
||||
}
|
||||
18
public/themes/cloud/theme.json
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"name": "Cloud",
|
||||
"description": "Cloud Theme",
|
||||
"variables": {
|
||||
"btn-background-color": {
|
||||
"name": "Cor de fundo dos Botões",
|
||||
"default": "#000000"
|
||||
},
|
||||
"btn-foreground-color": {
|
||||
"name": "Cor do texto dos Botões",
|
||||
"default": "#ffffff"
|
||||
},
|
||||
"card-background-color": {
|
||||
"name": "Cor do cartão",
|
||||
"default": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
public/themes/desktop/login.background.jpg
Normal file
|
After Width: | Height: | Size: 145 KiB |
125
public/themes/desktop/login.css
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
@charset "UTF-8";
|
||||
/*Tema 1 - Desktop*/
|
||||
body .card {
|
||||
border: 0;
|
||||
background: transparent;
|
||||
}
|
||||
.col-md-5 {
|
||||
margin: 0 !important;
|
||||
width: 100%;
|
||||
}
|
||||
h2.card-header.text-center.mb-4, div.card-header:has(.mx-auto) {
|
||||
display: none;
|
||||
}
|
||||
span.glpi-logo.mb-4 {
|
||||
margin: 0 !important;
|
||||
}
|
||||
.btn-primary, .btn-outline-primary, .btn-ghost-primary {
|
||||
--tblr-btn-color: #71090e;
|
||||
--tblr-btn-color-interactive: #8d0a10;
|
||||
--tblr-btn-color-text: #1e293b;
|
||||
}
|
||||
.mb-3, .mb-4 {
|
||||
position: relative;
|
||||
}
|
||||
.mb-3:after {
|
||||
font-family: "Font Awesome 5 Free";
|
||||
font-weight: 900;
|
||||
content: "";
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
color: #6a696982;
|
||||
top: 12px;
|
||||
}
|
||||
.mb-4:before {
|
||||
font-family: "Font Awesome 5 Free";
|
||||
font-weight: 900;
|
||||
content: "";
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
color: #6a696982;
|
||||
top: 12px;
|
||||
}
|
||||
.col-md-5 {
|
||||
margin: 0 !important;
|
||||
width: 100%;
|
||||
max-width: 289px;
|
||||
}
|
||||
label.form-label {
|
||||
color: #a6abb1;
|
||||
}
|
||||
.card-body {
|
||||
padding: 0px !important;
|
||||
margin: auto;
|
||||
}
|
||||
.flex-fill.d-flex.flex-column.justify-content-center.py-4.mt-4 {
|
||||
width: 50%;
|
||||
background: #ffffffc9;
|
||||
border-radius: 30px;
|
||||
margin: 0;
|
||||
outline-offset: 0;
|
||||
box-shadow: 0px 6px 13px 1px #00000047;
|
||||
left: 0;
|
||||
height: 100% !important;
|
||||
top: -32px;
|
||||
border-radius: 0;
|
||||
position: absolute;
|
||||
padding-top: 130px !important;
|
||||
padding-bottom: 110px !important;
|
||||
}
|
||||
button.btn.btn-primary.w-100 {
|
||||
color: #ffffff;
|
||||
padding: 11px;
|
||||
border-radius: 30px;
|
||||
border: 1px solid #fff;
|
||||
background: #000000;
|
||||
}
|
||||
a {
|
||||
color: #000000 !important;
|
||||
text-decoration: underline;
|
||||
}
|
||||
body .form-control {
|
||||
display: block;
|
||||
width: 100%;
|
||||
min-width: 250px;
|
||||
padding: 0.7375rem 0.75rem;
|
||||
font-size: 0.875rem;
|
||||
font-weight: 400;
|
||||
line-height: 1.4285714286;
|
||||
color: inherit;
|
||||
background-color: #fdfdfd;
|
||||
background-clip: padding-box;
|
||||
border: 0;
|
||||
appearance: none;
|
||||
border-radius: 34px;
|
||||
transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
|
||||
background: #fff;
|
||||
border-radius: 0;
|
||||
border-bottom: 1px solid;
|
||||
}
|
||||
label.form-label {
|
||||
display: none;
|
||||
color: #fff;
|
||||
}
|
||||
span.form-label-description {
|
||||
margin-top: 10px;
|
||||
margin-bottom: 10px;
|
||||
text-align: left;
|
||||
width: 100%;
|
||||
display: block;
|
||||
}
|
||||
.card-body {
|
||||
margin: 0 auto;
|
||||
width: 350px;
|
||||
max-width: 100%;
|
||||
}
|
||||
.col-auto.offset-md-1.p-2.text-center {
|
||||
display: none;
|
||||
}
|
||||
.form-control:focus {
|
||||
color: inherit;
|
||||
background-color: #fdfdfd;
|
||||
border-color: #013453;
|
||||
outline: 0;
|
||||
box-shadow: 0 0 0 0.25rem #5e5e5e3b;
|
||||
}
|
||||
BIN
public/themes/desktop/login.logo.png
Normal file
|
After Width: | Height: | Size: 2.9 KiB |
BIN
public/themes/desktop/login.preview.jpg
Normal file
|
After Width: | Height: | Size: 105 KiB |
147
public/themes/desktop/login.scss
Normal file
|
|
@ -0,0 +1,147 @@
|
|||
/*Tema 1 - Desktop*/
|
||||
|
||||
$btn-background-color: #000000 !default;
|
||||
$btn-foreground-color: #ffffff !default;
|
||||
|
||||
body .card {
|
||||
border: 0;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.col-md-5 {
|
||||
margin: 0 !important;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
h2.card-header.text-center.mb-4,
|
||||
div.card-header:has(.mx-auto) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
span.glpi-logo.mb-4 {
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
.btn-primary,
|
||||
.btn-outline-primary,
|
||||
.btn-ghost-primary {
|
||||
--tblr-btn-color: #71090e;
|
||||
--tblr-btn-color-interactive: #8d0a10;
|
||||
--tblr-btn-color-text: #1e293b;
|
||||
}
|
||||
|
||||
.mb-3,
|
||||
.mb-4 {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.mb-3:after {
|
||||
font-family: "Font Awesome 5 Free";
|
||||
font-weight: 900;
|
||||
content: "\f007";
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
color: #6a696982;
|
||||
top: 12px;
|
||||
}
|
||||
|
||||
.mb-4:before {
|
||||
font-family: "Font Awesome 5 Free";
|
||||
font-weight: 900;
|
||||
content: "\f023";
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
color: #6a696982;
|
||||
top: 12px;
|
||||
}
|
||||
|
||||
.col-md-5 {
|
||||
margin: 0 !important;
|
||||
width: 100%;
|
||||
max-width: 289px;
|
||||
}
|
||||
|
||||
label.form-label {
|
||||
color: #a6abb1;
|
||||
}
|
||||
|
||||
.card-body {
|
||||
padding: 0px !important;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.flex-fill.d-flex.flex-column.justify-content-center.py-4.mt-4 {
|
||||
width: 50%;
|
||||
background: #ffffffc9;
|
||||
border-radius: 30px;
|
||||
margin: 0;
|
||||
outline-offset: 0;
|
||||
box-shadow: 0px 6px 13px 1px #00000047;
|
||||
left: 0;
|
||||
height: 100% !important;
|
||||
top: -32px;
|
||||
border-radius: 0;
|
||||
position: absolute;
|
||||
padding-top: 130px !important;
|
||||
padding-bottom: 110px !important;
|
||||
}
|
||||
|
||||
button.btn.btn-primary.w-100 {
|
||||
color: $btn-foreground-color;
|
||||
padding: 11px;
|
||||
border-radius: 30px;
|
||||
border: 1px solid #fff;
|
||||
background: $btn-background-color;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #000000 !important;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
body .form-control {
|
||||
display: block;
|
||||
width: 100%;
|
||||
min-width: 250px;
|
||||
padding: 0.7375rem 0.75rem;
|
||||
font-size: 0.875rem;
|
||||
font-weight: 400;
|
||||
line-height: 1.4285714286;
|
||||
color: inherit;
|
||||
background-color: #fdfdfd;
|
||||
background-clip: padding-box;
|
||||
border: 0;
|
||||
appearance: none;
|
||||
border-radius: 34px;
|
||||
transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
|
||||
background: #fff;
|
||||
border-radius: 0;
|
||||
border-bottom: 1px solid;
|
||||
}
|
||||
|
||||
label.form-label {
|
||||
display: none;
|
||||
color: #fff;
|
||||
}
|
||||
span.form-label-description {
|
||||
margin-top: 10px;
|
||||
margin-bottom: 10px;
|
||||
text-align: left;
|
||||
width: 100%;
|
||||
display: block;
|
||||
}
|
||||
.card-body {
|
||||
margin: 0 auto;
|
||||
width: 350px;
|
||||
max-width: 100%;
|
||||
}
|
||||
.col-auto.offset-md-1.p-2.text-center {
|
||||
display: none;
|
||||
}
|
||||
.form-control:focus {
|
||||
color: inherit;
|
||||
background-color: #fdfdfd;
|
||||
border-color: #013453;
|
||||
outline: 0;
|
||||
box-shadow: 0 0 0 0.25rem #5e5e5e3b;
|
||||
}
|
||||
18
public/themes/desktop/theme.json
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"name": "Desktop",
|
||||
"description": "Desktop Theme",
|
||||
"variables": {
|
||||
"btn-background-color": {
|
||||
"name": "Cor de fundo dos Botões",
|
||||
"default": "#000000"
|
||||
},
|
||||
"btn-foreground-color": {
|
||||
"name": "Cor do texto dos Botões",
|
||||
"default": "#ffffff"
|
||||
},
|
||||
"card-background-color": {
|
||||
"name": "Cor do cartão",
|
||||
"default": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
public/themes/light/login.background.jpg
Normal file
|
After Width: | Height: | Size: 113 KiB |
117
public/themes/light/login.css
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
@charset "UTF-8";
|
||||
/*Tema 8 - Light*/
|
||||
body .card {
|
||||
border: 0;
|
||||
background: transparent;
|
||||
}
|
||||
.col-md-5 {
|
||||
margin: 0 !important;
|
||||
width: 100%;
|
||||
}
|
||||
h2.card-header.text-center.mb-4, div.card-header:has(.mx-auto) {
|
||||
display: none;
|
||||
}
|
||||
span.glpi-logo.mb-4 {
|
||||
margin: 0 !important;
|
||||
}
|
||||
.btn-primary, .btn-outline-primary, .btn-ghost-primary {
|
||||
--tblr-btn-color: #71090e;
|
||||
--tblr-btn-color-interactive: #8d0a10;
|
||||
--tblr-btn-color-text: #1e293b;
|
||||
}
|
||||
.mb-3, .mb-4 {
|
||||
position: relative;
|
||||
}
|
||||
.mb-3:after {
|
||||
font-family: "Font Awesome 5 Free";
|
||||
font-weight: 900;
|
||||
content: "";
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
color: #013453;
|
||||
top: 12px;
|
||||
}
|
||||
.mb-4:before {
|
||||
font-family: "Font Awesome 5 Free";
|
||||
font-weight: 900;
|
||||
content: "";
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
color: #013453;
|
||||
top: 12px;
|
||||
}
|
||||
.col-md-5 {
|
||||
margin: 0 !important;
|
||||
width: 100%;
|
||||
max-width: 289px;
|
||||
}
|
||||
button.btn.btn-primary.w-100 {
|
||||
color: #ffffff;
|
||||
padding: 11px;
|
||||
border-radius: 30px;
|
||||
background: #013453;
|
||||
}
|
||||
label.form-label {
|
||||
color: #023454;
|
||||
}
|
||||
.card-body {
|
||||
padding: 0px !important;
|
||||
margin: auto;
|
||||
}
|
||||
.flex-fill.d-flex.flex-column.justify-content-center.py-4.mt-4 {
|
||||
background: transparent;
|
||||
border-radius: 30px;
|
||||
margin: 0;
|
||||
outline-offset: 0;
|
||||
height: 100% !important;
|
||||
border-radius: 0;
|
||||
padding-bottom: 10px !important;
|
||||
width: 320px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
a {
|
||||
color: #000000 !important;
|
||||
text-decoration: underline;
|
||||
}
|
||||
body .form-control {
|
||||
display: block;
|
||||
width: 100%;
|
||||
min-width: 250px;
|
||||
padding: 0.7375rem 0.75rem;
|
||||
font-size: 0.875rem;
|
||||
font-weight: 400;
|
||||
line-height: 1.4285714286;
|
||||
color: inherit;
|
||||
background-color: #fdfdfd;
|
||||
background-clip: padding-box;
|
||||
border: 0;
|
||||
appearance: none;
|
||||
border-radius: 34px;
|
||||
transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
|
||||
background: #fff;
|
||||
border-radius: 0;
|
||||
border-bottom: 1px solid;
|
||||
}
|
||||
label.form-label {
|
||||
display: none;
|
||||
color: #fff;
|
||||
}
|
||||
span.form-label-description {
|
||||
margin-top: 10px;
|
||||
margin-bottom: 10px;
|
||||
text-align: left;
|
||||
width: 100%;
|
||||
display: block;
|
||||
}
|
||||
.card-body {
|
||||
margin: 0 auto;
|
||||
width: 350px;
|
||||
max-width: 100%;
|
||||
}
|
||||
.form-control:focus {
|
||||
color: inherit;
|
||||
background-color: #fdfdfd;
|
||||
border-color: #013453;
|
||||
outline: 0;
|
||||
box-shadow: 0 0 0 0.25rem #0133533b;
|
||||
}
|
||||
BIN
public/themes/light/login.logo.png
Normal file
|
After Width: | Height: | Size: 2.6 KiB |
BIN
public/themes/light/login.preview.jpg
Normal file
|
After Width: | Height: | Size: 93 KiB |
138
public/themes/light/login.scss
Normal file
|
|
@ -0,0 +1,138 @@
|
|||
/*Tema 8 - Light*/
|
||||
|
||||
$btn-background-color: #013453 !default;
|
||||
$btn-foreground-color: #ffffff !default;
|
||||
|
||||
body .card {
|
||||
border: 0;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.col-md-5 {
|
||||
margin: 0 !important;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
h2.card-header.text-center.mb-4,
|
||||
div.card-header:has(.mx-auto) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
span.glpi-logo.mb-4 {
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
.btn-primary,
|
||||
.btn-outline-primary,
|
||||
.btn-ghost-primary {
|
||||
--tblr-btn-color: #71090e;
|
||||
--tblr-btn-color-interactive: #8d0a10;
|
||||
--tblr-btn-color-text: #1e293b;
|
||||
}
|
||||
|
||||
.mb-3,
|
||||
.mb-4 {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.mb-3:after {
|
||||
font-family: "Font Awesome 5 Free";
|
||||
font-weight: 900;
|
||||
content: "\f007";
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
color: #013453;
|
||||
top: 12px;
|
||||
}
|
||||
|
||||
.mb-4:before {
|
||||
font-family: "Font Awesome 5 Free";
|
||||
font-weight: 900;
|
||||
content: "\f023";
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
color: #013453;
|
||||
top: 12px;
|
||||
}
|
||||
|
||||
.col-md-5 {
|
||||
margin: 0 !important;
|
||||
width: 100%;
|
||||
max-width: 289px;
|
||||
}
|
||||
|
||||
button.btn.btn-primary.w-100 {
|
||||
color: $btn-foreground-color;
|
||||
padding: 11px;
|
||||
border-radius: 30px;
|
||||
background: $btn-background-color;
|
||||
}
|
||||
|
||||
label.form-label {
|
||||
color: #023454;
|
||||
}
|
||||
|
||||
.card-body {
|
||||
padding: 0px !important;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.flex-fill.d-flex.flex-column.justify-content-center.py-4.mt-4 {
|
||||
background: transparent;
|
||||
border-radius: 30px;
|
||||
margin: 0;
|
||||
outline-offset: 0;
|
||||
height: 100% !important;
|
||||
border-radius: 0;
|
||||
padding-bottom: 10px !important;
|
||||
width: 320px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #000000 !important;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
body .form-control {
|
||||
display: block;
|
||||
width: 100%;
|
||||
min-width: 250px;
|
||||
padding: 0.7375rem 0.75rem;
|
||||
font-size: 0.875rem;
|
||||
font-weight: 400;
|
||||
line-height: 1.4285714286;
|
||||
color: inherit;
|
||||
background-color: #fdfdfd;
|
||||
background-clip: padding-box;
|
||||
border: 0;
|
||||
appearance: none;
|
||||
border-radius: 34px;
|
||||
transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
|
||||
background: #fff;
|
||||
border-radius: 0;
|
||||
border-bottom: 1px solid;
|
||||
}
|
||||
label.form-label {
|
||||
display: none;
|
||||
color: #fff;
|
||||
}
|
||||
span.form-label-description {
|
||||
margin-top: 10px;
|
||||
margin-bottom: 10px;
|
||||
text-align: left;
|
||||
width: 100%;
|
||||
display: block;
|
||||
}
|
||||
.card-body {
|
||||
margin: 0 auto;
|
||||
width: 350px;
|
||||
max-width: 100%;
|
||||
}
|
||||
.form-control:focus {
|
||||
color: inherit;
|
||||
background-color: #fdfdfd;
|
||||
border-color: #013453;
|
||||
outline: 0;
|
||||
box-shadow: 0 0 0 0.25rem #0133533b;
|
||||
}
|
||||
18
public/themes/light/theme.json
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"name": "Light",
|
||||
"description": "Light Theme",
|
||||
"variables": {
|
||||
"btn-background-color": {
|
||||
"name": "Cor de fundo dos Botões",
|
||||
"default": "#013453"
|
||||
},
|
||||
"btn-foreground-color": {
|
||||
"name": "Cor do texto dos Botões",
|
||||
"default": "#ffffff"
|
||||
},
|
||||
"card-background-color": {
|
||||
"name": "Cor do cartão",
|
||||
"default": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
public/themes/neon/login.background.jpg
Normal file
|
After Width: | Height: | Size: 303 KiB |
122
public/themes/neon/login.css
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
@charset "UTF-8";
|
||||
/*Tema 5 - Neon*/
|
||||
body .card {
|
||||
border: 0;
|
||||
background: transparent;
|
||||
}
|
||||
.col-md-5 {
|
||||
margin: 0 !important;
|
||||
width: 100%;
|
||||
}
|
||||
h2.card-header.text-center.mb-4, div.card-header:has(.mx-auto) {
|
||||
display: none;
|
||||
}
|
||||
span.glpi-logo.mb-4 {
|
||||
margin: 0 !important;
|
||||
}
|
||||
.btn-primary, .btn-outline-primary, .btn-ghost-primary {
|
||||
--tblr-btn-color: #71090e;
|
||||
--tblr-btn-color-interactive: #8d0a10;
|
||||
--tblr-btn-color-text: #1e293b;
|
||||
}
|
||||
.mb-3, .mb-4 {
|
||||
position: relative;
|
||||
}
|
||||
.mb-3:after {
|
||||
font-family: "Font Awesome 5 Free";
|
||||
font-weight: 900;
|
||||
content: "";
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
color: #fff;
|
||||
top: 12px;
|
||||
}
|
||||
.mb-4:before {
|
||||
font-family: "Font Awesome 5 Free";
|
||||
font-weight: 900;
|
||||
content: "";
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
color: #fff;
|
||||
top: 12px;
|
||||
}
|
||||
.col-md-5 {
|
||||
margin: 0 !important;
|
||||
width: 100%;
|
||||
max-width: 289px;
|
||||
}
|
||||
label.form-label {
|
||||
color: #fff;
|
||||
}
|
||||
.card-body {
|
||||
padding: 0px !important;
|
||||
margin: auto;
|
||||
}
|
||||
.flex-fill.d-flex.flex-column.justify-content-center.py-4.mt-4 {
|
||||
width: 50%;
|
||||
background: transparent;
|
||||
border-radius: 30px;
|
||||
margin: 0;
|
||||
outline-offset: 0;
|
||||
box-shadow: 0px 6px 13px 1px #00000047;
|
||||
left: 0;
|
||||
height: 100% !important;
|
||||
top: -32px;
|
||||
border-radius: 0;
|
||||
position: absolute;
|
||||
padding-top: 130px !important;
|
||||
padding-bottom: 110px !important;
|
||||
}
|
||||
button.btn.btn-primary.w-100 {
|
||||
color: #ffffff;
|
||||
padding: 11px;
|
||||
border-radius: 30px;
|
||||
border: 1px solid #fff;
|
||||
background: #000000;
|
||||
}
|
||||
a {
|
||||
color: #ffffff !important;
|
||||
text-decoration: underline;
|
||||
}
|
||||
body .form-control {
|
||||
display: block;
|
||||
width: 100%;
|
||||
min-width: 250px;
|
||||
padding: 0.7375rem 0.75rem;
|
||||
font-size: 0.875rem;
|
||||
font-weight: 400;
|
||||
line-height: 1.4285714286;
|
||||
color: inherit;
|
||||
border: 0;
|
||||
appearance: none;
|
||||
transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
|
||||
background: #ffffff05;
|
||||
border-radius: 0;
|
||||
border-bottom: 1px solid #fff;
|
||||
}
|
||||
label.form-label {
|
||||
display: none;
|
||||
color: #fff;
|
||||
}
|
||||
span.form-label-description {
|
||||
margin-top: 10px;
|
||||
margin-bottom: 10px;
|
||||
text-align: left;
|
||||
width: 100%;
|
||||
display: block;
|
||||
}
|
||||
.card-body {
|
||||
margin: 0 auto;
|
||||
width: 350px;
|
||||
max-width: 100%;
|
||||
}
|
||||
.col-auto.offset-md-1.p-2.text-center {
|
||||
display: none;
|
||||
}
|
||||
.form-control:focus {
|
||||
color: inherit;
|
||||
background-color: #fdfdfd;
|
||||
border-color: #013453;
|
||||
outline: 0;
|
||||
box-shadow: 0 0 0 0.25rem #5e5e5e3b;
|
||||
}
|
||||
BIN
public/themes/neon/login.logo.png
Normal file
|
After Width: | Height: | Size: 3.5 KiB |
BIN
public/themes/neon/login.preview.jpg
Normal file
|
After Width: | Height: | Size: 159 KiB |
143
public/themes/neon/login.scss
Normal file
|
|
@ -0,0 +1,143 @@
|
|||
/*Tema 5 - Neon*/
|
||||
|
||||
$btn-background-color: #000000 !default;
|
||||
$btn-foreground-color: #ffffff !default;
|
||||
|
||||
body .card {
|
||||
border: 0;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.col-md-5 {
|
||||
margin: 0 !important;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
h2.card-header.text-center.mb-4,
|
||||
div.card-header:has(.mx-auto) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
span.glpi-logo.mb-4 {
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
.btn-primary,
|
||||
.btn-outline-primary,
|
||||
.btn-ghost-primary {
|
||||
--tblr-btn-color: #71090e;
|
||||
--tblr-btn-color-interactive: #8d0a10;
|
||||
--tblr-btn-color-text: #1e293b;
|
||||
}
|
||||
|
||||
.mb-3,
|
||||
.mb-4 {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.mb-3:after {
|
||||
font-family: "Font Awesome 5 Free";
|
||||
font-weight: 900;
|
||||
content: "\f007";
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
color: #fff;
|
||||
top: 12px;
|
||||
}
|
||||
|
||||
.mb-4:before {
|
||||
font-family: "Font Awesome 5 Free";
|
||||
font-weight: 900;
|
||||
content: "\f023";
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
color: #fff;
|
||||
top: 12px;
|
||||
}
|
||||
|
||||
.col-md-5 {
|
||||
margin: 0 !important;
|
||||
width: 100%;
|
||||
max-width: 289px;
|
||||
}
|
||||
|
||||
label.form-label {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.card-body {
|
||||
padding: 0px !important;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.flex-fill.d-flex.flex-column.justify-content-center.py-4.mt-4 {
|
||||
width: 50%;
|
||||
background: transparent;
|
||||
border-radius: 30px;
|
||||
margin: 0;
|
||||
outline-offset: 0;
|
||||
box-shadow: 0px 6px 13px 1px #00000047;
|
||||
left: 0;
|
||||
height: 100% !important;
|
||||
top: -32px;
|
||||
border-radius: 0;
|
||||
position: absolute;
|
||||
padding-top: 130px !important;
|
||||
padding-bottom: 110px !important;
|
||||
}
|
||||
|
||||
button.btn.btn-primary.w-100 {
|
||||
color: $btn-foreground-color;
|
||||
padding: 11px;
|
||||
border-radius: 30px;
|
||||
border: 1px solid #fff;
|
||||
background: $btn-background-color;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #ffffff !important;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
body .form-control {
|
||||
display: block;
|
||||
width: 100%;
|
||||
min-width: 250px;
|
||||
padding: 0.7375rem 0.75rem;
|
||||
font-size: 0.875rem;
|
||||
font-weight: 400;
|
||||
line-height: 1.4285714286;
|
||||
color: inherit;
|
||||
border: 0;
|
||||
appearance: none;
|
||||
transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
|
||||
background: #ffffff05;
|
||||
border-radius: 0;
|
||||
border-bottom: 1px solid #fff;
|
||||
}
|
||||
label.form-label {
|
||||
display: none;
|
||||
color: #fff;
|
||||
}
|
||||
span.form-label-description {
|
||||
margin-top: 10px;
|
||||
margin-bottom: 10px;
|
||||
text-align: left;
|
||||
width: 100%;
|
||||
display: block;
|
||||
}
|
||||
.card-body {
|
||||
margin: 0 auto;
|
||||
width: 350px;
|
||||
max-width: 100%;
|
||||
}
|
||||
.col-auto.offset-md-1.p-2.text-center {
|
||||
display: none;
|
||||
}
|
||||
.form-control:focus {
|
||||
color: inherit;
|
||||
background-color: #fdfdfd;
|
||||
border-color: #013453;
|
||||
outline: 0;
|
||||
box-shadow: 0 0 0 0.25rem #5e5e5e3b;
|
||||
}
|
||||
18
public/themes/neon/theme.json
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"name": "Neon",
|
||||
"description": "Neon Theme",
|
||||
"variables": {
|
||||
"btn-background-color": {
|
||||
"name": "Cor de fundo dos Botões",
|
||||
"default": "#000000"
|
||||
},
|
||||
"btn-foreground-color": {
|
||||
"name": "Cor do texto dos Botões",
|
||||
"default": "#ffffff"
|
||||
},
|
||||
"card-background-color": {
|
||||
"name": "Cor do cartão",
|
||||
"default": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
public/themes/night/login.background.jpg
Normal file
|
After Width: | Height: | Size: 147 KiB |
127
public/themes/night/login.css
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
@charset "UTF-8";
|
||||
/*Tema 4 - Night*/
|
||||
body .card {
|
||||
border: 0;
|
||||
background: transparent;
|
||||
}
|
||||
.col-md-5 {
|
||||
margin: 0 !important;
|
||||
width: 100%;
|
||||
}
|
||||
h2.card-header.text-center.mb-4, div.card-header:has(.mx-auto) {
|
||||
display: none;
|
||||
}
|
||||
span.glpi-logo.mb-4 {
|
||||
margin: 0 !important;
|
||||
}
|
||||
.btn-primary, .btn-outline-primary, .btn-ghost-primary {
|
||||
--tblr-btn-color: #71090e;
|
||||
--tblr-btn-color-interactive: #8d0a10;
|
||||
--tblr-btn-color-text: #1e293b;
|
||||
}
|
||||
.mb-3, .mb-4 {
|
||||
position: relative;
|
||||
}
|
||||
.mb-3:after {
|
||||
font-family: "Font Awesome 5 Free";
|
||||
font-weight: 900;
|
||||
content: "";
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
color: #fff;
|
||||
top: 12px;
|
||||
}
|
||||
.mb-4:before {
|
||||
font-family: "Font Awesome 5 Free";
|
||||
font-weight: 900;
|
||||
content: "";
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
color: #fff;
|
||||
top: 12px;
|
||||
}
|
||||
.col-md-5 {
|
||||
margin: 0 !important;
|
||||
width: 100%;
|
||||
max-width: 289px;
|
||||
}
|
||||
label.form-label {
|
||||
color: #fff;
|
||||
}
|
||||
.card-body {
|
||||
padding: 0px !important;
|
||||
margin: auto;
|
||||
}
|
||||
.flex-fill.d-flex.flex-column.justify-content-center.py-4.mt-4 {
|
||||
width: 50%;
|
||||
background: transparent;
|
||||
border-radius: 30px;
|
||||
margin: 0;
|
||||
outline-offset: 0;
|
||||
box-shadow: 0px 6px 13px 1px #00000047;
|
||||
left: 0;
|
||||
height: 100% !important;
|
||||
top: -32px;
|
||||
border-radius: 0;
|
||||
position: absolute;
|
||||
padding-top: 130px !important;
|
||||
padding-bottom: 110px !important;
|
||||
background: rgba(255, 255, 255, 0.04);
|
||||
box-shadow: 0 4px 30px rgba(0, 0, 0, 0.1);
|
||||
backdrop-filter: blur(5px);
|
||||
-webkit-backdrop-filter: blur(5px);
|
||||
border: 1px solid rgba(255, 255, 255, 0.3);
|
||||
}
|
||||
button.btn.btn-primary.w-100 {
|
||||
color: #000000;
|
||||
padding: 11px;
|
||||
border-radius: 30px;
|
||||
border: 1px solid #fff;
|
||||
background: #ffffff;
|
||||
}
|
||||
a {
|
||||
color: #ffffff !important;
|
||||
text-decoration: underline;
|
||||
}
|
||||
body .form-control {
|
||||
display: block;
|
||||
width: 100%;
|
||||
min-width: 250px;
|
||||
padding: 0.7375rem 0.75rem;
|
||||
font-size: 0.875rem;
|
||||
font-weight: 400;
|
||||
line-height: 1.4285714286;
|
||||
color: inherit;
|
||||
border: 0;
|
||||
appearance: none;
|
||||
transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
|
||||
background: #ffffff05;
|
||||
border-radius: 0;
|
||||
border-bottom: 1px solid #fff;
|
||||
}
|
||||
label.form-label {
|
||||
display: none;
|
||||
color: #fff;
|
||||
}
|
||||
span.form-label-description {
|
||||
margin-top: 10px;
|
||||
margin-bottom: 10px;
|
||||
text-align: left;
|
||||
width: 100%;
|
||||
display: block;
|
||||
}
|
||||
.card-body {
|
||||
margin: 0 auto;
|
||||
width: 350px;
|
||||
max-width: 100%;
|
||||
}
|
||||
.col-auto.offset-md-1.p-2.text-center {
|
||||
display: none;
|
||||
}
|
||||
.form-control:focus {
|
||||
color: inherit;
|
||||
background-color: #fdfdfd;
|
||||
border-color: #013453;
|
||||
outline: 0;
|
||||
box-shadow: 0 0 0 0.25rem #5e5e5e3b;
|
||||
}
|
||||
BIN
public/themes/night/login.logo.png
Normal file
|
After Width: | Height: | Size: 3.5 KiB |
BIN
public/themes/night/login.preview.jpg
Normal file
|
After Width: | Height: | Size: 122 KiB |
151
public/themes/night/login.scss
Normal file
|
|
@ -0,0 +1,151 @@
|
|||
/*Tema 4 - Night*/
|
||||
|
||||
$btn-background-color: #ffffff !default;
|
||||
$btn-foreground-color: #000000 !default;
|
||||
|
||||
body .card {
|
||||
border: 0;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.col-md-5 {
|
||||
margin: 0 !important;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
h2.card-header.text-center.mb-4,
|
||||
div.card-header:has(.mx-auto) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
span.glpi-logo.mb-4 {
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
.btn-primary,
|
||||
.btn-outline-primary,
|
||||
.btn-ghost-primary {
|
||||
--tblr-btn-color: #71090e;
|
||||
--tblr-btn-color-interactive: #8d0a10;
|
||||
--tblr-btn-color-text: #1e293b;
|
||||
}
|
||||
|
||||
.mb-3,
|
||||
.mb-4 {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.mb-3:after {
|
||||
font-family: "Font Awesome 5 Free";
|
||||
font-weight: 900;
|
||||
content: "\f007";
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
color: #fff;
|
||||
top: 12px;
|
||||
}
|
||||
|
||||
.mb-4:before {
|
||||
font-family: "Font Awesome 5 Free";
|
||||
font-weight: 900;
|
||||
content: "\f023";
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
color: #fff;
|
||||
top: 12px;
|
||||
}
|
||||
|
||||
.col-md-5 {
|
||||
margin: 0 !important;
|
||||
width: 100%;
|
||||
max-width: 289px;
|
||||
}
|
||||
|
||||
label.form-label {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.card-body {
|
||||
padding: 0px !important;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.flex-fill.d-flex.flex-column.justify-content-center.py-4.mt-4 {
|
||||
width: 50%;
|
||||
background: transparent;
|
||||
border-radius: 30px;
|
||||
margin: 0;
|
||||
outline-offset: 0;
|
||||
box-shadow: 0px 6px 13px 1px #00000047;
|
||||
left: 0;
|
||||
height: 100% !important;
|
||||
top: -32px;
|
||||
border-radius: 0;
|
||||
position: absolute;
|
||||
padding-top: 130px !important;
|
||||
padding-bottom: 110px !important;
|
||||
background: rgb(255 255 255 / 4%);
|
||||
box-shadow: 0 4px 30px rgb(0 0 0 / 10%);
|
||||
backdrop-filter: blur(5px);
|
||||
-webkit-backdrop-filter: blur(5px);
|
||||
border: 1px solid rgba(255, 255, 255, 0.3);
|
||||
}
|
||||
|
||||
button.btn.btn-primary.w-100 {
|
||||
color: $btn-foreground-color;
|
||||
padding: 11px;
|
||||
border-radius: 30px;
|
||||
border: 1px solid #fff;
|
||||
background: $btn-background-color;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #ffffff !important;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
body .form-control {
|
||||
display: block;
|
||||
width: 100%;
|
||||
min-width: 250px;
|
||||
padding: 0.7375rem 0.75rem;
|
||||
font-size: 0.875rem;
|
||||
font-weight: 400;
|
||||
line-height: 1.4285714286;
|
||||
color: inherit;
|
||||
border: 0;
|
||||
appearance: none;
|
||||
transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
|
||||
background: #ffffff05;
|
||||
border-radius: 0;
|
||||
border-bottom: 1px solid #fff;
|
||||
}
|
||||
|
||||
label.form-label {
|
||||
display: none;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
span.form-label-description {
|
||||
margin-top: 10px;
|
||||
margin-bottom: 10px;
|
||||
text-align: left;
|
||||
width: 100%;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.card-body {
|
||||
margin: 0 auto;
|
||||
width: 350px;
|
||||
max-width: 100%;
|
||||
}
|
||||
.col-auto.offset-md-1.p-2.text-center {
|
||||
display: none;
|
||||
}
|
||||
.form-control:focus {
|
||||
color: inherit;
|
||||
background-color: #fdfdfd;
|
||||
border-color: #013453;
|
||||
outline: 0;
|
||||
box-shadow: 0 0 0 0.25rem #5e5e5e3b;
|
||||
}
|
||||
18
public/themes/night/theme.json
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"name": "Night",
|
||||
"description": "Night Theme",
|
||||
"variables": {
|
||||
"btn-background-color": {
|
||||
"name": "Cor de fundo dos Botões",
|
||||
"default": "#ffffff"
|
||||
},
|
||||
"btn-foreground-color": {
|
||||
"name": "Cor do texto dos Botões",
|
||||
"default": "#000000"
|
||||
},
|
||||
"card-background-color": {
|
||||
"name": "Cor do cartão",
|
||||
"default": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
112
public/themes/original/login.css
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
@charset "UTF-8";
|
||||
/*Tema 10 - Original*/
|
||||
body .card {
|
||||
border: 0;
|
||||
background: transparent;
|
||||
}
|
||||
.flex-fill.d-flex.flex-column.justify-content-center.py-4.mt-4 {
|
||||
width: 525px;
|
||||
background: transparent;
|
||||
margin: 0px auto !important;
|
||||
}
|
||||
.col-md-5 {
|
||||
margin: 0 !important;
|
||||
width: 100%;
|
||||
}
|
||||
h2.card-header.text-center.mb-4, div.card-header:has(.mx-auto) {
|
||||
display: none;
|
||||
}
|
||||
.flex-fill.d-flex.flex-column.justify-content-center.py-4.mt-4 {
|
||||
min-height: 711px;
|
||||
width: 525px;
|
||||
background: transparent;
|
||||
border-radius: 0;
|
||||
box-shadow: 0 4px 30pxrgba 0, 0, 0, 0.1;
|
||||
-webkit-backdrop-filter: blur(5px);
|
||||
border: 1pxsolidrgba 255, 255, 255, 0.3;
|
||||
margin: 0px auto !important;
|
||||
height: 100% !important;
|
||||
}
|
||||
span.glpi-logo.mb-4 {
|
||||
margin: 0 !important;
|
||||
}
|
||||
.btn-primary, .btn-outline-primary, .btn-ghost-primary {
|
||||
--tblr-btn-color: #71090e;
|
||||
--tblr-btn-color-interactive: #8d0a10;
|
||||
--tblr-btn-color-text: #1e293b;
|
||||
}
|
||||
.mb-3, .mb-4 {
|
||||
position: relative;
|
||||
}
|
||||
.mb-3:after {
|
||||
font-family: "Font Awesome 5 Free";
|
||||
font-weight: 900;
|
||||
content: "";
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
color: #6a696982;
|
||||
top: 12px;
|
||||
}
|
||||
.mb-4:before {
|
||||
font-family: "Font Awesome 5 Free";
|
||||
font-weight: 900;
|
||||
content: "";
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
color: #6a696982;
|
||||
top: 12px;
|
||||
}
|
||||
.col-md-5 {
|
||||
margin: 0 !important;
|
||||
width: 100%;
|
||||
max-width: 289px;
|
||||
}
|
||||
body .form-control {
|
||||
display: block;
|
||||
width: 100%;
|
||||
padding: 0.7375rem 0.75rem;
|
||||
font-size: 0.875rem;
|
||||
font-weight: 400;
|
||||
line-height: 1.4285714286;
|
||||
color: inherit;
|
||||
background-color: #fdfdfd;
|
||||
background-clip: padding-box;
|
||||
border: 1px solid #d9dbde;
|
||||
appearance: none;
|
||||
border-radius: 34px;
|
||||
transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
|
||||
}
|
||||
label.form-label {
|
||||
color: #fff;
|
||||
}
|
||||
a {
|
||||
color: #73fff9 !important;
|
||||
text-decoration: none;
|
||||
}
|
||||
body {
|
||||
background: #1c2e63;
|
||||
background: linear-gradient(360deg, #1c2e63 65%, #3a5693 65%);
|
||||
}
|
||||
button.btn.btn-primary.w-100 {
|
||||
background: #fdc95c;
|
||||
color: #1c2e63;
|
||||
padding: 11px;
|
||||
border-radius: 30px;
|
||||
border: 1px solid #fff;
|
||||
}
|
||||
label.form-label {
|
||||
display: none;
|
||||
color: #fff;
|
||||
}
|
||||
span.form-label-description {
|
||||
margin-top: 10px;
|
||||
margin-bottom: 10px;
|
||||
text-align: left;
|
||||
width: 100%;
|
||||
display: block;
|
||||
}
|
||||
.card-body {
|
||||
margin: 0 auto;
|
||||
width: 350px;
|
||||
max-width: 100%;
|
||||
}
|
||||
BIN
public/themes/original/login.logo.png
Normal file
|
After Width: | Height: | Size: 3.5 KiB |
BIN
public/themes/original/login.preview.jpg
Normal file
|
After Width: | Height: | Size: 29 KiB |
136
public/themes/original/login.scss
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
/*Tema 10 - Original*/
|
||||
|
||||
$btn-background-color: #fdc95c !default;
|
||||
$btn-foreground-color: #1c2e63 !default;
|
||||
|
||||
body .card {
|
||||
border: 0;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.flex-fill.d-flex.flex-column.justify-content-center.py-4.mt-4 {
|
||||
width: 525px;
|
||||
background: transparent;
|
||||
margin: 0px auto !important;
|
||||
}
|
||||
|
||||
.col-md-5 {
|
||||
margin: 0 !important;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
h2.card-header.text-center.mb-4,
|
||||
div.card-header:has(.mx-auto) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.flex-fill.d-flex.flex-column.justify-content-center.py-4.mt-4 {
|
||||
min-height: 711px;
|
||||
width: 525px;
|
||||
background: transparent;
|
||||
border-radius: 0;
|
||||
box-shadow: 0 4px 30pxrgba (0, 0, 0, 0.1);
|
||||
-webkit-backdrop-filter: blur(5px);
|
||||
border: 1pxsolidrgba (255, 255, 255, 0.3);
|
||||
margin: 0px auto !important;
|
||||
height: 100% !important;
|
||||
}
|
||||
|
||||
span.glpi-logo.mb-4 {
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
.btn-primary,
|
||||
.btn-outline-primary,
|
||||
.btn-ghost-primary {
|
||||
--tblr-btn-color: #71090e;
|
||||
--tblr-btn-color-interactive: #8d0a10;
|
||||
--tblr-btn-color-text: #1e293b;
|
||||
}
|
||||
|
||||
.mb-3,
|
||||
.mb-4 {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.mb-3:after {
|
||||
font-family: "Font Awesome 5 Free";
|
||||
font-weight: 900;
|
||||
content: "\f007";
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
color: #6a696982;
|
||||
top: 12px;
|
||||
}
|
||||
|
||||
.mb-4:before {
|
||||
font-family: "Font Awesome 5 Free";
|
||||
font-weight: 900;
|
||||
content: "\f023";
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
color: #6a696982;
|
||||
top: 12px;
|
||||
}
|
||||
|
||||
.col-md-5 {
|
||||
margin: 0 !important;
|
||||
width: 100%;
|
||||
max-width: 289px;
|
||||
}
|
||||
|
||||
body .form-control {
|
||||
display: block;
|
||||
width: 100%;
|
||||
padding: 0.7375rem 0.75rem;
|
||||
font-size: 0.875rem;
|
||||
font-weight: 400;
|
||||
line-height: 1.4285714286;
|
||||
color: inherit;
|
||||
background-color: #fdfdfd;
|
||||
background-clip: padding-box;
|
||||
border: 1px solid #d9dbde;
|
||||
appearance: none;
|
||||
border-radius: 34px;
|
||||
transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
|
||||
}
|
||||
|
||||
label.form-label {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #73fff9 !important;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
body {
|
||||
background: #1c2e63;
|
||||
background: linear-gradient(360deg, #1c2e63 65%, #3a5693 65%);
|
||||
}
|
||||
|
||||
button.btn.btn-primary.w-100 {
|
||||
background: $btn-background-color;
|
||||
color: $btn-foreground-color;
|
||||
padding: 11px;
|
||||
border-radius: 30px;
|
||||
border: 1px solid #fff;
|
||||
}
|
||||
label.form-label {
|
||||
display: none;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
span.form-label-description {
|
||||
margin-top: 10px;
|
||||
margin-bottom: 10px;
|
||||
text-align: left;
|
||||
width: 100%;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.card-body {
|
||||
margin: 0 auto;
|
||||
width: 350px;
|
||||
max-width: 100%;
|
||||
}
|
||||
18
public/themes/original/theme.json
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"name": "GLPI Original",
|
||||
"description": "GLPI Original Theme",
|
||||
"variables": {
|
||||
"btn-background-color": {
|
||||
"name": "Cor de fundo dos Botões",
|
||||
"default": "#fdc95c"
|
||||
},
|
||||
"btn-foreground-color": {
|
||||
"name": "Cor do texto dos Botões",
|
||||
"default": "#1c2e63"
|
||||
},
|
||||
"card-background-color": {
|
||||
"name": "Cor do cartão",
|
||||
"default": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
public/themes/power-red/login.background.jpg
Normal file
|
After Width: | Height: | Size: 293 KiB |
94
public/themes/power-red/login.css
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
@charset "UTF-8";
|
||||
/*Tema 2 - PowerRed*/
|
||||
body .card {
|
||||
border: 0;
|
||||
background: transparent;
|
||||
}
|
||||
.flex-fill.d-flex.flex-column.justify-content-center.py-4.mt-4 {
|
||||
width: 525px;
|
||||
background: #ffffffde;
|
||||
margin: 0px auto !important;
|
||||
}
|
||||
.col-md-5 {
|
||||
margin: 0 !important;
|
||||
width: 100%;
|
||||
}
|
||||
h2.card-header.text-center.mb-4, div.card-header:has(.mx-auto) {
|
||||
display: none;
|
||||
}
|
||||
.flex-fill.d-flex.flex-column.justify-content-center.py-4.mt-4 {
|
||||
min-height: 711px;
|
||||
width: 525px;
|
||||
background: rgba(255, 255, 255, 0.9);
|
||||
border-radius: 0;
|
||||
box-shadow: 0 4px 30pxrgba 0, 0, 0, 0.1;
|
||||
backdrop-filter: blur(5px);
|
||||
-webkit-backdrop-filter: blur(5px);
|
||||
border: 1pxsolidrgba 255, 255, 255, 0.3;
|
||||
margin: 0px auto !important;
|
||||
height: 100% !important;
|
||||
top: 0 !important;
|
||||
}
|
||||
span.glpi-logo.mb-4 {
|
||||
margin: 0 !important;
|
||||
}
|
||||
button.btn.btn-primary.w-100 {
|
||||
color: #ffffff;
|
||||
padding: 11px;
|
||||
border-radius: 30px;
|
||||
background: #013453;
|
||||
border: 0;
|
||||
}
|
||||
.btn-primary, .btn-outline-primary, .btn-ghost-primary {
|
||||
--tblr-btn-color: #71090e;
|
||||
--tblr-btn-color-interactive: #8d0a10;
|
||||
--tblr-btn-color-text: #1e293b;
|
||||
}
|
||||
body .form-control:focus {
|
||||
color: inherit;
|
||||
background-color: #fdfdfd;
|
||||
border-color: #b90e16;
|
||||
outline: 0;
|
||||
box-shadow: 0 0 0 0.25rem rgba(185, 14, 22, 0.27);
|
||||
}
|
||||
.mb-3, .mb-4 {
|
||||
position: relative;
|
||||
}
|
||||
.mb-3:after {
|
||||
font-family: "Font Awesome 5 Free";
|
||||
font-weight: 900;
|
||||
content: "";
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
color: #6a6969;
|
||||
top: 8px;
|
||||
}
|
||||
.mb-4:before {
|
||||
font-family: "Font Awesome 5 Free";
|
||||
font-weight: 900;
|
||||
content: "";
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
color: #6a6969;
|
||||
top: 8px;
|
||||
}
|
||||
body .card {
|
||||
border: 0 none;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
label.form-label {
|
||||
display: none;
|
||||
color: #fff;
|
||||
}
|
||||
span.form-label-description {
|
||||
margin-top: 10px;
|
||||
margin-bottom: 10px;
|
||||
text-align: left;
|
||||
width: 100%;
|
||||
display: block;
|
||||
}
|
||||
.card-body {
|
||||
margin: 0 auto;
|
||||
width: 350px;
|
||||
max-width: 100%;
|
||||
}
|
||||
BIN
public/themes/power-red/login.logo.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
BIN
public/themes/power-red/login.preview.jpg
Normal file
|
After Width: | Height: | Size: 180 KiB |
113
public/themes/power-red/login.scss
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
/*Tema 2 - PowerRed*/
|
||||
|
||||
$btn-background-color: #013453 !default;
|
||||
$btn-foreground-color: #ffffff !default;
|
||||
|
||||
body .card {
|
||||
border: 0;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.flex-fill.d-flex.flex-column.justify-content-center.py-4.mt-4 {
|
||||
width: 525px;
|
||||
background: #ffffffde;
|
||||
margin: 0px auto !important;
|
||||
}
|
||||
|
||||
.col-md-5 {
|
||||
margin: 0 !important;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
h2.card-header.text-center.mb-4,
|
||||
div.card-header:has(.mx-auto) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.flex-fill.d-flex.flex-column.justify-content-center.py-4.mt-4 {
|
||||
min-height: 711px;
|
||||
width: 525px;
|
||||
background: rgb(255 255 255 / 90%);
|
||||
border-radius: 0;
|
||||
box-shadow: 0 4px 30pxrgba (0, 0, 0, 0.1);
|
||||
backdrop-filter: blur(5px);
|
||||
-webkit-backdrop-filter: blur(5px);
|
||||
border: 1pxsolidrgba (255, 255, 255, 0.3);
|
||||
margin: 0px auto !important;
|
||||
height: 100% !important;
|
||||
top: 0 !important;
|
||||
}
|
||||
|
||||
span.glpi-logo.mb-4 {
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
button.btn.btn-primary.w-100 {
|
||||
color: $btn-foreground-color;
|
||||
padding: 11px;
|
||||
border-radius: 30px;
|
||||
background: $btn-background-color;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.btn-primary,
|
||||
.btn-outline-primary,
|
||||
.btn-ghost-primary {
|
||||
--tblr-btn-color: #71090e;
|
||||
--tblr-btn-color-interactive: #8d0a10;
|
||||
--tblr-btn-color-text: #1e293b;
|
||||
}
|
||||
|
||||
body .form-control:focus {
|
||||
color: inherit;
|
||||
background-color: #fdfdfd;
|
||||
border-color: #b90e16;
|
||||
outline: 0;
|
||||
box-shadow: 0 0 0 0.25rem rgb(185 14 22 / 27%);
|
||||
}
|
||||
|
||||
.mb-3,
|
||||
.mb-4 {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.mb-3:after {
|
||||
font-family: "Font Awesome 5 Free";
|
||||
font-weight: 900;
|
||||
content: "\f007";
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
color: #6a6969;
|
||||
top: 8px;
|
||||
}
|
||||
|
||||
.mb-4:before {
|
||||
font-family: "Font Awesome 5 Free";
|
||||
font-weight: 900;
|
||||
content: "\f023";
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
color: #6a6969;
|
||||
top: 8px;
|
||||
}
|
||||
|
||||
body .card {
|
||||
border: 0 none;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
label.form-label {
|
||||
display: none;
|
||||
color: #fff;
|
||||
}
|
||||
span.form-label-description {
|
||||
margin-top: 10px;
|
||||
margin-bottom: 10px;
|
||||
text-align: left;
|
||||
width: 100%;
|
||||
display: block;
|
||||
}
|
||||
.card-body {
|
||||
margin: 0 auto;
|
||||
width: 350px;
|
||||
max-width: 100%;
|
||||
}
|
||||
18
public/themes/power-red/theme.json
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"name": "Power Red",
|
||||
"description": "Power Red Theme",
|
||||
"variables": {
|
||||
"btn-background-color": {
|
||||
"name": "Cor de fundo dos Botões",
|
||||
"default": "#013453"
|
||||
},
|
||||
"btn-foreground-color": {
|
||||
"name": "Cor do texto dos Botões",
|
||||
"default": "#ffffff"
|
||||
},
|
||||
"card-background-color": {
|
||||
"name": "Cor do cartão",
|
||||
"default": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
public/themes/prompt-developer/login.background.jpg
Normal file
|
After Width: | Height: | Size: 221 KiB |
127
public/themes/prompt-developer/login.css
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
@charset "UTF-8";
|
||||
/*Tema 6 - Prompt Developer*/
|
||||
body .card {
|
||||
border: 0;
|
||||
background: transparent;
|
||||
}
|
||||
.col-md-5 {
|
||||
margin: 0 !important;
|
||||
width: 100%;
|
||||
}
|
||||
h2.card-header.text-center.mb-4, div.card-header:has(.mx-auto) {
|
||||
display: none;
|
||||
}
|
||||
span.glpi-logo.mb-4 {
|
||||
margin: 0 !important;
|
||||
}
|
||||
.btn-primary, .btn-outline-primary, .btn-ghost-primary {
|
||||
--tblr-btn-color: #71090e;
|
||||
--tblr-btn-color-interactive: #8d0a10;
|
||||
--tblr-btn-color-text: #1e293b;
|
||||
}
|
||||
.mb-3, .mb-4 {
|
||||
position: relative;
|
||||
}
|
||||
.mb-3:after {
|
||||
font-family: "Font Awesome 5 Free";
|
||||
font-weight: 900;
|
||||
content: "";
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
color: #fff;
|
||||
top: 12px;
|
||||
}
|
||||
.mb-4:before {
|
||||
font-family: "Font Awesome 5 Free";
|
||||
font-weight: 900;
|
||||
content: "";
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
color: #fff;
|
||||
top: 12px;
|
||||
}
|
||||
.col-md-5 {
|
||||
margin: 0 !important;
|
||||
width: 100%;
|
||||
max-width: 289px;
|
||||
}
|
||||
label.form-label {
|
||||
color: #fff;
|
||||
}
|
||||
.card-body {
|
||||
padding: 0px !important;
|
||||
margin: auto;
|
||||
}
|
||||
.flex-fill.d-flex.flex-column.justify-content-center.py-4.mt-4 {
|
||||
width: 50%;
|
||||
background: transparent;
|
||||
border-radius: 30px;
|
||||
margin: 0;
|
||||
outline-offset: 0;
|
||||
box-shadow: 0px 6px 13px 1px #00000047;
|
||||
height: 100% !important;
|
||||
top: -32px;
|
||||
border-radius: 0;
|
||||
right: 1px !important;
|
||||
position: absolute;
|
||||
padding-top: 130px !important;
|
||||
padding-bottom: 110px !important;
|
||||
background: rgba(0, 0, 0, 0.38);
|
||||
box-shadow: 0 4px 30pxrgba 0, 0, 0, 0.1;
|
||||
backdrop-filter: blur(5px);
|
||||
-webkit-backdrop-filter: blur(5px);
|
||||
border: 1pxsolidrgba 255, 255, 255, 0.3;
|
||||
}
|
||||
button.btn.btn-primary.w-100 {
|
||||
color: #000000;
|
||||
padding: 11px;
|
||||
border-radius: 30px;
|
||||
border: 1px solid #fff;
|
||||
background: #ffffff;
|
||||
}
|
||||
a {
|
||||
color: #ffffff !important;
|
||||
text-decoration: underline;
|
||||
}
|
||||
body .form-control {
|
||||
display: block;
|
||||
width: 100%;
|
||||
min-width: 250px;
|
||||
padding: 0.7375rem 0.75rem;
|
||||
font-size: 0.875rem;
|
||||
font-weight: 400;
|
||||
line-height: 1.4285714286;
|
||||
color: inherit;
|
||||
border: 0;
|
||||
appearance: none;
|
||||
transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
|
||||
background: #ffffff05;
|
||||
border-radius: 0;
|
||||
border-bottom: 1px solid #fff;
|
||||
}
|
||||
label.form-label {
|
||||
display: none;
|
||||
color: #fff;
|
||||
}
|
||||
span.form-label-description {
|
||||
margin-top: 10px;
|
||||
margin-bottom: 10px;
|
||||
text-align: left;
|
||||
width: 100%;
|
||||
display: block;
|
||||
}
|
||||
.card-body {
|
||||
margin: 0 auto;
|
||||
width: 350px;
|
||||
max-width: 100%;
|
||||
}
|
||||
.col-auto.offset-md-1.p-2.text-center {
|
||||
display: none;
|
||||
}
|
||||
.form-control:focus {
|
||||
color: inherit;
|
||||
background-color: #fdfdfd;
|
||||
border-color: #013453;
|
||||
outline: 0;
|
||||
box-shadow: 0 0 0 0.25rem #5e5e5e3b;
|
||||
}
|
||||
BIN
public/themes/prompt-developer/login.logo.png
Normal file
|
After Width: | Height: | Size: 3.5 KiB |
BIN
public/themes/prompt-developer/login.preview.jpg
Normal file
|
After Width: | Height: | Size: 146 KiB |
148
public/themes/prompt-developer/login.scss
Normal file
|
|
@ -0,0 +1,148 @@
|
|||
/*Tema 6 - Prompt Developer*/
|
||||
|
||||
$btn-background-color: #ffffff !default;
|
||||
$btn-foreground-color: #000000 !default;
|
||||
|
||||
body .card {
|
||||
border: 0;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.col-md-5 {
|
||||
margin: 0 !important;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
h2.card-header.text-center.mb-4,
|
||||
div.card-header:has(.mx-auto) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
span.glpi-logo.mb-4 {
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
.btn-primary,
|
||||
.btn-outline-primary,
|
||||
.btn-ghost-primary {
|
||||
--tblr-btn-color: #71090e;
|
||||
--tblr-btn-color-interactive: #8d0a10;
|
||||
--tblr-btn-color-text: #1e293b;
|
||||
}
|
||||
|
||||
.mb-3,
|
||||
.mb-4 {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.mb-3:after {
|
||||
font-family: "Font Awesome 5 Free";
|
||||
font-weight: 900;
|
||||
content: "\f007";
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
color: #fff;
|
||||
top: 12px;
|
||||
}
|
||||
|
||||
.mb-4:before {
|
||||
font-family: "Font Awesome 5 Free";
|
||||
font-weight: 900;
|
||||
content: "\f023";
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
color: #fff;
|
||||
top: 12px;
|
||||
}
|
||||
|
||||
.col-md-5 {
|
||||
margin: 0 !important;
|
||||
width: 100%;
|
||||
max-width: 289px;
|
||||
}
|
||||
|
||||
label.form-label {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.card-body {
|
||||
padding: 0px !important;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.flex-fill.d-flex.flex-column.justify-content-center.py-4.mt-4 {
|
||||
width: 50%;
|
||||
background: transparent;
|
||||
border-radius: 30px;
|
||||
margin: 0;
|
||||
outline-offset: 0;
|
||||
box-shadow: 0px 6px 13px 1px #00000047;
|
||||
height: 100% !important;
|
||||
top: -32px;
|
||||
border-radius: 0;
|
||||
right: 1px !important;
|
||||
position: absolute;
|
||||
padding-top: 130px !important;
|
||||
padding-bottom: 110px !important;
|
||||
background: rgb(0 0 0 / 38%);
|
||||
box-shadow: 0 4px 30pxrgba (0, 0, 0, 0.1);
|
||||
backdrop-filter: blur(5px);
|
||||
-webkit-backdrop-filter: blur(5px);
|
||||
border: 1pxsolidrgba (255, 255, 255, 0.3);
|
||||
}
|
||||
|
||||
button.btn.btn-primary.w-100 {
|
||||
color: $btn-foreground-color;
|
||||
padding: 11px;
|
||||
border-radius: 30px;
|
||||
border: 1px solid #fff;
|
||||
background: $btn-background-color;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #ffffff !important;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
body .form-control {
|
||||
display: block;
|
||||
width: 100%;
|
||||
min-width: 250px;
|
||||
padding: 0.7375rem 0.75rem;
|
||||
font-size: 0.875rem;
|
||||
font-weight: 400;
|
||||
line-height: 1.4285714286;
|
||||
color: inherit;
|
||||
border: 0;
|
||||
appearance: none;
|
||||
transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
|
||||
background: #ffffff05;
|
||||
border-radius: 0;
|
||||
border-bottom: 1px solid #fff;
|
||||
}
|
||||
label.form-label {
|
||||
display: none;
|
||||
color: #fff;
|
||||
}
|
||||
span.form-label-description {
|
||||
margin-top: 10px;
|
||||
margin-bottom: 10px;
|
||||
text-align: left;
|
||||
width: 100%;
|
||||
display: block;
|
||||
}
|
||||
.card-body {
|
||||
margin: 0 auto;
|
||||
width: 350px;
|
||||
max-width: 100%;
|
||||
}
|
||||
.col-auto.offset-md-1.p-2.text-center {
|
||||
display: none;
|
||||
}
|
||||
.form-control:focus {
|
||||
color: inherit;
|
||||
background-color: #fdfdfd;
|
||||
border-color: #013453;
|
||||
outline: 0;
|
||||
box-shadow: 0 0 0 0.25rem #5e5e5e3b;
|
||||
}
|
||||
18
public/themes/prompt-developer/theme.json
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"name": "Prompt Developer",
|
||||
"description": "Prompt Developer Theme",
|
||||
"variables": {
|
||||
"btn-background-color": {
|
||||
"name": "Cor de fundo dos Botões",
|
||||
"default": "#0000003b"
|
||||
},
|
||||
"btn-foreground-color": {
|
||||
"name": "Cor do texto dos Botões",
|
||||
"default": "#ffffff"
|
||||
},
|
||||
"card-background-color": {
|
||||
"name": "Cor do cartão",
|
||||
"default": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
117
setup.php
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
<?php
|
||||
|
||||
define('PLUGIN_BUTTERFLY_VERSION', '2.1.0');
|
||||
|
||||
// Minimal GLPI version, inclusive
|
||||
define("PLUGIN_BUTTERFLY_MIN_GLPI_VERSION", "10.0.0");
|
||||
|
||||
// Maximum GLPI version, exclusive
|
||||
define("PLUGIN_BUTTERFLY_MAX_GLPI_VERSION", "11.0.99");
|
||||
|
||||
|
||||
$folder = basename(__DIR__);
|
||||
|
||||
if (strtolower($folder) !== "butterfly") {
|
||||
$msg = sprintf("Please, rename the plugin folder \"%s\" to \"butterfly\"", $folder);
|
||||
Session::addMessageAfterRedirect($msg, true, ERROR);
|
||||
}
|
||||
|
||||
// Init the hooks of the plugins -Needed
|
||||
function plugin_init_butterfly()
|
||||
{
|
||||
global $PLUGIN_HOOKS, $CFG_GLPI;
|
||||
$PLUGIN_HOOKS['csrf_compliant']['butterfly'] = true;
|
||||
|
||||
// Register firewall strategies for legacy scripts even before installation
|
||||
if (class_exists(\Glpi\Http\Firewall::class)) {
|
||||
\Glpi\Http\Firewall::addPluginStrategyForLegacyScripts(
|
||||
'butterfly',
|
||||
'#^/front/picture\.send\.php$#',
|
||||
\Glpi\Http\Firewall::STRATEGY_NO_CHECK
|
||||
);
|
||||
\Glpi\Http\Firewall::addPluginStrategyForLegacyScripts(
|
||||
'butterfly',
|
||||
'#^/front/login\.css\.php$#',
|
||||
\Glpi\Http\Firewall::STRATEGY_NO_CHECK
|
||||
);
|
||||
\Glpi\Http\Firewall::addPluginStrategyForLegacyScripts(
|
||||
'butterfly',
|
||||
'#^/front/internal\.css\.php$#',
|
||||
\Glpi\Http\Firewall::STRATEGY_NO_CHECK
|
||||
);
|
||||
\Glpi\Http\Firewall::addPluginStrategyForLegacyScripts(
|
||||
'butterfly',
|
||||
'#^/front/internal\.js\.php$#',
|
||||
\Glpi\Http\Firewall::STRATEGY_NO_CHECK
|
||||
);
|
||||
}
|
||||
|
||||
// $PLUGIN_HOOKS['config_page']['butterfly'] = '../../front/config.form.php?itemtype=Config&glpi_tab=PluginButterflyConfig$1';
|
||||
|
||||
$plugin = new Plugin();
|
||||
|
||||
if ($plugin->isInstalled('butterfly') && $plugin->isActivated('butterfly')) {
|
||||
|
||||
$autoload = __DIR__ . '/vendor/autoload.php';
|
||||
if (file_exists($autoload)) {
|
||||
include_once $autoload;
|
||||
}
|
||||
;
|
||||
|
||||
Plugin::registerClass('PluginButterflyConfig', [
|
||||
'addtabon' => ['Config']
|
||||
]);
|
||||
|
||||
// Register config page only when installed & activated
|
||||
$PLUGIN_HOOKS['config_page']['butterfly'] = '../../front/config.form.php?itemtype=Config&glpi_tab=PluginButterflyConfig$1';
|
||||
|
||||
$PLUGIN_HOOKS['display_login']['butterfly'] = "plugin_butterfly_display_login";
|
||||
|
||||
// Tip Trick to add version in css output
|
||||
$PLUGIN_HOOKS["add_css"]['butterfly'] = new PluginButterflyFileVersion('front/internal.css.php');
|
||||
$PLUGIN_HOOKS["add_javascript"]['butterfly'] = new PluginButterflyFileVersion('front/internal.js.php');
|
||||
|
||||
$CFG_GLPI['javascript']['config']['config'][] = 'codemirror';
|
||||
$CFG_GLPI['javascript']['config']['config'][] = 'tinymce';
|
||||
}
|
||||
}
|
||||
|
||||
// Get the name and the version of the plugin - Needed
|
||||
function plugin_version_butterfly()
|
||||
{
|
||||
return [
|
||||
'name' => t_butterfly('Butterfly'),
|
||||
'version' => PLUGIN_BUTTERFLY_VERSION,
|
||||
'author' => 'Rodolpho Lopes',
|
||||
'homepage' => 'https://github.com/rodolpholopes',
|
||||
'license' => 'GPL v2+',
|
||||
'minGlpiVersion' => PLUGIN_BUTTERFLY_MIN_GLPI_VERSION,
|
||||
'requirements' => [
|
||||
'glpi' => [
|
||||
'min' => PLUGIN_BUTTERFLY_MIN_GLPI_VERSION,
|
||||
'max' => PLUGIN_BUTTERFLY_MAX_GLPI_VERSION,
|
||||
]
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
// Optional : check prerequisites before install : may print errors or add to message after redirect
|
||||
function plugin_butterfly_check_prerequisites()
|
||||
{
|
||||
if (version_compare(GLPI_VERSION, PLUGIN_BUTTERFLY_MIN_GLPI_VERSION, 'lt')) {
|
||||
echo "This plugin requires GLPI >= " . PLUGIN_BUTTERFLY_MIN_GLPI_VERSION;
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
function plugin_butterfly_check_config()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
function t_butterfly($str)
|
||||
{
|
||||
return __($str, 'butterfly');
|
||||
}
|
||||
12
themes/.htaccess
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
# Allow direct access to theme files
|
||||
<Files ~ "\.(jpg|jpeg|png|gif|css|scss|json)$">
|
||||
Order allow,deny
|
||||
Allow from all
|
||||
Satisfy any
|
||||
</Files>
|
||||
|
||||
# Disable PHP execution in themes directory
|
||||
<Files ~ "\.php$">
|
||||
Order deny,allow
|
||||
Deny from all
|
||||
</Files>
|
||||
BIN
themes/aurora-boreal/login.background.jpg
Normal file
|
After Width: | Height: | Size: 301 KiB |
108
themes/aurora-boreal/login.css
Normal file
|
|
@ -0,0 +1,108 @@
|
|||
@charset "UTF-8";
|
||||
/*Tema - Aurora Boreal*/
|
||||
body .card {
|
||||
border: 0;
|
||||
background: transparent;
|
||||
}
|
||||
.flex-fill.d-flex.flex-column.justify-content-center.py-4.mt-4 {
|
||||
width: 525px;
|
||||
background: transparent;
|
||||
margin: 0px auto !important;
|
||||
}
|
||||
.col-md-5 {
|
||||
margin: 0 !important;
|
||||
width: 100%;
|
||||
}
|
||||
h2.card-header.text-center.mb-4, div.card-header:has(.mx-auto) {
|
||||
display: none;
|
||||
}
|
||||
.flex-fill.d-flex.flex-column.justify-content-center.py-4.mt-4 {
|
||||
min-height: 711px;
|
||||
width: 525px;
|
||||
background: transparent;
|
||||
border-radius: 0;
|
||||
box-shadow: 0 4px 30px rgba(0, 0, 0, 0.1);
|
||||
-webkit-backdrop-filter: blur(5px);
|
||||
border: 1px solid rgba(255, 255, 255, 0.3);
|
||||
margin: 0px auto !important;
|
||||
height: 100% !important;
|
||||
}
|
||||
span.glpi-logo.mb-4 {
|
||||
margin: 0 !important;
|
||||
}
|
||||
.btn-primary, .btn-outline-primary, .btn-ghost-primary {
|
||||
--tblr-btn-color: #71090e;
|
||||
--tblr-btn-color-interactive: #8d0a10;
|
||||
--tblr-btn-color-text: #1e293b;
|
||||
}
|
||||
body .form-control:focus {
|
||||
color: inherit;
|
||||
background-color: #fdfdfd;
|
||||
border-color: #1b5ca3c2;
|
||||
outline: 0;
|
||||
box-shadow: 0 0 0 0.25rem #1b5ca3c2;
|
||||
}
|
||||
.mb-3, .mb-4 {
|
||||
position: relative;
|
||||
}
|
||||
.mb-3:after {
|
||||
font-family: "Font Awesome 5 Free";
|
||||
font-weight: 900;
|
||||
content: "";
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
color: #6a696982;
|
||||
top: 12px;
|
||||
}
|
||||
.mb-4:before {
|
||||
font-family: "Font Awesome 5 Free";
|
||||
font-weight: 900;
|
||||
content: "";
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
color: #6a696982;
|
||||
top: 12px;
|
||||
}
|
||||
.col-md-5 {
|
||||
margin: 0 !important;
|
||||
width: 100%;
|
||||
max-width: 289px;
|
||||
}
|
||||
body .form-control {
|
||||
display: block;
|
||||
width: 100%;
|
||||
padding: 0.7375rem 0.75rem;
|
||||
font-size: 0.875rem;
|
||||
font-weight: 400;
|
||||
line-height: 1.4285714286;
|
||||
color: inherit;
|
||||
background-color: #fdfdfd;
|
||||
background-clip: padding-box;
|
||||
border: 1px solid #d9dbde;
|
||||
appearance: none;
|
||||
border-radius: 34px;
|
||||
transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
|
||||
}
|
||||
button.btn.btn-primary.w-100 {
|
||||
background: transparent;
|
||||
color: #ffffff;
|
||||
padding: 11px;
|
||||
border-radius: 30px;
|
||||
border: 1px solid #fff;
|
||||
}
|
||||
label.form-label {
|
||||
color: #fff;
|
||||
}
|
||||
a {
|
||||
color: #73fff9 !important;
|
||||
text-decoration: none;
|
||||
}
|
||||
label.form-label {
|
||||
display: none;
|
||||
color: #fff;
|
||||
}
|
||||
.card-body {
|
||||
margin: 0 auto;
|
||||
width: 350px;
|
||||
max-width: 100%;
|
||||
}
|
||||
BIN
themes/aurora-boreal/login.logo.png
Normal file
|
After Width: | Height: | Size: 3.5 KiB |
BIN
themes/aurora-boreal/login.preview.jpg
Normal file
|
After Width: | Height: | Size: 190 KiB |
129
themes/aurora-boreal/login.scss
Normal file
|
|
@ -0,0 +1,129 @@
|
|||
/*Tema - Aurora Boreal*/
|
||||
|
||||
$btn-foreground-color: #ffffff !default;
|
||||
|
||||
body .card {
|
||||
border: 0;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.flex-fill.d-flex.flex-column.justify-content-center.py-4.mt-4 {
|
||||
width: 525px;
|
||||
background: transparent;
|
||||
margin: 0px auto !important;
|
||||
}
|
||||
|
||||
.col-md-5 {
|
||||
margin: 0 !important;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
h2.card-header.text-center.mb-4,
|
||||
div.card-header:has(.mx-auto) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.flex-fill.d-flex.flex-column.justify-content-center.py-4.mt-4 {
|
||||
min-height: 711px;
|
||||
width: 525px;
|
||||
background: transparent;
|
||||
border-radius: 0;
|
||||
box-shadow: 0 4px 30px rgba(0, 0, 0, 0.1);
|
||||
-webkit-backdrop-filter: blur(5px);
|
||||
border: 1px solid rgba(255, 255, 255, 0.3);
|
||||
margin: 0px auto !important;
|
||||
height: 100% !important;
|
||||
}
|
||||
|
||||
span.glpi-logo.mb-4 {
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
.btn-primary,
|
||||
.btn-outline-primary,
|
||||
.btn-ghost-primary {
|
||||
--tblr-btn-color: #71090e;
|
||||
--tblr-btn-color-interactive: #8d0a10;
|
||||
--tblr-btn-color-text: #1e293b;
|
||||
}
|
||||
|
||||
body .form-control:focus {
|
||||
color: inherit;
|
||||
background-color: #fdfdfd;
|
||||
border-color: #1b5ca3c2;
|
||||
outline: 0;
|
||||
box-shadow: 0 0 0 0.25rem #1b5ca3c2;
|
||||
}
|
||||
|
||||
.mb-3,
|
||||
.mb-4 {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.mb-3:after {
|
||||
font-family: "Font Awesome 5 Free";
|
||||
font-weight: 900;
|
||||
content: "\f007";
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
color: #6a696982;
|
||||
top: 12px;
|
||||
}
|
||||
|
||||
.mb-4:before {
|
||||
font-family: "Font Awesome 5 Free";
|
||||
font-weight: 900;
|
||||
content: "\f023";
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
color: #6a696982;
|
||||
top: 12px;
|
||||
}
|
||||
|
||||
.col-md-5 {
|
||||
margin: 0 !important;
|
||||
width: 100%;
|
||||
max-width: 289px;
|
||||
}
|
||||
|
||||
body .form-control {
|
||||
display: block;
|
||||
width: 100%;
|
||||
padding: 0.7375rem 0.75rem;
|
||||
font-size: 0.875rem;
|
||||
font-weight: 400;
|
||||
line-height: 1.4285714286;
|
||||
color: inherit;
|
||||
background-color: #fdfdfd;
|
||||
background-clip: padding-box;
|
||||
border: 1px solid #d9dbde;
|
||||
appearance: none;
|
||||
border-radius: 34px;
|
||||
transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
|
||||
}
|
||||
|
||||
button.btn.btn-primary.w-100 {
|
||||
background: transparent;
|
||||
color: $btn-foreground-color;
|
||||
padding: 11px;
|
||||
border-radius: 30px;
|
||||
border: 1px solid #fff;
|
||||
}
|
||||
|
||||
label.form-label {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #73fff9 !important;
|
||||
text-decoration: none;
|
||||
}
|
||||
label.form-label {
|
||||
display: none;
|
||||
color: #fff;
|
||||
}
|
||||
.card-body {
|
||||
margin: 0 auto;
|
||||
width: 350px;
|
||||
max-width: 100%;
|
||||
}
|
||||
14
themes/aurora-boreal/theme.json
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"name": "Aurora Boreal",
|
||||
"description": "Aurora Boreal Theme",
|
||||
"variables": {
|
||||
"btn-foreground-color": {
|
||||
"name": "Cor do texto dos Botões",
|
||||
"default": "#ffffff"
|
||||
},
|
||||
"card-background-color": {
|
||||
"name": "Cor do cartão",
|
||||
"default": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
themes/baloons/login.background.jpg
Normal file
|
After Width: | Height: | Size: 141 KiB |
114
themes/baloons/login.css
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
@charset "UTF-8";
|
||||
/*Tema 9 - Baloons*/
|
||||
body .card {
|
||||
border: 0;
|
||||
background: transparent;
|
||||
}
|
||||
.col-md-5 {
|
||||
margin: 0 !important;
|
||||
width: 100%;
|
||||
}
|
||||
h2.card-header.text-center.mb-4, div.card-header:has(.mx-auto) {
|
||||
display: none;
|
||||
}
|
||||
span.glpi-logo.mb-4 {
|
||||
margin: 0 !important;
|
||||
}
|
||||
.btn-primary, .btn-outline-primary, .btn-ghost-primary {
|
||||
--tblr-btn-color: #71090e;
|
||||
--tblr-btn-color-interactive: #8d0a10;
|
||||
--tblr-btn-color-text: #1e293b;
|
||||
}
|
||||
.mb-3, .mb-4 {
|
||||
position: relative;
|
||||
}
|
||||
.mb-3:after {
|
||||
font-family: "Font Awesome 5 Free";
|
||||
font-weight: 900;
|
||||
content: "";
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
color: #6a696982;
|
||||
top: 12px;
|
||||
}
|
||||
.mb-4:before {
|
||||
font-family: "Font Awesome 5 Free";
|
||||
font-weight: 900;
|
||||
content: "";
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
color: #6a696982;
|
||||
top: 12px;
|
||||
}
|
||||
.col-md-5 {
|
||||
margin: 0 !important;
|
||||
width: 100%;
|
||||
max-width: 289px;
|
||||
}
|
||||
label.form-label {
|
||||
color: #a6abb1;
|
||||
}
|
||||
.flex-fill.d-flex.flex-column.justify-content-center.py-4.mt-4 {
|
||||
width: 383px;
|
||||
background: #e6eef8;
|
||||
border-radius: 0;
|
||||
margin: 114px auto !important;
|
||||
outline: 28px solid #ffffff30;
|
||||
outline-offset: 0;
|
||||
box-shadow: 0px 6px 13px 1px #00000047;
|
||||
height: 100% !important;
|
||||
}
|
||||
button.btn.btn-primary.w-100 {
|
||||
background: transparent;
|
||||
color: #ffffff;
|
||||
padding: 11px;
|
||||
border-radius: 30px;
|
||||
border: 1px solid #fff;
|
||||
background: #593a90;
|
||||
background: linear-gradient(0deg, #593a90 0%, #7551b5 48%, 1 100%);
|
||||
}
|
||||
a {
|
||||
color: #7551b5 !important;
|
||||
text-decoration: none;
|
||||
}
|
||||
body .form-control {
|
||||
display: block;
|
||||
width: 100%;
|
||||
padding: 0.7375rem 0.75rem;
|
||||
font-size: 0.875rem;
|
||||
font-weight: 400;
|
||||
line-height: 1.4285714286;
|
||||
color: inherit;
|
||||
background-color: #fdfdfd;
|
||||
background-clip: padding-box;
|
||||
border: 0;
|
||||
appearance: none;
|
||||
border-radius: 34px;
|
||||
transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
|
||||
background: linear-gradient(0deg, #e6eef8, #e6eef8), #cfd8dc;
|
||||
box-shadow: inset -4px -4px 12px rgba(253, 255, 255, 0.8), inset 4px 4px 12px rgba(187, 195, 206, 0.6);
|
||||
border-radius: 16px;
|
||||
}
|
||||
label.form-label {
|
||||
display: none;
|
||||
color: #fff;
|
||||
}
|
||||
span.form-label-description {
|
||||
margin-top: 10px;
|
||||
margin-bottom: 10px;
|
||||
text-align: left;
|
||||
width: 100%;
|
||||
display: block;
|
||||
}
|
||||
.card-body {
|
||||
margin: 0 auto;
|
||||
width: 350px;
|
||||
max-width: 100%;
|
||||
}
|
||||
.form-control:focus {
|
||||
color: inherit;
|
||||
background-color: #fdfdfd;
|
||||
border-color: #673ab7;
|
||||
outline: 0;
|
||||
box-shadow: 0 0 0 0.25rem rgba(103, 58, 183, 0.26);
|
||||
}
|
||||
BIN
themes/baloons/login.logo.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
BIN
themes/baloons/login.preview.jpg
Normal file
|
After Width: | Height: | Size: 118 KiB |
137
themes/baloons/login.scss
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
/*Tema 9 - Baloons*/
|
||||
|
||||
$btn-background-color1: #593a90 !default;
|
||||
$btn-background-color2: #7551b5 !default;
|
||||
$btn-foreground-color: #ffffff !default;
|
||||
|
||||
body .card {
|
||||
border: 0;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.col-md-5 {
|
||||
margin: 0 !important;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
h2.card-header.text-center.mb-4,
|
||||
div.card-header:has(.mx-auto) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
span.glpi-logo.mb-4 {
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
.btn-primary,
|
||||
.btn-outline-primary,
|
||||
.btn-ghost-primary {
|
||||
--tblr-btn-color: #71090e;
|
||||
--tblr-btn-color-interactive: #8d0a10;
|
||||
--tblr-btn-color-text: #1e293b;
|
||||
}
|
||||
|
||||
.mb-3,
|
||||
.mb-4 {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.mb-3:after {
|
||||
font-family: "Font Awesome 5 Free";
|
||||
font-weight: 900;
|
||||
content: "\f007";
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
color: #6a696982;
|
||||
top: 12px;
|
||||
}
|
||||
|
||||
.mb-4:before {
|
||||
font-family: "Font Awesome 5 Free";
|
||||
font-weight: 900;
|
||||
content: "\f023";
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
color: #6a696982;
|
||||
top: 12px;
|
||||
}
|
||||
|
||||
.col-md-5 {
|
||||
margin: 0 !important;
|
||||
width: 100%;
|
||||
max-width: 289px;
|
||||
}
|
||||
|
||||
label.form-label {
|
||||
color: #a6abb1;
|
||||
}
|
||||
|
||||
.flex-fill.d-flex.flex-column.justify-content-center.py-4.mt-4 {
|
||||
width: 383px;
|
||||
background: rgb(230 238 248);
|
||||
border-radius: 0;
|
||||
margin: 114px auto !important;
|
||||
outline: 28px solid #ffffff30;
|
||||
outline-offset: 0;
|
||||
box-shadow: 0px 6px 13px 1px #00000047;
|
||||
height: 100% !important;
|
||||
}
|
||||
|
||||
button.btn.btn-primary.w-100 {
|
||||
background: transparent;
|
||||
color: $btn-foreground-color;
|
||||
padding: 11px;
|
||||
border-radius: 30px;
|
||||
border: 1px solid #fff;
|
||||
background: $btn-background-color1;
|
||||
background: linear-gradient(0deg, $btn-background-color1 0%, $btn-background-color2 48%, 1 100%);
|
||||
}
|
||||
|
||||
a {
|
||||
color: #7551b5 !important;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
body .form-control {
|
||||
display: block;
|
||||
width: 100%;
|
||||
padding: 0.7375rem 0.75rem;
|
||||
font-size: 0.875rem;
|
||||
font-weight: 400;
|
||||
line-height: 1.4285714286;
|
||||
color: inherit;
|
||||
background-color: #fdfdfd;
|
||||
background-clip: padding-box;
|
||||
border: 0;
|
||||
appearance: none;
|
||||
border-radius: 34px;
|
||||
transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
|
||||
background: linear-gradient(0deg, #e6eef8, #e6eef8), #cfd8dc;
|
||||
box-shadow: inset -4px -4px 12px rgb(253 255 255 / 80%),
|
||||
inset 4px 4px 12px rgb(187 195 206 / 60%);
|
||||
border-radius: 16px;
|
||||
}
|
||||
|
||||
label.form-label {
|
||||
display: none;
|
||||
color: #fff;
|
||||
}
|
||||
span.form-label-description {
|
||||
margin-top: 10px;
|
||||
margin-bottom: 10px;
|
||||
text-align: left;
|
||||
width: 100%;
|
||||
display: block;
|
||||
}
|
||||
.card-body {
|
||||
margin: 0 auto;
|
||||
width: 350px;
|
||||
max-width: 100%;
|
||||
}
|
||||
.form-control:focus {
|
||||
color: inherit;
|
||||
background-color: #fdfdfd;
|
||||
border-color: #673ab7;
|
||||
outline: 0;
|
||||
box-shadow: 0 0 0 0.25rem rgb(103 58 183 / 26%);
|
||||
}
|
||||
22
themes/baloons/theme.json
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
{
|
||||
"name": "Ballons",
|
||||
"description": "Ballons Theme",
|
||||
"variables": {
|
||||
"btn-background-color1": {
|
||||
"name": "Cor de fundo 1 dos Botões",
|
||||
"default": "#593a90"
|
||||
},
|
||||
"btn-background-color2": {
|
||||
"name": "Cor de fundo 2 dos Botões",
|
||||
"default": "#7551b5"
|
||||
},
|
||||
"btn-foreground-color": {
|
||||
"name": "Cor do texto dos Botões",
|
||||
"default": "#ffffff"
|
||||
},
|
||||
"card-background-color": {
|
||||
"name": "Cor do cartão",
|
||||
"default": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
themes/cloud/login.background.jpg
Normal file
|
After Width: | Height: | Size: 183 KiB |
119
themes/cloud/login.css
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
@charset "UTF-8";
|
||||
/*Tema 3 - Cloud*/
|
||||
body .card {
|
||||
border: 0;
|
||||
background: transparent;
|
||||
}
|
||||
.col-md-5 {
|
||||
margin: 0 !important;
|
||||
width: 100%;
|
||||
}
|
||||
h2.card-header.text-center.mb-4, div.card-header:has(.mx-auto) {
|
||||
display: none;
|
||||
}
|
||||
span.glpi-logo.mb-4 {
|
||||
margin: 0 !important;
|
||||
}
|
||||
.btn-primary, .btn-outline-primary, .btn-ghost-primary {
|
||||
--tblr-btn-color: #71090e;
|
||||
--tblr-btn-color-interactive: #8d0a10;
|
||||
--tblr-btn-color-text: #1e293b;
|
||||
}
|
||||
.mb-3, .mb-4 {
|
||||
position: relative;
|
||||
}
|
||||
.mb-3:after {
|
||||
font-family: "Font Awesome 5 Free";
|
||||
font-weight: 900;
|
||||
content: "";
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
color: #6a696982;
|
||||
top: 12px;
|
||||
}
|
||||
.mb-4:before {
|
||||
font-family: "Font Awesome 5 Free";
|
||||
font-weight: 900;
|
||||
content: "";
|
||||
position: absolute;
|
||||
right: 20px;
|
||||
color: #6a696982;
|
||||
top: 12px;
|
||||
}
|
||||
.col-md-5 {
|
||||
margin: 0 !important;
|
||||
width: 100%;
|
||||
max-width: 289px;
|
||||
}
|
||||
label.form-label {
|
||||
color: #a6abb1;
|
||||
}
|
||||
.card-body {
|
||||
padding: 0px !important;
|
||||
margin: auto;
|
||||
}
|
||||
.flex-fill.d-flex.flex-column.justify-content-center.py-4.mt-4 {
|
||||
width: 383px;
|
||||
background: #ffffff;
|
||||
border-radius: 30px;
|
||||
margin: 114px auto !important;
|
||||
outline-offset: 0;
|
||||
box-shadow: 0px 6px 13px 1px #00000047;
|
||||
height: 100% !important;
|
||||
}
|
||||
button.btn.btn-primary.w-100 {
|
||||
color: #ffffff;
|
||||
padding: 11px;
|
||||
border-radius: 30px;
|
||||
border: 1px solid #fff;
|
||||
background: #000000;
|
||||
}
|
||||
a {
|
||||
color: #000000 !important;
|
||||
text-decoration: underline;
|
||||
}
|
||||
body .form-control {
|
||||
display: block;
|
||||
width: 100%;
|
||||
min-width: 250px;
|
||||
padding: 0.7375rem 0.75rem;
|
||||
font-size: 0.875rem;
|
||||
font-weight: 400;
|
||||
line-height: 1.4285714286;
|
||||
color: inherit;
|
||||
background-color: #fdfdfd;
|
||||
background-clip: padding-box;
|
||||
border: 0;
|
||||
appearance: none;
|
||||
border-radius: 34px;
|
||||
transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
|
||||
background: #fff;
|
||||
border-radius: 0;
|
||||
border-bottom: 1px solid;
|
||||
}
|
||||
label.form-label {
|
||||
display: none;
|
||||
color: #fff;
|
||||
}
|
||||
span.form-label-description {
|
||||
margin-top: 10px;
|
||||
margin-bottom: 10px;
|
||||
text-align: left;
|
||||
width: 100%;
|
||||
display: block;
|
||||
}
|
||||
.card-body {
|
||||
margin: 0 auto;
|
||||
width: 350px;
|
||||
max-width: 100%;
|
||||
}
|
||||
.col-auto.offset-md-1.p-2.text-center {
|
||||
display: none;
|
||||
}
|
||||
.form-control:focus {
|
||||
color: inherit;
|
||||
background-color: #fdfdfd;
|
||||
border-color: #013453;
|
||||
outline: 0;
|
||||
box-shadow: 0 0 0 0.25rem #5e5e5e3b;
|
||||
}
|
||||
BIN
themes/cloud/login.logo.png
Normal file
|
After Width: | Height: | Size: 2.9 KiB |
BIN
themes/cloud/login.preview.jpg
Normal file
|
After Width: | Height: | Size: 126 KiB |