Update packages, improve vite integration

This commit is contained in:
Andreas Palm 2024-09-11 23:10:39 +02:00
parent 7fca100a3d
commit 0d375668f8
12 changed files with 1966 additions and 13108 deletions

14422
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,29 +1,23 @@
{ {
"private": true, "private": true,
"type": "module",
"scripts": { "scripts": {
"api-docs:validate": "./node_modules/raml2html/bin/raml2html --validate www/api/docs.raml > /dev/null", "api-docs:validate": "./node_modules/raml2html/bin/raml2html --validate www/api/docs.raml > /dev/null",
"api-docs:build": "./node_modules/raml2html/bin/raml2html --validate --theme raml2html-werk-theme --input www/api/docs.raml --output www/api/docs-tmp.html && cat www/api/docs-tmp.html | sed -e 's/<\\/head>/<link rel=\\\"stylesheet\\\" href=\\\"\\.\\/assets\\/docs_custom\\.css\\\"><\\/head>/' > www/api/docs.html && rm www/api/docs-tmp.html", "api-docs:build": "./node_modules/raml2html/bin/raml2html --validate --theme raml2html-werk-theme --input www/api/docs.raml --output www/api/docs-tmp.html && cat www/api/docs-tmp.html | sed -e 's/<\\/head>/<link rel=\\\"stylesheet\\\" href=\\\"\\.\\/assets\\/docs_custom\\.css\\\"><\\/head>/' > www/api/docs.html && rm www/api/docs-tmp.html",
"dev": "npm run development", "dev": "vite -d --cors --host ::",
"development": "./node_modules/cross-env/src/bin/cross-env-shell.js NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js", "build": "vite build",
"watch": "npm run development -- --watch", "preview": "vite preview"
"hot": "./node_modules/cross-env/src/bin/cross-env-shell.js NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --disable-host-check --config=node_modules/laravel-mix/setup/webpack.config.js",
"prod": "npm run production",
"production": "./node_modules/cross-env/src/bin/cross-env-shell.js NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js"
}, },
"devDependencies": { "devDependencies": {
"cross-env": "^7.0", "raml2html": "^7.8.0",
"laravel-mix": "^5.0.1", "raml2html-werk-theme": "^1.3.4"
"raml2html": "^7.6.0",
"raml2html-werk-theme": "^1.1.0",
"resolve-url-loader": "^3.1.0",
"sass": "^1.15.2",
"sass-loader": "^8.0.0"
}, },
"dependencies": { "dependencies": {
"@vitejs/plugin-vue": "^4.3.4", "@vitejs/plugin-vue": "^5",
"axios": "^1.5.0", "axios": "^1",
"primevue": "^3.35.0", "glob": "^10.3.12",
"vite": "^4.4.9", "primevue": "^3",
"vue": "^3.3.4" "vite": "^5",
"vue": "^3"
} }
} }

View File

@ -64,7 +64,7 @@ class ModuleScriptCache
$this->absoluteCacheDir = $this->baseDir . '/www/cache'; $this->absoluteCacheDir = $this->baseDir . '/www/cache';
$this->relativeCacheDir = './cache'; $this->relativeCacheDir = './cache';
$this->assetDir = '/dist'; $this->assetDir = '/dist';
$this->assetManifest = json_decode(file_get_contents($this->baseDir. '/www' . $this->assetDir . '/manifest.json')); $this->assetManifest = json_decode(file_get_contents($this->baseDir. '/www' . $this->assetDir . '/.vite/manifest.json'));
// Cache-Ordner anzulegen, falls nicht existent // Cache-Ordner anzulegen, falls nicht existent
if (!is_dir($this->absoluteCacheDir)) { if (!is_dir($this->absoluteCacheDir)) {
@ -221,6 +221,7 @@ class ModuleScriptCache
$realPath = realpath($this->baseDir . '/' . $file); $realPath = realpath($this->baseDir . '/' . $file);
if (!is_file($realPath)) if (!is_file($realPath))
continue; continue;
$this->javascriptModules[] = $file; continue;
if (isset($this->assetManifest->$file)) if (isset($this->assetManifest->$file))
$this->javascriptModules[] = $this->assetManifest->$file; $this->javascriptModules[] = $this->assetManifest->$file;
@ -299,7 +300,23 @@ class ModuleScriptCache
if (empty($this->javascriptModules)) if (empty($this->javascriptModules))
return ''; return '';
$html = ''; $tags = [];
if (defined('VITE_DEV_SERVER')) {
foreach ($this->javascriptModules as $module)
$tags[] = sprintf('<script type="module" src="%s"></script>',VITE_DEV_SERVER.'/'.$module);
} else {
foreach ($this->javascriptModules as $module)
$this->includeChunk($module, true);
foreach (array_unique($this->renderedCss) as $css)
$tags[] = sprintf('<link rel="stylesheet" href="%s" />', $this->GetLinkUrl($css));
foreach (array_unique($this->renderedJs) as $js)
$tags[] = sprintf('<script type="module" src="%s"></script>', $this->GetLinkUrl($js));
foreach (array_diff(array_unique($this->renderedPreload), $this->renderedJs) as $preload)
$tags[] = sprintf('<link rel="modulepreload" href="%s" />', $this->GetLinkUrl($preload));
}
return join("\n", $tags);
foreach ($this->javascriptModules as $module) { foreach ($this->javascriptModules as $module) {
if (is_object($module)) { if (is_object($module)) {
if (defined('VITE_DEV_SERVER')) { if (defined('VITE_DEV_SERVER')) {
@ -324,6 +341,32 @@ class ModuleScriptCache
return $html; return $html;
} }
private array $renderedCss = [];
private array $renderedJs = [];
private array $renderedPreload = [];
private function includeChunk(string $chunkName, bool $isRoot = false) : void
{
if (!isset($this->assetManifest->$chunkName))
return;
$manifestEntry = $this->assetManifest->$chunkName;
foreach ($manifestEntry->css as $cssFile)
$this->renderedCss[] = $cssFile;
foreach ($manifestEntry->imports as $import)
$this->includeChunk($import);
if ($isRoot)
$this->renderedJs[] = $manifestEntry->file;
else
$this->renderedPreload[] = $manifestEntry->file;
}
private function GetLinkUrl(string $chunkFile) {
if (str_starts_with($chunkFile, 'http:'))
return $chunkFile;
return '.'.$this->assetDir.'/'.$chunkFile;
}
/** /**
* @return string * @return string
*/ */

View File

@ -4,12 +4,12 @@
* SPDX-License-Identifier: AGPL-3.0-only * SPDX-License-Identifier: AGPL-3.0-only
*/ */
@import "basecomponent.css";
@import "autocomplete.css"; @import "autocomplete.css";
@import "checkbox.css";
@import "dialog.css"; @import "dialog.css";
@import "dropdown.css"; @import "dropdown.css";
@import "icons.css";
@import "listbox.css"; @import "listbox.css";
@import "multiselect.css";
.p-component-overlay { .p-component-overlay {
background-color: rgba(170,170,170,0.7); background-color: rgba(170,170,170,0.7);
@ -26,6 +26,6 @@
} }
.p-icon { .p-icon {
width: 1em; width: 1rem;
height: 1em; height: 1rem;
} }

View File

@ -105,4 +105,102 @@ input[type=text].p-autocomplete-dd-input {
.p-autocomplete-dd .p-autocomplete-dropdown svg { .p-autocomplete-dd .p-autocomplete-dropdown svg {
width: 14px; width: 14px;
height: 14px; height: 14px;
}
@layer primevue {
.p-autocomplete {
display: inline-flex;
}
.p-autocomplete-loader {
position: absolute;
top: 50%;
margin-top: -0.5rem;
}
.p-autocomplete-dd .p-autocomplete-input {
flex: 1 1 auto;
width: 1%;
}
.p-autocomplete-dd .p-autocomplete-input,
.p-autocomplete-dd .p-autocomplete-multiple-container {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
}
.p-autocomplete-dd .p-autocomplete-dropdown {
border-top-left-radius: 0;
border-bottom-left-radius: 0px;
}
.p-autocomplete .p-autocomplete-panel {
min-width: 100%;
}
.p-autocomplete-panel {
position: absolute;
overflow: auto;
top: 0;
left: 0;
}
.p-autocomplete-items {
margin: 0;
padding: 0;
list-style-type: none;
}
.p-autocomplete-item {
cursor: pointer;
white-space: nowrap;
position: relative;
overflow: hidden;
}
.p-autocomplete-multiple-container {
margin: 0;
padding: 0;
list-style-type: none;
cursor: text;
overflow: hidden;
display: flex;
align-items: center;
flex-wrap: wrap;
}
.p-autocomplete-token {
cursor: default;
display: inline-flex;
align-items: center;
flex: 0 0 auto;
}
.p-autocomplete-token-icon {
cursor: pointer;
}
.p-autocomplete-input-token {
flex: 1 1 auto;
display: inline-flex;
}
.p-autocomplete-input-token input {
border: 0 none;
outline: 0 none;
background-color: transparent;
margin: 0;
padding: 0;
box-shadow: none;
border-radius: 0;
width: 100%;
}
.p-fluid .p-autocomplete {
display: flex;
}
.p-fluid .p-autocomplete-dd .p-autocomplete-input {
width: 1%;
}
} }

View File

@ -0,0 +1,163 @@
@layer primevue {
.p-component, .p-component * {
box-sizing: border-box;
}
.p-hidden-space {
visibility: hidden;
}
.p-reset {
margin: 0;
padding: 0;
border: 0;
outline: 0;
text-decoration: none;
font-size: 100%;
list-style: none;
}
.p-disabled, .p-disabled * {
cursor: default;
pointer-events: none;
user-select: none;
}
.p-component-overlay {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.p-unselectable-text {
user-select: none;
}
.p-sr-only {
border: 0;
clip: rect(1px, 1px, 1px, 1px);
clip-path: inset(50%);
height: 1px;
margin: -1px;
overflow: hidden;
padding: 0;
position: absolute;
width: 1px;
word-wrap: normal;
}
.p-link {
text-align: left;
background-color: transparent;
margin: 0;
padding: 0;
border: none;
cursor: pointer;
user-select: none;
}
.p-link:disabled {
cursor: default;
}
/* Non vue overlay animations */
.p-connected-overlay {
opacity: 0;
transform: scaleY(0.8);
transition: transform .12s cubic-bezier(0, 0, 0.2, 1), opacity .12s cubic-bezier(0, 0, 0.2, 1);
}
.p-connected-overlay-visible {
opacity: 1;
transform: scaleY(1);
}
.p-connected-overlay-hidden {
opacity: 0;
transform: scaleY(1);
transition: opacity .1s linear;
}
/* Vue based overlay animations */
.p-connected-overlay-enter-from {
opacity: 0;
transform: scaleY(0.8);
}
.p-connected-overlay-leave-to {
opacity: 0;
}
.p-connected-overlay-enter-active {
transition: transform .12s cubic-bezier(0, 0, 0.2, 1), opacity .12s cubic-bezier(0, 0, 0.2, 1);
}
.p-connected-overlay-leave-active {
transition: opacity .1s linear;
}
/* Toggleable Content */
.p-toggleable-content-enter-from,
.p-toggleable-content-leave-to {
max-height: 0;
}
.p-toggleable-content-enter-to,
.p-toggleable-content-leave-from {
max-height: 1000px;
}
.p-toggleable-content-leave-active {
overflow: hidden;
transition: max-height 0.45s cubic-bezier(0, 1, 0, 1);
}
.p-toggleable-content-enter-active {
overflow: hidden;
transition: max-height 1s ease-in-out;
}
.p-button {
display: inline-flex;
cursor: pointer;
user-select: none;
align-items: center;
vertical-align: bottom;
text-align: center;
overflow: hidden;
position: relative;
}
.p-button-label {
flex: 1 1 auto;
}
.p-button-icon-right {
order: 1;
}
.p-button:disabled {
cursor: default;
}
.p-button-icon-only {
justify-content: center;
}
.p-button-icon-only .p-button-label {
visibility: hidden;
width: 0;
flex: 0 0 auto;
}
.p-button-vertical {
flex-direction: column;
}
.p-button-icon-bottom {
order: 2;
}
.p-buttonset .p-button {
margin: 0;
}
.p-buttonset .p-button:not(:last-child), .p-buttonset .p-button:not(:last-child):hover {
border-right: 0 none;
}
.p-buttonset .p-button:not(:first-of-type):not(:last-of-type) {
border-radius: 0;
}
.p-buttonset .p-button:first-of-type:not(:only-of-type) {
border-top-right-radius: 0;
border-bottom-right-radius: 0;
}
.p-buttonset .p-button:last-of-type:not(:only-of-type) {
border-top-left-radius: 0;
border-bottom-left-radius: 0;
}
.p-buttonset .p-button:focus {
position: relative;
z-index: 1;
}
.p-fluid .p-inputtext {
width: 100%;
}
.p-fluid .p-input-icon-left,
.p-fluid .p-input-icon-right {
width: 100%;
}
}

View File

@ -31,4 +31,136 @@
text-align: right; text-align: right;
border-bottom-right-radius: 4px; border-bottom-right-radius: 4px;
border-bottom-left-radius: 4px; border-bottom-left-radius: 4px;
}
@layer primevue {
.p-dialog-mask.p-component-overlay {
pointer-events: auto;
}
.p-dialog {
max-height: 90%;
transform: scale(1);
}
.p-dialog-content {
overflow-y: auto;
}
.p-dialog-header {
display: flex;
align-items: center;
justify-content: space-between;
flex-shrink: 0;
}
.p-dialog-footer {
flex-shrink: 0;
}
.p-dialog .p-dialog-header-icons {
display: flex;
align-items: center;
}
.p-dialog .p-dialog-header-icon {
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
position: relative;
}
/* Fluid */
.p-fluid .p-dialog-footer .p-button {
width: auto;
}
/* Animation */
/* Center */
.p-dialog-enter-active {
transition: all 150ms cubic-bezier(0, 0, 0.2, 1);
}
.p-dialog-leave-active {
transition: all 150ms cubic-bezier(0.4, 0, 0.2, 1);
}
.p-dialog-enter-from,
.p-dialog-leave-to {
opacity: 0;
transform: scale(0.7);
}
/* Top, Bottom, Left, Right, Top* and Bottom* */
.p-dialog-top .p-dialog,
.p-dialog-bottom .p-dialog,
.p-dialog-left .p-dialog,
.p-dialog-right .p-dialog,
.p-dialog-topleft .p-dialog,
.p-dialog-topright .p-dialog,
.p-dialog-bottomleft .p-dialog,
.p-dialog-bottomright .p-dialog {
margin: 0.75rem;
transform: translate3d(0px, 0px, 0px);
}
.p-dialog-top .p-dialog-enter-active,
.p-dialog-top .p-dialog-leave-active,
.p-dialog-bottom .p-dialog-enter-active,
.p-dialog-bottom .p-dialog-leave-active,
.p-dialog-left .p-dialog-enter-active,
.p-dialog-left .p-dialog-leave-active,
.p-dialog-right .p-dialog-enter-active,
.p-dialog-right .p-dialog-leave-active,
.p-dialog-topleft .p-dialog-enter-active,
.p-dialog-topleft .p-dialog-leave-active,
.p-dialog-topright .p-dialog-enter-active,
.p-dialog-topright .p-dialog-leave-active,
.p-dialog-bottomleft .p-dialog-enter-active,
.p-dialog-bottomleft .p-dialog-leave-active,
.p-dialog-bottomright .p-dialog-enter-active,
.p-dialog-bottomright .p-dialog-leave-active {
transition: all 0.3s ease-out;
}
.p-dialog-top .p-dialog-enter-from,
.p-dialog-top .p-dialog-leave-to {
transform: translate3d(0px, -100%, 0px);
}
.p-dialog-bottom .p-dialog-enter-from,
.p-dialog-bottom .p-dialog-leave-to {
transform: translate3d(0px, 100%, 0px);
}
.p-dialog-left .p-dialog-enter-from,
.p-dialog-left .p-dialog-leave-to,
.p-dialog-topleft .p-dialog-enter-from,
.p-dialog-topleft .p-dialog-leave-to,
.p-dialog-bottomleft .p-dialog-enter-from,
.p-dialog-bottomleft .p-dialog-leave-to {
transform: translate3d(-100%, 0px, 0px);
}
.p-dialog-right .p-dialog-enter-from,
.p-dialog-right .p-dialog-leave-to,
.p-dialog-topright .p-dialog-enter-from,
.p-dialog-topright .p-dialog-leave-to,
.p-dialog-bottomright .p-dialog-enter-from,
.p-dialog-bottomright .p-dialog-leave-to {
transform: translate3d(100%, 0px, 0px);
}
/* Maximize */
.p-dialog-maximized {
width: 100vw !important;
height: 100vh !important;
top: 0px !important;
left: 0px !important;
max-height: 100%;
height: 100%;
}
.p-dialog-maximized .p-dialog-content {
flex-grow: 1;
}
.p-confirm-dialog .p-dialog-content {
display: flex;
align-items: center;
}
} }

View File

@ -4,6 +4,87 @@
* SPDX-License-Identifier: AGPL-3.0-only * SPDX-License-Identifier: AGPL-3.0-only
*/ */
@layer primevue {
.p-dropdown {
display: inline-flex;
cursor: pointer;
position: relative;
user-select: none;
}
.p-dropdown-clear-icon {
position: absolute;
top: 50%;
margin-top: -0.5rem;
}
.p-dropdown-trigger {
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
}
.p-dropdown-label {
display: block;
white-space: nowrap;
overflow: hidden;
flex: 1 1 auto;
width: 1%;
text-overflow: ellipsis;
cursor: pointer;
}
.p-dropdown-label-empty {
overflow: hidden;
opacity: 0;
}
input.p-dropdown-label {
cursor: default;
}
.p-dropdown .p-dropdown-panel {
min-width: 100%;
}
.p-dropdown-panel {
position: absolute;
top: 0;
left: 0;
}
.p-dropdown-items-wrapper {
overflow: auto;
}
.p-dropdown-item {
cursor: pointer;
font-weight: normal;
white-space: nowrap;
position: relative;
overflow: hidden;
display: flex;
align-items: center;
}
.p-dropdown-item-group {
cursor: auto;
}
.p-dropdown-items {
margin: 0;
padding: 0;
list-style-type: none;
}
.p-dropdown-filter {
width: 100%;
}
.p-dropdown-filter-container {
position: relative;
}
.p-dropdown-filter-icon {
position: absolute;
top: 50%;
margin-top: -0.5rem;
}
.p-fluid .p-dropdown {
display: flex;
}
.p-fluid .p-dropdown .p-dropdown-label {
width: 1%;
}
}
.p-dropdown { .p-dropdown {
background: #ffffff; background: #ffffff;
border: 1px solid #ced4da; border: 1px solid #ced4da;

View File

@ -4,6 +4,36 @@
* SPDX-License-Identifier: AGPL-3.0-only * SPDX-License-Identifier: AGPL-3.0-only
*/ */
@layer primevue {
.p-listbox-list-wrapper {
overflow: auto;
}
.p-listbox-list {
list-style-type: none;
margin: 0;
padding: 0;
}
.p-listbox-item {
cursor: pointer;
position: relative;
overflow: hidden;
}
.p-listbox-item-group {
cursor: auto;
}
.p-listbox-filter-container {
position: relative;
}
.p-listbox-filter-icon {
position: absolute;
top: 50%;
margin-top: -0.5rem;
}
.p-listbox-filter {
width: 100%;
}
}
.p-listbox { .p-listbox {
background: #ffffff; background: #ffffff;
color: #6d6d6f; color: #6d6d6f;

View File

@ -2,19 +2,49 @@
// //
// SPDX-License-Identifier: AGPL-3.0-only // SPDX-License-Identifier: AGPL-3.0-only
import glob from 'glob'; import {globSync} from 'glob';
import path from 'path'; import * as path from 'path';
import vue from '@vitejs/plugin-vue'; import vue from '@vitejs/plugin-vue';
const moduleInputs = glob.sync('classes/Modules/*/www/js/entry.{js,jsx}') const globpattern = [
.map(file => ['modules/'+file.split('/')[2], file]); 'classes/Modules/*/www/js/?(*.)entry.{js,ts}',
'www/themes/*/js/?(*.)entry.{js,ts}'
];
const inputs = globSync(globpattern)
.map(file => {
const regex = /(?<prefix>themes|Modules)\/(?<name>\w+)\/(\w+\/)*((?<entry>\w+)\.)?entry\.(js|ts)$/;
const match = file.match(regex);
console.log(match);
let entryname = file;
if (match) {
entryname = [match.groups.prefix.toLowerCase(), match.groups.name].join('/');
if (match.groups.entry && match.groups.entry.toLowerCase() !== match.groups.name.toLowerCase())
entryname += '-'+match.groups.entry;
}
return [entryname, file];
})
/** @type {import('vite').UserConfig} */ /** @type {import('vite').UserConfig} */
export default { export default {
build: { build: {
rollupOptions: { rollupOptions: {
input: { input: {
...Object.fromEntries(moduleInputs) ...Object.fromEntries(inputs)
},
output: {
assetFileNames: function(assetInfo) {
console.log(assetInfo);
return 'assets/[name]-[hash][extname]';
},
entryFileNames: function(chunkInfo) {
console.log(chunkInfo);
return '[name]-[hash].js';
},
chunkFileNames: function (chunkInfo) {
console.log(chunkInfo);
return '[name]-[hash].js';
}
} }
}, },
manifest: true, manifest: true,

View File

@ -1,3 +1,5 @@
@layer reset, primevue;
body { body {
font-size: 12px; font-size: 12px;
font-family: 'Inter', Arial, Helvetica, sans-serif; font-family: 'Inter', Arial, Helvetica, sans-serif;
@ -878,15 +880,12 @@ ul.menu > li > a {
} }
#main.fixed .menu-wrapper { #main.fixed .menu-wrapper {
width: calc(100% - var(--sidebar-not-collapsed-width)); width: calc(100% - 72px);
z-index: 950; z-index: 950;
position: fixed; position: fixed;
top: 0; top: 0;
border-bottom: 3px solid #2DCA73; border-bottom: 3px solid #2DCA73;
} }
#sidebar.collapsed + #main.fixed .menu-wrapper {
width: calc(100% - var(--sidebar-collapsed-width));
}
#main.fixed .menu-wrapper #current{ #main.fixed .menu-wrapper #current{
padding-top: 10px; padding-top: 10px;
@ -1809,11 +1808,10 @@ a.startpage {
::-ms-input-placeholder { /* Microsoft Edge */ ::-ms-input-placeholder { /* Microsoft Edge */
color: #BBB; color: #BBB;
} }
:placeholder { /* Modern Browser */ ::placeholder { /* Modern Browser */
color: #F00; color: #BBB;
opacity: 1; /* Firefox */ opacity: 1; /* Firefox */
} }
input.ui-autocomplete-input::-webkit-input-placeholder { input.ui-autocomplete-input::-webkit-input-placeholder {
color: #999; color: #999;
opacity: 1; opacity: 1;
@ -2408,10 +2406,6 @@ ul.tag-editor {
border-color: var(--textfield-border); border-color: var(--textfield-border);
border-radius: 7px; border-radius: 7px;
padding: 0px !important; padding: 0px !important;
min-height: 300px;
height: 300px;
resize: vertical;
overflow: hidden;
} }
.ticket_nachricht_box fieldset { .ticket_nachricht_box fieldset {
@ -2420,8 +2414,8 @@ ul.tag-editor {
.ticket_text { .ticket_text {
width: 100%; width: 100%;
height: 100%;
border: none; border: none;
height: 300px;
} }
.ui-button-icon, .ui-button-icon,
@ -4876,8 +4870,3 @@ tilegrid
padding: 0; padding: 0;
margin: 0; margin: 0;
} }
input:placeholder-shown.placeholder_warning {
background-color: var(--warning);
}