mirror of
https://github.com/Part-DB/Part-DB-server.git
synced 2025-06-21 09:35:49 +02:00
Implemented a new darkmode selector using bootstrap 5.3 color mode
This commit is contained in:
parent
0aec9419ec
commit
6df65a0b9d
15 changed files with 1465 additions and 1412 deletions
|
@ -18,43 +18,118 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {Controller} from "@hotwired/stimulus";
|
import {Controller} from "@hotwired/stimulus";
|
||||||
import Darkmode from "darkmode-js/src";
|
|
||||||
import "darkmode-js"
|
|
||||||
|
|
||||||
export default class extends Controller {
|
export default class extends Controller {
|
||||||
|
|
||||||
_darkmode;
|
|
||||||
|
|
||||||
connect() {
|
connect() {
|
||||||
if (typeof window.getComputedStyle(document.body).mixBlendMode == 'undefined') {
|
this.setMode(this.getMode());
|
||||||
console.warn("The browser does not support mix blend mode. Darkmode will not work.");
|
document.querySelectorAll('input[name="darkmode"]').forEach((radio) => {
|
||||||
|
radio.addEventListener('change', this._radioChanged.bind(this));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event listener for the change of radio buttons
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
_radioChanged(event) {
|
||||||
|
const new_mode = this.getSelectedMode();
|
||||||
|
this.setMode(new_mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the current mode from the local storage
|
||||||
|
* @return {'dark', 'light', 'auto'}
|
||||||
|
*/
|
||||||
|
getMode() {
|
||||||
|
return localStorage.getItem('darkmode') ?? 'auto';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the mode in the local storage and apply it and change the state of the radio buttons
|
||||||
|
* @param mode
|
||||||
|
*/
|
||||||
|
setMode(mode) {
|
||||||
|
if (mode !== 'dark' && mode !== 'light' && mode !== 'auto') {
|
||||||
|
console.warn('Invalid darkmode mode: ' + mode);
|
||||||
|
mode = 'auto';
|
||||||
|
}
|
||||||
|
|
||||||
|
localStorage.setItem('darkmode', mode);
|
||||||
|
|
||||||
|
this.setButtonMode(mode);
|
||||||
|
|
||||||
|
if (mode === 'auto') {
|
||||||
|
this._setDarkmodeAuto();
|
||||||
|
} else if (mode === 'dark') {
|
||||||
|
this._enableDarkmode();
|
||||||
|
} else if (mode === 'light') {
|
||||||
|
this._disableDarkmode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the selected mode via the radio buttons
|
||||||
|
* @return {'dark', 'light', 'auto'}
|
||||||
|
*/
|
||||||
|
getSelectedMode() {
|
||||||
|
return document.querySelector('input[name="darkmode"]:checked').value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the state of the radio buttons
|
||||||
|
* @param mode
|
||||||
|
*/
|
||||||
|
setButtonMode(mode) {
|
||||||
|
document.querySelector('input[name="darkmode"][value="' + mode + '"]').checked = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable darkmode by adding the data-bs-theme="dark" to the html tag
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
_enableDarkmode() {
|
||||||
|
//Add data-bs-theme="dark" to the html tag
|
||||||
|
document.documentElement.setAttribute('data-bs-theme', 'dark');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disable darkmode by adding the data-bs-theme="light" to the html tag
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
_disableDarkmode() {
|
||||||
|
//Set data-bs-theme to light
|
||||||
|
document.documentElement.setAttribute('data-bs-theme', 'light');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the darkmode to auto and enable/disable it depending on the system settings, also add
|
||||||
|
* an event listener to change the darkmode if the system settings change
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
_setDarkmodeAuto() {
|
||||||
|
if (this.getMode() !== 'auto') {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
if (window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches) {
|
||||||
const darkmode = new Darkmode();
|
this._enableDarkmode();
|
||||||
this._darkmode = darkmode;
|
} else {
|
||||||
|
this._disableDarkmode();
|
||||||
//Unhide darkmode button
|
|
||||||
this._showWidget();
|
|
||||||
|
|
||||||
//Set the switch according to our current darkmode state
|
|
||||||
const toggler = document.getElementById("toggleDarkmode");
|
|
||||||
toggler.checked = darkmode.isActivated();
|
|
||||||
}
|
|
||||||
catch (e)
|
|
||||||
{
|
|
||||||
console.error(e);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', event => {
|
||||||
|
console.log('Prefered color scheme changed to ' + event.matches ? 'dark' : 'light');
|
||||||
|
this._setDarkmodeAuto();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
_showWidget() {
|
/**
|
||||||
this.element.classList.remove('hidden');
|
* Check if darkmode is activated
|
||||||
}
|
* @return {boolean}
|
||||||
|
*/
|
||||||
toggleDarkmode() {
|
isDarkmodeActivated() {
|
||||||
this._darkmode.toggle();
|
return document.documentElement.getAttribute('data-bs-theme') === 'dark';
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,37 +0,0 @@
|
||||||
/*
|
|
||||||
* This file is part of Part-DB (https://github.com/Part-DB/Part-DB-symfony).
|
|
||||||
*
|
|
||||||
* Copyright (C) 2019 - 2022 Jan Böhmer (https://github.com/jbtronics)
|
|
||||||
*
|
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as published
|
|
||||||
* by the Free Software Foundation, either version 3 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 Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
.darkmode-layer {
|
|
||||||
z-index: 2020;
|
|
||||||
}
|
|
||||||
|
|
||||||
/** If darkmode is enabled revert the blening for images and videos, as these should be shown not inverted */
|
|
||||||
.darkmode--activated img,
|
|
||||||
.darkmode--activated video,
|
|
||||||
.darkmode--activated object {
|
|
||||||
mix-blend-mode: difference;
|
|
||||||
}
|
|
||||||
|
|
||||||
.darkmode--activated .hoverpic:hover {
|
|
||||||
background: black;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tools-ic-logos img {
|
|
||||||
mix-blend-mode: normal;
|
|
||||||
}
|
|
|
@ -22,7 +22,6 @@
|
||||||
|
|
||||||
import '../css/app/layout.css';
|
import '../css/app/layout.css';
|
||||||
import '../css/app/helpers.css';
|
import '../css/app/helpers.css';
|
||||||
import '../css/app/darkmode.css';
|
|
||||||
import '../css/app/tables.css';
|
import '../css/app/tables.css';
|
||||||
import '../css/app/bs-overrides.css';
|
import '../css/app/bs-overrides.css';
|
||||||
import '../css/app/treeview.css';
|
import '../css/app/treeview.css';
|
||||||
|
|
|
@ -62,7 +62,7 @@ class RegisterEventHelper {
|
||||||
this.registerLoadHandler(() => {
|
this.registerLoadHandler(() => {
|
||||||
$(".tooltip").remove();
|
$(".tooltip").remove();
|
||||||
//Exclude dropdown buttons from tooltips, otherwise we run into endless errors from bootstrap (bootstrap.esm.js:614 Bootstrap doesn't allow more than one instance per element. Bound instance: bs.dropdown.)
|
//Exclude dropdown buttons from tooltips, otherwise we run into endless errors from bootstrap (bootstrap.esm.js:614 Bootstrap doesn't allow more than one instance per element. Bound instance: bs.dropdown.)
|
||||||
$('a[title], button[title]:not([data-bs-toggle="dropdown"]), p[title], span[title], h6[title], h3[title], i.fas[title]')
|
$('a[title], label[title], button[title]:not([data-bs-toggle="dropdown"]), p[title], span[title], h6[title], h3[title], i.fas[title]')
|
||||||
//@ts-ignore
|
//@ts-ignore
|
||||||
.tooltip("hide").tooltip({container: "body", placement: "auto", boundary: 'window'});
|
.tooltip("hide").tooltip({container: "body", placement: "auto", boundary: 'window'});
|
||||||
});
|
});
|
||||||
|
|
|
@ -66,7 +66,6 @@
|
||||||
"bs-custom-file-input": "^1.3.4",
|
"bs-custom-file-input": "^1.3.4",
|
||||||
"clipboard": "^2.0.4",
|
"clipboard": "^2.0.4",
|
||||||
"compression-webpack-plugin": "^10.0.0",
|
"compression-webpack-plugin": "^10.0.0",
|
||||||
"darkmode-js": "^1.5.0",
|
|
||||||
"datatables.net-bs5": "^1.10.20",
|
"datatables.net-bs5": "^1.10.20",
|
||||||
"datatables.net-buttons-bs5": "^2.2.2",
|
"datatables.net-buttons-bs5": "^2.2.2",
|
||||||
"datatables.net-colreorder-bs5": "^1.5.1",
|
"datatables.net-colreorder-bs5": "^1.5.1",
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{% import "helper.twig" as helper %}
|
{% import "helper.twig" as helper %}
|
||||||
|
|
||||||
<nav class="navbar navbar-expand-md navbar-light bg-light border-bottom shadow-sm fixed-top py-0" id="navbar">
|
<nav class="navbar navbar-expand-md bg-body-tertiary border-bottom shadow-sm fixed-top py-0" id="navbar">
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
<button type="button" class="navbar-toggler" data-bs-toggle="collapse" data-bs-target="#sidebar-container">
|
<button type="button" class="navbar-toggler" data-bs-toggle="collapse" data-bs-target="#sidebar-container">
|
||||||
<span class="visually-hidden">{% trans %}sidebar.toggle{% endtrans %}</span>
|
<span class="visually-hidden">{% trans %}sidebar.toggle{% endtrans %}</span>
|
||||||
|
@ -61,11 +61,15 @@
|
||||||
aria-hidden="true"></i> {% trans %}user.login{% endtrans %}</a>
|
aria-hidden="true"></i> {% trans %}user.login{% endtrans %}</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<li role="separator" class="dropdown-divider" id="toggleDarkmodeSeparator"></li>
|
<li role="separator" class="dropdown-divider" id="toggleDarkmodeSeparator"></li>
|
||||||
<div class="px-4 px-3" id="toggleDarkmodeContainer hidden" {{ stimulus_controller('common/darkmode') }}>
|
<div class="px-4 py-0 d-flex justify-content-between align-items-baseline">
|
||||||
<div class="form-check form-switch">
|
<span>{% trans %}ui.toggle_darkmode{% endtrans %}</span>
|
||||||
<input type="checkbox" class="form-check-input" id="toggleDarkmode" {{ stimulus_action('common/darkmode', 'toggleDarkmode', 'change') }}>
|
<div class="btn-group" role="group" {{ stimulus_controller('common/darkmode') }}>
|
||||||
<label class="form-check-label"
|
<input type="radio" class="btn-check" name="darkmode" id="darkmode-light" autocomplete="off" value="light">
|
||||||
for="toggleDarkmode">{% trans %}ui.toggle_darkmode{% endtrans %}</label>
|
<label class="btn btn-outline-secondary" for="darkmode-light" title="{% trans %}ui.darkmode.light{% endtrans %}"><i class="fa-solid fa-sun"></i></label>
|
||||||
|
<input type="radio" class="btn-check" name="darkmode" id="darkmode-dark" autocomplete="off" value="dark">
|
||||||
|
<label class="btn btn-outline-secondary" for="darkmode-dark" title="{% trans %}ui.darkmode.dark{% endtrans %}"><i class="fa-solid fa-moon"></i></label>
|
||||||
|
<input type="radio" class="btn-check" name="darkmode" id="darkmode-auto" autocomplete="off" value="auto" checked>
|
||||||
|
<label class="btn btn-outline-secondary" for="darkmode-auto" title="{% trans %}ui.darkmode.auto{% endtrans %}"><i class="fa-solid fa-circle-half-stroke"></i></label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<li role="separator" class="dropdown-divider"></li>
|
<li role="separator" class="dropdown-divider"></li>
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
<ul class="dropdown-menu" aria-labelledby="dropdownCat">
|
<ul class="dropdown-menu" aria-labelledby="dropdownCat">
|
||||||
{{ _self.sidebar_dropdown('tree-categories') }}
|
{{ _self.sidebar_dropdown('tree-categories') }}
|
||||||
</ul>
|
</ul>
|
||||||
<input type="search" class="form-control bg-light border-0" placeholder="{% trans %}search.placeholder{% endtrans %}" {{ stimulus_action('elements/sidebar_tree', 'searchInput') }}>
|
<input type="search" class="form-control bg-body-tertiary border-0" placeholder="{% trans %}search.placeholder{% endtrans %}" {{ stimulus_action('elements/sidebar_tree', 'searchInput') }}>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="{{ id }}Tree" {{ stimulus_target('elements/sidebar_tree', 'tree') }}></div>
|
<div id="{{ id }}Tree" {{ stimulus_target('elements/sidebar_tree', 'tree') }}></div>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{% extends "base.html.twig" %}
|
{% extends "base.html.twig" %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="rounded p-4" style="background-color: var(--bs-gray-300);">
|
<div class="rounded p-4 bg-body-secondary">
|
||||||
<h1 class="display-3">{{ partdb_title }}</h1>
|
<h1 class="display-3">{{ partdb_title }}</h1>
|
||||||
<h4>
|
<h4>
|
||||||
{% trans %}version.caption{% endtrans %}: {{ shivas_app_version }}
|
{% trans %}version.caption{% endtrans %}: {{ shivas_app_version }}
|
||||||
|
|
|
@ -42,7 +42,7 @@
|
||||||
<td>
|
<td>
|
||||||
<h6>
|
<h6>
|
||||||
{% if lot.owner %}
|
{% if lot.owner %}
|
||||||
<span class="badge bg-light mb-1" title="{% trans %}part_lot.owner{% endtrans %}">
|
<span class="badge bg-body-tertiary mb-1" title="{% trans %}part_lot.owner{% endtrans %}">
|
||||||
{{ helper.user_icon_link(lot.owner) }}
|
{{ helper.user_icon_link(lot.owner) }}
|
||||||
</span><br>
|
</span><br>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
|
@ -12,10 +12,10 @@
|
||||||
{# @var pic App\Entity\Attachments\Attachment #}
|
{# @var pic App\Entity\Attachments\Attachment #}
|
||||||
<div class="carousel-item {% if loop.first %}active{% endif %}">
|
<div class="carousel-item {% if loop.first %}active{% endif %}">
|
||||||
<a href="{{ entity_url(pic, 'file_view') }}" data-turbo="false" target="_blank" rel="noopener">
|
<a href="{{ entity_url(pic, 'file_view') }}" data-turbo="false" target="_blank" rel="noopener">
|
||||||
<img class="d-block w-100 img-fluid img-thumbnail bg-light part-info-image" src="{{ entity_url(pic, 'file_view') }}" alt="">
|
<img class="d-block w-100 img-fluid img-thumbnail bg-body-tertiary part-info-image" src="{{ entity_url(pic, 'file_view') }}" alt="">
|
||||||
<div class="mask"></div>
|
<div class="mask"></div>
|
||||||
<div class="carousel-caption-hover">
|
<div class="carousel-caption-hover">
|
||||||
<div class="carousel-caption">
|
<div class="carousel-caption text-body ">
|
||||||
<div><b>{{ pic.name }}</b></div>
|
<div><b>{{ pic.name }}</b></div>
|
||||||
<div>{% if pic.filename %}({{ pic.filename }}) {% endif %}</div>
|
<div>{% if pic.filename %}({{ pic.filename }}) {% endif %}</div>
|
||||||
<div>{{ entity_type_label(pic.element) }}</div>
|
<div>{{ entity_type_label(pic.element) }}</div>
|
||||||
|
@ -38,5 +38,5 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% else %}
|
{% else %}
|
||||||
<img src="{{ asset('img/part_placeholder.svg') }}" class="img-fluid img-thumbnail bg-light mb-2" alt="Part main image" height="300" width="300">
|
<img src="{{ asset('img/part_placeholder.svg') }}" class="img-fluid img-thumbnail bg-body-tertiary mb-2" alt="Part main image" height="300" width="300">
|
||||||
{% endif %}
|
{% endif %}
|
|
@ -6,10 +6,10 @@
|
||||||
<div class="col-md-3 col-lg-4 col-4 mt-auto mb-auto">
|
<div class="col-md-3 col-lg-4 col-4 mt-auto mb-auto">
|
||||||
{% if project.masterPictureAttachment %}
|
{% if project.masterPictureAttachment %}
|
||||||
<a href="{{ entity_url(project.masterPictureAttachment, 'file_view') }}" data-turbo="false" target="_blank" rel="noopener">
|
<a href="{{ entity_url(project.masterPictureAttachment, 'file_view') }}" data-turbo="false" target="_blank" rel="noopener">
|
||||||
<img class="d-block w-100 img-fluid img-thumbnail bg-light part-info-image" src="{{ entity_url(project.masterPictureAttachment, 'file_view') }}" alt="">
|
<img class="d-block w-100 img-fluid img-thumbnail bg-body-tertiary part-info-image" src="{{ entity_url(project.masterPictureAttachment, 'file_view') }}" alt="">
|
||||||
</a>
|
</a>
|
||||||
{% else %}
|
{% else %}
|
||||||
<img src="{{ asset('img/part_placeholder.svg') }}" class="img-fluid img-thumbnail bg-light mb-2 " alt="Part main image" height="300" width="300">
|
<img src="{{ asset('img/part_placeholder.svg') }}" class="img-fluid img-thumbnail bg-body-tertiary mb-2 " alt="Part main image" height="300" width="300">
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-9 col-lg-8 col-7">
|
<div class="col-md-9 col-lg-8 col-7">
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,14 +1,14 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<xliff xmlns="urn:oasis:names:tc:xliff:document:2.0" version="2.0" srcLang="en" trgLang="de">
|
<xliff xmlns="urn:oasis:names:tc:xliff:document:2.0" version="2.0" srcLang="en" trgLang="de">
|
||||||
<file id="security.en">
|
<file id="security.de">
|
||||||
<unit id="aazoCks" name="user.login_error.user_disabled">
|
<unit id="aazoCks" name="user.login_error.user_disabled">
|
||||||
<segment state="translated">
|
<segment>
|
||||||
<source>user.login_error.user_disabled</source>
|
<source>user.login_error.user_disabled</source>
|
||||||
<target>Ihr Account ist deaktiviert! Kontaktiere einen Administrator, wenn Sie denken, dass dies ein Fehler ist.</target>
|
<target>Ihr Account ist deaktiviert! Kontaktiere einen Administrator, wenn Sie denken, dass dies ein Fehler ist.</target>
|
||||||
</segment>
|
</segment>
|
||||||
</unit>
|
</unit>
|
||||||
<unit id="Dpb9AmY" name="saml.error.cannot_login_local_user_per_saml">
|
<unit id="Dpb9AmY" name="saml.error.cannot_login_local_user_per_saml">
|
||||||
<segment state="translated">
|
<segment>
|
||||||
<source>saml.error.cannot_login_local_user_per_saml</source>
|
<source>saml.error.cannot_login_local_user_per_saml</source>
|
||||||
<target>Sie können sich per SSO nicht als lokaler Nutzer einloggen! Nutzen Sie stattdessen ihr lokales Passwort.</target>
|
<target>Sie können sich per SSO nicht als lokaler Nutzer einloggen! Nutzen Sie stattdessen ihr lokales Passwort.</target>
|
||||||
</segment>
|
</segment>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<xliff xmlns="urn:oasis:names:tc:xliff:document:2.0" version="2.0" srcLang="en" trgLang="de">
|
<xliff xmlns="urn:oasis:names:tc:xliff:document:2.0" version="2.0" srcLang="en" trgLang="de">
|
||||||
<file id="validators.en">
|
<file id="validators.de">
|
||||||
<unit id="xevSdCK" name="part.master_attachment.must_be_picture">
|
<unit id="xevSdCK" name="part.master_attachment.must_be_picture">
|
||||||
<notes>
|
<notes>
|
||||||
<note category="file-source" priority="1">Part-DB1\src\Entity\Attachments\AttachmentContainingDBElement.php:0</note>
|
<note category="file-source" priority="1">Part-DB1\src\Entity\Attachments\AttachmentContainingDBElement.php:0</note>
|
||||||
|
@ -37,7 +37,7 @@
|
||||||
<note priority="1">Part-DB1\src\Entity\UserSystem\Group.php:0</note>
|
<note priority="1">Part-DB1\src\Entity\UserSystem\Group.php:0</note>
|
||||||
<note priority="1">Part-DB1\src\Entity\UserSystem\User.php:0</note>
|
<note priority="1">Part-DB1\src\Entity\UserSystem\User.php:0</note>
|
||||||
</notes>
|
</notes>
|
||||||
<segment state="translated">
|
<segment>
|
||||||
<source>part.master_attachment.must_be_picture</source>
|
<source>part.master_attachment.must_be_picture</source>
|
||||||
<target>Der Vorschauanhang muss ein gültiges Bild sein!</target>
|
<target>Der Vorschauanhang muss ein gültiges Bild sein!</target>
|
||||||
</segment>
|
</segment>
|
||||||
|
@ -82,7 +82,7 @@
|
||||||
<note priority="1">src\Entity\StructuralDBElement.php:0</note>
|
<note priority="1">src\Entity\StructuralDBElement.php:0</note>
|
||||||
<note priority="1">src\Entity\Supplier.php:0</note>
|
<note priority="1">src\Entity\Supplier.php:0</note>
|
||||||
</notes>
|
</notes>
|
||||||
<segment state="translated">
|
<segment>
|
||||||
<source>structural.entity.unique_name</source>
|
<source>structural.entity.unique_name</source>
|
||||||
<target>Es kann auf jeder Ebene nur ein Objekt mit dem gleichem Namen geben!</target>
|
<target>Es kann auf jeder Ebene nur ein Objekt mit dem gleichem Namen geben!</target>
|
||||||
</segment>
|
</segment>
|
||||||
|
@ -102,7 +102,7 @@
|
||||||
<note category="file-source" priority="1">Part-DB1\src\Entity\Parameters\StorelocationParameter.php:0</note>
|
<note category="file-source" priority="1">Part-DB1\src\Entity\Parameters\StorelocationParameter.php:0</note>
|
||||||
<note category="file-source" priority="1">Part-DB1\src\Entity\Parameters\SupplierParameter.php:0</note>
|
<note category="file-source" priority="1">Part-DB1\src\Entity\Parameters\SupplierParameter.php:0</note>
|
||||||
</notes>
|
</notes>
|
||||||
<segment state="translated">
|
<segment>
|
||||||
<source>parameters.validator.min_lesser_typical</source>
|
<source>parameters.validator.min_lesser_typical</source>
|
||||||
<target>Wert muss kleiner oder gleich als der typische Wert sein ({{ compared_value }}).</target>
|
<target>Wert muss kleiner oder gleich als der typische Wert sein ({{ compared_value }}).</target>
|
||||||
</segment>
|
</segment>
|
||||||
|
@ -122,7 +122,7 @@
|
||||||
<note category="file-source" priority="1">Part-DB1\src\Entity\Parameters\StorelocationParameter.php:0</note>
|
<note category="file-source" priority="1">Part-DB1\src\Entity\Parameters\StorelocationParameter.php:0</note>
|
||||||
<note category="file-source" priority="1">Part-DB1\src\Entity\Parameters\SupplierParameter.php:0</note>
|
<note category="file-source" priority="1">Part-DB1\src\Entity\Parameters\SupplierParameter.php:0</note>
|
||||||
</notes>
|
</notes>
|
||||||
<segment state="translated">
|
<segment>
|
||||||
<source>parameters.validator.min_lesser_max</source>
|
<source>parameters.validator.min_lesser_max</source>
|
||||||
<target>Wert muss kleiner als der Maximalwert sein ({{ compared_value }}).</target>
|
<target>Wert muss kleiner als der Maximalwert sein ({{ compared_value }}).</target>
|
||||||
</segment>
|
</segment>
|
||||||
|
@ -142,7 +142,7 @@
|
||||||
<note category="file-source" priority="1">Part-DB1\src\Entity\Parameters\StorelocationParameter.php:0</note>
|
<note category="file-source" priority="1">Part-DB1\src\Entity\Parameters\StorelocationParameter.php:0</note>
|
||||||
<note category="file-source" priority="1">Part-DB1\src\Entity\Parameters\SupplierParameter.php:0</note>
|
<note category="file-source" priority="1">Part-DB1\src\Entity\Parameters\SupplierParameter.php:0</note>
|
||||||
</notes>
|
</notes>
|
||||||
<segment state="translated">
|
<segment>
|
||||||
<source>parameters.validator.max_greater_typical</source>
|
<source>parameters.validator.max_greater_typical</source>
|
||||||
<target>Wert muss größer oder gleich dem typischen Wert sein ({{ compared_value }}).</target>
|
<target>Wert muss größer oder gleich dem typischen Wert sein ({{ compared_value }}).</target>
|
||||||
</segment>
|
</segment>
|
||||||
|
@ -152,7 +152,7 @@
|
||||||
<note category="file-source" priority="1">Part-DB1\src\Entity\UserSystem\User.php:0</note>
|
<note category="file-source" priority="1">Part-DB1\src\Entity\UserSystem\User.php:0</note>
|
||||||
<note priority="1">Part-DB1\src\Entity\UserSystem\User.php:0</note>
|
<note priority="1">Part-DB1\src\Entity\UserSystem\User.php:0</note>
|
||||||
</notes>
|
</notes>
|
||||||
<segment state="translated">
|
<segment>
|
||||||
<source>validator.user.username_already_used</source>
|
<source>validator.user.username_already_used</source>
|
||||||
<target>Es existiert bereits ein Benutzer mit diesem Namen.</target>
|
<target>Es existiert bereits ein Benutzer mit diesem Namen.</target>
|
||||||
</segment>
|
</segment>
|
||||||
|
@ -162,7 +162,7 @@
|
||||||
<note category="file-source" priority="1">Part-DB1\src\Entity\UserSystem\User.php:0</note>
|
<note category="file-source" priority="1">Part-DB1\src\Entity\UserSystem\User.php:0</note>
|
||||||
<note priority="1">Part-DB1\src\Entity\UserSystem\User.php:0</note>
|
<note priority="1">Part-DB1\src\Entity\UserSystem\User.php:0</note>
|
||||||
</notes>
|
</notes>
|
||||||
<segment state="translated">
|
<segment>
|
||||||
<source>user.invalid_username</source>
|
<source>user.invalid_username</source>
|
||||||
<target>Der Benutzername darf nur Buchstaben, Zahlen, Unterstriche, Punkte, Plus- oder Minuszeichen enthalten.</target>
|
<target>Der Benutzername darf nur Buchstaben, Zahlen, Unterstriche, Punkte, Plus- oder Minuszeichen enthalten.</target>
|
||||||
</segment>
|
</segment>
|
||||||
|
@ -171,7 +171,7 @@
|
||||||
<notes>
|
<notes>
|
||||||
<note category="state" priority="1">obsolete</note>
|
<note category="state" priority="1">obsolete</note>
|
||||||
</notes>
|
</notes>
|
||||||
<segment state="translated">
|
<segment>
|
||||||
<source>validator.noneofitschild.self</source>
|
<source>validator.noneofitschild.self</source>
|
||||||
<target>Ein Element kann nicht sein eigenenes übergeordnetes Element sein!</target>
|
<target>Ein Element kann nicht sein eigenenes übergeordnetes Element sein!</target>
|
||||||
</segment>
|
</segment>
|
||||||
|
@ -180,139 +180,139 @@
|
||||||
<notes>
|
<notes>
|
||||||
<note category="state" priority="1">obsolete</note>
|
<note category="state" priority="1">obsolete</note>
|
||||||
</notes>
|
</notes>
|
||||||
<segment state="final">
|
<segment>
|
||||||
<source>validator.noneofitschild.children</source>
|
<source>validator.noneofitschild.children</source>
|
||||||
<target>Ein Kindelement kann nicht das übergeordnete Element sein!</target>
|
<target>Ein Kindelement kann nicht das übergeordnete Element sein!</target>
|
||||||
</segment>
|
</segment>
|
||||||
</unit>
|
</unit>
|
||||||
<unit id="ayNr6QK" name="validator.select_valid_category">
|
<unit id="ayNr6QK" name="validator.select_valid_category">
|
||||||
<segment state="translated">
|
<segment>
|
||||||
<source>validator.select_valid_category</source>
|
<source>validator.select_valid_category</source>
|
||||||
<target>Bitte wählen Sie eine gültige Kategorie.</target>
|
<target>Bitte wählen Sie eine gültige Kategorie.</target>
|
||||||
</segment>
|
</segment>
|
||||||
</unit>
|
</unit>
|
||||||
<unit id="6vIlN5q" name="validator.part_lot.only_existing">
|
<unit id="6vIlN5q" name="validator.part_lot.only_existing">
|
||||||
<segment state="translated">
|
<segment>
|
||||||
<source>validator.part_lot.only_existing</source>
|
<source>validator.part_lot.only_existing</source>
|
||||||
<target>Der Lagerort wurde als "nur bestehende Teile" markiert, daher können keine neuen Teile hinzugefügt werden.</target>
|
<target>Der Lagerort wurde als "nur bestehende Teile" markiert, daher können keine neuen Teile hinzugefügt werden.</target>
|
||||||
</segment>
|
</segment>
|
||||||
</unit>
|
</unit>
|
||||||
<unit id="3xoKOIS" name="validator.part_lot.location_full.no_increase">
|
<unit id="3xoKOIS" name="validator.part_lot.location_full.no_increase">
|
||||||
<segment state="translated">
|
<segment>
|
||||||
<source>validator.part_lot.location_full.no_increase</source>
|
<source>validator.part_lot.location_full.no_increase</source>
|
||||||
<target>Lagerort ist voll. Bestand kann nicht erhöht werden (neuer Wert muss kleiner sein als {{old_amount}}).</target>
|
<target>Lagerort ist voll. Bestand kann nicht erhöht werden (neuer Wert muss kleiner sein als {{old_amount}}).</target>
|
||||||
</segment>
|
</segment>
|
||||||
</unit>
|
</unit>
|
||||||
<unit id="R6Ov4Yt" name="validator.part_lot.location_full">
|
<unit id="R6Ov4Yt" name="validator.part_lot.location_full">
|
||||||
<segment state="final">
|
<segment>
|
||||||
<source>validator.part_lot.location_full</source>
|
<source>validator.part_lot.location_full</source>
|
||||||
<target>Der Lagerort ist voll, daher können keine neue Teile hinzugefügt werden.</target>
|
<target>Der Lagerort ist voll, daher können keine neue Teile hinzugefügt werden.</target>
|
||||||
</segment>
|
</segment>
|
||||||
</unit>
|
</unit>
|
||||||
<unit id="BNQk2e7" name="validator.part_lot.single_part">
|
<unit id="BNQk2e7" name="validator.part_lot.single_part">
|
||||||
<segment state="final">
|
<segment>
|
||||||
<source>validator.part_lot.single_part</source>
|
<source>validator.part_lot.single_part</source>
|
||||||
<target>Der Lagerort wurde als "Nur ein Bauteil" markiert, daher kann kein neues Bauteil hinzugefügt werden.</target>
|
<target>Der Lagerort wurde als "Nur ein Bauteil" markiert, daher kann kein neues Bauteil hinzugefügt werden.</target>
|
||||||
</segment>
|
</segment>
|
||||||
</unit>
|
</unit>
|
||||||
<unit id="4gPskOG" name="validator.attachment.must_not_be_null">
|
<unit id="4gPskOG" name="validator.attachment.must_not_be_null">
|
||||||
<segment state="translated">
|
<segment>
|
||||||
<source>validator.attachment.must_not_be_null</source>
|
<source>validator.attachment.must_not_be_null</source>
|
||||||
<target>Sie müssen ein Dateitypen auswählen!</target>
|
<target>Sie müssen ein Dateitypen auswählen!</target>
|
||||||
</segment>
|
</segment>
|
||||||
</unit>
|
</unit>
|
||||||
<unit id="cDDVrWT" name="validator.orderdetail.supplier_must_not_be_null">
|
<unit id="cDDVrWT" name="validator.orderdetail.supplier_must_not_be_null">
|
||||||
<segment state="translated">
|
<segment>
|
||||||
<source>validator.orderdetail.supplier_must_not_be_null</source>
|
<source>validator.orderdetail.supplier_must_not_be_null</source>
|
||||||
<target>Sie müssen einen Lieferanten auswählen!</target>
|
<target>Sie müssen einen Lieferanten auswählen!</target>
|
||||||
</segment>
|
</segment>
|
||||||
</unit>
|
</unit>
|
||||||
<unit id="k5DDdB4" name="validator.measurement_unit.use_si_prefix_needs_unit">
|
<unit id="k5DDdB4" name="validator.measurement_unit.use_si_prefix_needs_unit">
|
||||||
<segment state="translated">
|
<segment>
|
||||||
<source>validator.measurement_unit.use_si_prefix_needs_unit</source>
|
<source>validator.measurement_unit.use_si_prefix_needs_unit</source>
|
||||||
<target>Um SI-Prefixe zu aktivieren, müssen Sie einen Einheitensymbol setzen!</target>
|
<target>Um SI-Prefixe zu aktivieren, müssen Sie einen Einheitensymbol setzen!</target>
|
||||||
</segment>
|
</segment>
|
||||||
</unit>
|
</unit>
|
||||||
<unit id="DuzIOCr" name="part.ipn.must_be_unique">
|
<unit id="DuzIOCr" name="part.ipn.must_be_unique">
|
||||||
<segment state="translated">
|
<segment>
|
||||||
<source>part.ipn.must_be_unique</source>
|
<source>part.ipn.must_be_unique</source>
|
||||||
<target>Die Internal Part Number (IPN) muss einzigartig sein. Der Wert {{value}} wird bereits benutzt!</target>
|
<target>Die Internal Part Number (IPN) muss einzigartig sein. Der Wert {{value}} wird bereits benutzt!</target>
|
||||||
</segment>
|
</segment>
|
||||||
</unit>
|
</unit>
|
||||||
<unit id="Z4Kuuo2" name="validator.project.bom_entry.name_or_part_needed">
|
<unit id="Z4Kuuo2" name="validator.project.bom_entry.name_or_part_needed">
|
||||||
<segment state="translated">
|
<segment>
|
||||||
<source>validator.project.bom_entry.name_or_part_needed</source>
|
<source>validator.project.bom_entry.name_or_part_needed</source>
|
||||||
<target>Sie müssen ein Bauteil auswählen, oder einen Namen für ein nicht-Bauteil BOM-Eintrag setzen!</target>
|
<target>Sie müssen ein Bauteil auswählen, oder einen Namen für ein nicht-Bauteil BOM-Eintrag setzen!</target>
|
||||||
</segment>
|
</segment>
|
||||||
</unit>
|
</unit>
|
||||||
<unit id="WF_v4ih" name="project.bom_entry.name_already_in_bom">
|
<unit id="WF_v4ih" name="project.bom_entry.name_already_in_bom">
|
||||||
<segment state="translated">
|
<segment>
|
||||||
<source>project.bom_entry.name_already_in_bom</source>
|
<source>project.bom_entry.name_already_in_bom</source>
|
||||||
<target>Es gibt bereits einen BOM Eintrag mit diesem Namen!</target>
|
<target>Es gibt bereits einen BOM Eintrag mit diesem Namen!</target>
|
||||||
</segment>
|
</segment>
|
||||||
</unit>
|
</unit>
|
||||||
<unit id="5v4p85H" name="project.bom_entry.part_already_in_bom">
|
<unit id="5v4p85H" name="project.bom_entry.part_already_in_bom">
|
||||||
<segment state="translated">
|
<segment>
|
||||||
<source>project.bom_entry.part_already_in_bom</source>
|
<source>project.bom_entry.part_already_in_bom</source>
|
||||||
<target>Dieses Bauteil existiert bereits in der BOM!</target>
|
<target>Dieses Bauteil existiert bereits in der BOM!</target>
|
||||||
</segment>
|
</segment>
|
||||||
</unit>
|
</unit>
|
||||||
<unit id="3lM32Tw" name="project.bom_entry.mountnames_quantity_mismatch">
|
<unit id="3lM32Tw" name="project.bom_entry.mountnames_quantity_mismatch">
|
||||||
<segment state="translated">
|
<segment>
|
||||||
<source>project.bom_entry.mountnames_quantity_mismatch</source>
|
<source>project.bom_entry.mountnames_quantity_mismatch</source>
|
||||||
<target>Die Anzahl der Bestückungsnamen muss mit der Menge der zu bestückenden Bauteile übereinstimmen!</target>
|
<target>Die Anzahl der Bestückungsnamen muss mit der Menge der zu bestückenden Bauteile übereinstimmen!</target>
|
||||||
</segment>
|
</segment>
|
||||||
</unit>
|
</unit>
|
||||||
<unit id="x47D5WT" name="project.bom_entry.can_not_add_own_builds_part">
|
<unit id="x47D5WT" name="project.bom_entry.can_not_add_own_builds_part">
|
||||||
<segment state="translated">
|
<segment>
|
||||||
<source>project.bom_entry.can_not_add_own_builds_part</source>
|
<source>project.bom_entry.can_not_add_own_builds_part</source>
|
||||||
<target>Die BOM eines Projektes kann nicht das eigene Produktionsbauteil enthalten!</target>
|
<target>Die BOM eines Projektes kann nicht das eigene Produktionsbauteil enthalten!</target>
|
||||||
</segment>
|
</segment>
|
||||||
</unit>
|
</unit>
|
||||||
<unit id="2x2XDI_" name="project.bom_has_to_include_all_subelement_parts">
|
<unit id="2x2XDI_" name="project.bom_has_to_include_all_subelement_parts">
|
||||||
<segment state="translated">
|
<segment>
|
||||||
<source>project.bom_has_to_include_all_subelement_parts</source>
|
<source>project.bom_has_to_include_all_subelement_parts</source>
|
||||||
<target>Die Projekt-BOM muss alle Produktionsbauteile der Unterprojekte enthalten. Bauteil %part_name% des Projektes %project_name% fehlt!</target>
|
<target>Die Projekt-BOM muss alle Produktionsbauteile der Unterprojekte enthalten. Bauteil %part_name% des Projektes %project_name% fehlt!</target>
|
||||||
</segment>
|
</segment>
|
||||||
</unit>
|
</unit>
|
||||||
<unit id="U9b1EzD" name="project.bom_entry.price_not_allowed_on_parts">
|
<unit id="U9b1EzD" name="project.bom_entry.price_not_allowed_on_parts">
|
||||||
<segment state="translated">
|
<segment>
|
||||||
<source>project.bom_entry.price_not_allowed_on_parts</source>
|
<source>project.bom_entry.price_not_allowed_on_parts</source>
|
||||||
<target>Sie können keinen Preis für Bauteil-BOM-Einträge definieren. Definieren Sie die Preise stattdessen auf dem Bauteil.</target>
|
<target>Sie können keinen Preis für Bauteil-BOM-Einträge definieren. Definieren Sie die Preise stattdessen auf dem Bauteil.</target>
|
||||||
</segment>
|
</segment>
|
||||||
</unit>
|
</unit>
|
||||||
<unit id="ID056SR" name="validator.project_build.lot_bigger_than_needed">
|
<unit id="ID056SR" name="validator.project_build.lot_bigger_than_needed">
|
||||||
<segment state="translated">
|
<segment>
|
||||||
<source>validator.project_build.lot_bigger_than_needed</source>
|
<source>validator.project_build.lot_bigger_than_needed</source>
|
||||||
<target>Sie haben mehr zur Entnahme ausgewählt als notwendig. Entfernen Sie die überflüssige Anzahl.</target>
|
<target>Sie haben mehr zur Entnahme ausgewählt als notwendig. Entfernen Sie die überflüssige Anzahl.</target>
|
||||||
</segment>
|
</segment>
|
||||||
</unit>
|
</unit>
|
||||||
<unit id="6hV5UqD" name="validator.project_build.lot_smaller_than_needed">
|
<unit id="6hV5UqD" name="validator.project_build.lot_smaller_than_needed">
|
||||||
<segment state="translated">
|
<segment>
|
||||||
<source>validator.project_build.lot_smaller_than_needed</source>
|
<source>validator.project_build.lot_smaller_than_needed</source>
|
||||||
<target>Sie haben weniger zur Entnahme ausgewählt, als zum Bau notwendig ist! Fügen Sie mehr hinzu.</target>
|
<target>Sie haben weniger zur Entnahme ausgewählt, als zum Bau notwendig ist! Fügen Sie mehr hinzu.</target>
|
||||||
</segment>
|
</segment>
|
||||||
</unit>
|
</unit>
|
||||||
<unit id="G9ZKt.4" name="part.name.must_match_category_regex">
|
<unit id="G9ZKt.4" name="part.name.must_match_category_regex">
|
||||||
<segment state="translated">
|
<segment>
|
||||||
<source>part.name.must_match_category_regex</source>
|
<source>part.name.must_match_category_regex</source>
|
||||||
<target>Der Bauteilename entspricht nicht dem regulären Ausdruck, der von der Kategorie vorgegeben wurde: %regex%</target>
|
<target>Der Bauteilename entspricht nicht dem regulären Ausdruck, der von der Kategorie vorgegeben wurde: %regex%</target>
|
||||||
</segment>
|
</segment>
|
||||||
</unit>
|
</unit>
|
||||||
<unit id="m8kMFhf" name="validator.attachment.name_not_blank">
|
<unit id="m8kMFhf" name="validator.attachment.name_not_blank">
|
||||||
<segment state="translated">
|
<segment>
|
||||||
<source>validator.attachment.name_not_blank</source>
|
<source>validator.attachment.name_not_blank</source>
|
||||||
<target>Wählen Sie einen Wert, oder laden Sie eine Datei hoch, um dessen Dateiname automatisch als Namen für diesen Anhang zu nutzen.</target>
|
<target>Wählen Sie einen Wert, oder laden Sie eine Datei hoch, um dessen Dateiname automatisch als Namen für diesen Anhang zu nutzen.</target>
|
||||||
</segment>
|
</segment>
|
||||||
</unit>
|
</unit>
|
||||||
<unit id="nwGaNBW" name="validator.part_lot.owner_must_match_storage_location_owner">
|
<unit id="nwGaNBW" name="validator.part_lot.owner_must_match_storage_location_owner">
|
||||||
<segment state="translated">
|
<segment>
|
||||||
<source>validator.part_lot.owner_must_match_storage_location_owner</source>
|
<source>validator.part_lot.owner_must_match_storage_location_owner</source>
|
||||||
<target>Der Besitzer dieses Bauteilebestandes und des gewählten Lagerortes müssen übereinstimmen (%owner_name%)!</target>
|
<target>Der Besitzer dieses Bauteilebestandes und des gewählten Lagerortes müssen übereinstimmen (%owner_name%)!</target>
|
||||||
</segment>
|
</segment>
|
||||||
</unit>
|
</unit>
|
||||||
<unit id="HXSz3nQ" name="validator.part_lot.owner_must_not_be_anonymous">
|
<unit id="HXSz3nQ" name="validator.part_lot.owner_must_not_be_anonymous">
|
||||||
<segment state="translated">
|
<segment>
|
||||||
<source>validator.part_lot.owner_must_not_be_anonymous</source>
|
<source>validator.part_lot.owner_must_not_be_anonymous</source>
|
||||||
<target>Der Eigentümer darf nicht der anonymous Benutzer sein!</target>
|
<target>Der Eigentümer darf nicht der anonymous Benutzer sein!</target>
|
||||||
</segment>
|
</segment>
|
||||||
|
|
|
@ -3029,11 +3029,6 @@ d@1, d@^1.0.1:
|
||||||
es5-ext "^0.10.50"
|
es5-ext "^0.10.50"
|
||||||
type "^1.0.1"
|
type "^1.0.1"
|
||||||
|
|
||||||
darkmode-js@^1.5.0:
|
|
||||||
version "1.5.7"
|
|
||||||
resolved "https://registry.yarnpkg.com/darkmode-js/-/darkmode-js-1.5.7.tgz#b260ff671d67e021446ac8bade458e08338f6410"
|
|
||||||
integrity sha512-gM1KhV/yy/84ZUpES9/oeOn0CVtuOi2HBd+Kccr4CJz+rFccQo2gUuPbjfyPXUx7t800Zf408G6kZb5rkTgjFA==
|
|
||||||
|
|
||||||
dash-ast@^2.0.1:
|
dash-ast@^2.0.1:
|
||||||
version "2.0.1"
|
version "2.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/dash-ast/-/dash-ast-2.0.1.tgz#8d0fd2e601c59bf874cc22877ee7dd889f54dee8"
|
resolved "https://registry.yarnpkg.com/dash-ast/-/dash-ast-2.0.1.tgz#8d0fd2e601c59bf874cc22877ee7dd889f54dee8"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue