Initial commit
This commit is contained in:
commit
5f557d5d43
3
.gitattributes
vendored
Normal file
3
.gitattributes
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
/gradlew text eol=lf
|
||||||
|
*.bat text eol=crlf
|
||||||
|
*.jar binary
|
38
.gitignore
vendored
Normal file
38
.gitignore
vendored
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
node_modules
|
||||||
|
HELP.md
|
||||||
|
.gradle
|
||||||
|
build/
|
||||||
|
!gradle/wrapper/gradle-wrapper.jar
|
||||||
|
!**/src/main/**/build/
|
||||||
|
!**/src/test/**/build/
|
||||||
|
|
||||||
|
### STS ###
|
||||||
|
.apt_generated
|
||||||
|
.classpath
|
||||||
|
.factorypath
|
||||||
|
.project
|
||||||
|
.settings
|
||||||
|
.springBeans
|
||||||
|
.sts4-cache
|
||||||
|
bin/
|
||||||
|
!**/src/main/**/bin/
|
||||||
|
!**/src/test/**/bin/
|
||||||
|
|
||||||
|
### IntelliJ IDEA ###
|
||||||
|
.idea
|
||||||
|
*.iws
|
||||||
|
*.iml
|
||||||
|
*.ipr
|
||||||
|
out/
|
||||||
|
!**/src/main/**/out/
|
||||||
|
!**/src/test/**/out/
|
||||||
|
|
||||||
|
### NetBeans ###
|
||||||
|
/nbproject/private/
|
||||||
|
/nbbuild/
|
||||||
|
/dist/
|
||||||
|
/nbdist/
|
||||||
|
/.nb-gradle/
|
||||||
|
|
||||||
|
### VS Code ###
|
||||||
|
.vscode/
|
49
build.gradle.kts
Normal file
49
build.gradle.kts
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
plugins {
|
||||||
|
java
|
||||||
|
id("org.springframework.boot") version "3.4.1"
|
||||||
|
id("io.spring.dependency-management") version "1.1.7"
|
||||||
|
id("com.vaadin") version "24.6.0"
|
||||||
|
}
|
||||||
|
|
||||||
|
group = "ru.vyatsu"
|
||||||
|
version = "1.0.0"
|
||||||
|
|
||||||
|
java {
|
||||||
|
toolchain {
|
||||||
|
languageVersion = JavaLanguageVersion.of(17)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
configurations {
|
||||||
|
compileOnly {
|
||||||
|
extendsFrom(configurations.annotationProcessor.get())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
mavenCentral()
|
||||||
|
}
|
||||||
|
|
||||||
|
extra["vaadinVersion"] = "24.6.0"
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation("org.springframework.boot:spring-boot-starter-data-jpa")
|
||||||
|
implementation("org.springframework.boot:spring-boot-starter-web")
|
||||||
|
implementation("com.vaadin:vaadin-spring-boot-starter")
|
||||||
|
implementation("org.yaml:snakeyaml")
|
||||||
|
compileOnly("org.projectlombok:lombok")
|
||||||
|
annotationProcessor("org.projectlombok:lombok")
|
||||||
|
runtimeOnly("org.postgresql:postgresql")
|
||||||
|
testImplementation("org.springframework.boot:spring-boot-starter-test")
|
||||||
|
testRuntimeOnly("org.junit.platform:junit-platform-launcher")
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencyManagement {
|
||||||
|
imports {
|
||||||
|
mavenBom("com.vaadin:vaadin-bom:${property("vaadinVersion")}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.withType<Test> {
|
||||||
|
useJUnitPlatform()
|
||||||
|
}
|
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
Binary file not shown.
7
gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
7
gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
distributionBase=GRADLE_USER_HOME
|
||||||
|
distributionPath=wrapper/dists
|
||||||
|
distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip
|
||||||
|
networkTimeout=10000
|
||||||
|
validateDistributionUrl=true
|
||||||
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
|
zipStorePath=wrapper/dists
|
252
gradlew
vendored
Normal file
252
gradlew
vendored
Normal file
@ -0,0 +1,252 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
#
|
||||||
|
# Copyright © 2015-2021 the original authors.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
#
|
||||||
|
|
||||||
|
##############################################################################
|
||||||
|
#
|
||||||
|
# Gradle start up script for POSIX generated by Gradle.
|
||||||
|
#
|
||||||
|
# Important for running:
|
||||||
|
#
|
||||||
|
# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
|
||||||
|
# noncompliant, but you have some other compliant shell such as ksh or
|
||||||
|
# bash, then to run this script, type that shell name before the whole
|
||||||
|
# command line, like:
|
||||||
|
#
|
||||||
|
# ksh Gradle
|
||||||
|
#
|
||||||
|
# Busybox and similar reduced shells will NOT work, because this script
|
||||||
|
# requires all of these POSIX shell features:
|
||||||
|
# * functions;
|
||||||
|
# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
|
||||||
|
# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
|
||||||
|
# * compound commands having a testable exit status, especially «case»;
|
||||||
|
# * various built-in commands including «command», «set», and «ulimit».
|
||||||
|
#
|
||||||
|
# Important for patching:
|
||||||
|
#
|
||||||
|
# (2) This script targets any POSIX shell, so it avoids extensions provided
|
||||||
|
# by Bash, Ksh, etc; in particular arrays are avoided.
|
||||||
|
#
|
||||||
|
# The "traditional" practice of packing multiple parameters into a
|
||||||
|
# space-separated string is a well documented source of bugs and security
|
||||||
|
# problems, so this is (mostly) avoided, by progressively accumulating
|
||||||
|
# options in "$@", and eventually passing that to Java.
|
||||||
|
#
|
||||||
|
# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
|
||||||
|
# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
|
||||||
|
# see the in-line comments for details.
|
||||||
|
#
|
||||||
|
# There are tweaks for specific operating systems such as AIX, CygWin,
|
||||||
|
# Darwin, MinGW, and NonStop.
|
||||||
|
#
|
||||||
|
# (3) This script is generated from the Groovy template
|
||||||
|
# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||||
|
# within the Gradle project.
|
||||||
|
#
|
||||||
|
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||||
|
#
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
# Attempt to set APP_HOME
|
||||||
|
|
||||||
|
# Resolve links: $0 may be a link
|
||||||
|
app_path=$0
|
||||||
|
|
||||||
|
# Need this for daisy-chained symlinks.
|
||||||
|
while
|
||||||
|
APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
|
||||||
|
[ -h "$app_path" ]
|
||||||
|
do
|
||||||
|
ls=$( ls -ld "$app_path" )
|
||||||
|
link=${ls#*' -> '}
|
||||||
|
case $link in #(
|
||||||
|
/*) app_path=$link ;; #(
|
||||||
|
*) app_path=$APP_HOME$link ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
# This is normally unused
|
||||||
|
# shellcheck disable=SC2034
|
||||||
|
APP_BASE_NAME=${0##*/}
|
||||||
|
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
|
||||||
|
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s
|
||||||
|
' "$PWD" ) || exit
|
||||||
|
|
||||||
|
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||||
|
MAX_FD=maximum
|
||||||
|
|
||||||
|
warn () {
|
||||||
|
echo "$*"
|
||||||
|
} >&2
|
||||||
|
|
||||||
|
die () {
|
||||||
|
echo
|
||||||
|
echo "$*"
|
||||||
|
echo
|
||||||
|
exit 1
|
||||||
|
} >&2
|
||||||
|
|
||||||
|
# OS specific support (must be 'true' or 'false').
|
||||||
|
cygwin=false
|
||||||
|
msys=false
|
||||||
|
darwin=false
|
||||||
|
nonstop=false
|
||||||
|
case "$( uname )" in #(
|
||||||
|
CYGWIN* ) cygwin=true ;; #(
|
||||||
|
Darwin* ) darwin=true ;; #(
|
||||||
|
MSYS* | MINGW* ) msys=true ;; #(
|
||||||
|
NONSTOP* ) nonstop=true ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||||
|
|
||||||
|
|
||||||
|
# Determine the Java command to use to start the JVM.
|
||||||
|
if [ -n "$JAVA_HOME" ] ; then
|
||||||
|
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||||
|
# IBM's JDK on AIX uses strange locations for the executables
|
||||||
|
JAVACMD=$JAVA_HOME/jre/sh/java
|
||||||
|
else
|
||||||
|
JAVACMD=$JAVA_HOME/bin/java
|
||||||
|
fi
|
||||||
|
if [ ! -x "$JAVACMD" ] ; then
|
||||||
|
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||||
|
|
||||||
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
location of your Java installation."
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
JAVACMD=java
|
||||||
|
if ! command -v java >/dev/null 2>&1
|
||||||
|
then
|
||||||
|
die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||||
|
|
||||||
|
Please set the JAVA_HOME variable in your environment to match the
|
||||||
|
location of your Java installation."
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Increase the maximum file descriptors if we can.
|
||||||
|
if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
|
||||||
|
case $MAX_FD in #(
|
||||||
|
max*)
|
||||||
|
# In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked.
|
||||||
|
# shellcheck disable=SC2039,SC3045
|
||||||
|
MAX_FD=$( ulimit -H -n ) ||
|
||||||
|
warn "Could not query maximum file descriptor limit"
|
||||||
|
esac
|
||||||
|
case $MAX_FD in #(
|
||||||
|
'' | soft) :;; #(
|
||||||
|
*)
|
||||||
|
# In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked.
|
||||||
|
# shellcheck disable=SC2039,SC3045
|
||||||
|
ulimit -n "$MAX_FD" ||
|
||||||
|
warn "Could not set maximum file descriptor limit to $MAX_FD"
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Collect all arguments for the java command, stacking in reverse order:
|
||||||
|
# * args from the command line
|
||||||
|
# * the main class name
|
||||||
|
# * -classpath
|
||||||
|
# * -D...appname settings
|
||||||
|
# * --module-path (only if needed)
|
||||||
|
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
|
||||||
|
|
||||||
|
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||||
|
if "$cygwin" || "$msys" ; then
|
||||||
|
APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
|
||||||
|
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
|
||||||
|
|
||||||
|
JAVACMD=$( cygpath --unix "$JAVACMD" )
|
||||||
|
|
||||||
|
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||||
|
for arg do
|
||||||
|
if
|
||||||
|
case $arg in #(
|
||||||
|
-*) false ;; # don't mess with options #(
|
||||||
|
/?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
|
||||||
|
[ -e "$t" ] ;; #(
|
||||||
|
*) false ;;
|
||||||
|
esac
|
||||||
|
then
|
||||||
|
arg=$( cygpath --path --ignore --mixed "$arg" )
|
||||||
|
fi
|
||||||
|
# Roll the args list around exactly as many times as the number of
|
||||||
|
# args, so each arg winds up back in the position where it started, but
|
||||||
|
# possibly modified.
|
||||||
|
#
|
||||||
|
# NB: a `for` loop captures its iteration list before it begins, so
|
||||||
|
# changing the positional parameters here affects neither the number of
|
||||||
|
# iterations, nor the values presented in `arg`.
|
||||||
|
shift # remove old arg
|
||||||
|
set -- "$@" "$arg" # push replacement arg
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
|
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||||
|
|
||||||
|
# Collect all arguments for the java command:
|
||||||
|
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
|
||||||
|
# and any embedded shellness will be escaped.
|
||||||
|
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
|
||||||
|
# treated as '${Hostname}' itself on the command line.
|
||||||
|
|
||||||
|
set -- \
|
||||||
|
"-Dorg.gradle.appname=$APP_BASE_NAME" \
|
||||||
|
-classpath "$CLASSPATH" \
|
||||||
|
org.gradle.wrapper.GradleWrapperMain \
|
||||||
|
"$@"
|
||||||
|
|
||||||
|
# Stop when "xargs" is not available.
|
||||||
|
if ! command -v xargs >/dev/null 2>&1
|
||||||
|
then
|
||||||
|
die "xargs is not available"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Use "xargs" to parse quoted args.
|
||||||
|
#
|
||||||
|
# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
|
||||||
|
#
|
||||||
|
# In Bash we could simply go:
|
||||||
|
#
|
||||||
|
# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
|
||||||
|
# set -- "${ARGS[@]}" "$@"
|
||||||
|
#
|
||||||
|
# but POSIX shell has neither arrays nor command substitution, so instead we
|
||||||
|
# post-process each arg (as a line of input to sed) to backslash-escape any
|
||||||
|
# character that might be a shell metacharacter, then use eval to reverse
|
||||||
|
# that process (while maintaining the separation between arguments), and wrap
|
||||||
|
# the whole thing up as a single "set" statement.
|
||||||
|
#
|
||||||
|
# This will of course break if any of these variables contains a newline or
|
||||||
|
# an unmatched quote.
|
||||||
|
#
|
||||||
|
|
||||||
|
eval "set -- $(
|
||||||
|
printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
|
||||||
|
xargs -n1 |
|
||||||
|
sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
|
||||||
|
tr '\n' ' '
|
||||||
|
)" '"$@"'
|
||||||
|
|
||||||
|
exec "$JAVACMD" "$@"
|
94
gradlew.bat
vendored
Normal file
94
gradlew.bat
vendored
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
@rem
|
||||||
|
@rem Copyright 2015 the original author or authors.
|
||||||
|
@rem
|
||||||
|
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
@rem you may not use this file except in compliance with the License.
|
||||||
|
@rem You may obtain a copy of the License at
|
||||||
|
@rem
|
||||||
|
@rem https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
@rem
|
||||||
|
@rem Unless required by applicable law or agreed to in writing, software
|
||||||
|
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
@rem See the License for the specific language governing permissions and
|
||||||
|
@rem limitations under the License.
|
||||||
|
@rem
|
||||||
|
@rem SPDX-License-Identifier: Apache-2.0
|
||||||
|
@rem
|
||||||
|
|
||||||
|
@if "%DEBUG%"=="" @echo off
|
||||||
|
@rem ##########################################################################
|
||||||
|
@rem
|
||||||
|
@rem Gradle startup script for Windows
|
||||||
|
@rem
|
||||||
|
@rem ##########################################################################
|
||||||
|
|
||||||
|
@rem Set local scope for the variables with windows NT shell
|
||||||
|
if "%OS%"=="Windows_NT" setlocal
|
||||||
|
|
||||||
|
set DIRNAME=%~dp0
|
||||||
|
if "%DIRNAME%"=="" set DIRNAME=.
|
||||||
|
@rem This is normally unused
|
||||||
|
set APP_BASE_NAME=%~n0
|
||||||
|
set APP_HOME=%DIRNAME%
|
||||||
|
|
||||||
|
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||||
|
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||||
|
|
||||||
|
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||||
|
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||||
|
|
||||||
|
@rem Find java.exe
|
||||||
|
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||||
|
|
||||||
|
set JAVA_EXE=java.exe
|
||||||
|
%JAVA_EXE% -version >NUL 2>&1
|
||||||
|
if %ERRORLEVEL% equ 0 goto execute
|
||||||
|
|
||||||
|
echo. 1>&2
|
||||||
|
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2
|
||||||
|
echo. 1>&2
|
||||||
|
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
||||||
|
echo location of your Java installation. 1>&2
|
||||||
|
|
||||||
|
goto fail
|
||||||
|
|
||||||
|
:findJavaFromJavaHome
|
||||||
|
set JAVA_HOME=%JAVA_HOME:"=%
|
||||||
|
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||||
|
|
||||||
|
if exist "%JAVA_EXE%" goto execute
|
||||||
|
|
||||||
|
echo. 1>&2
|
||||||
|
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2
|
||||||
|
echo. 1>&2
|
||||||
|
echo Please set the JAVA_HOME variable in your environment to match the 1>&2
|
||||||
|
echo location of your Java installation. 1>&2
|
||||||
|
|
||||||
|
goto fail
|
||||||
|
|
||||||
|
:execute
|
||||||
|
@rem Setup the command line
|
||||||
|
|
||||||
|
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||||
|
|
||||||
|
|
||||||
|
@rem Execute Gradle
|
||||||
|
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
|
||||||
|
|
||||||
|
:end
|
||||||
|
@rem End local scope for the variables with windows NT shell
|
||||||
|
if %ERRORLEVEL% equ 0 goto mainEnd
|
||||||
|
|
||||||
|
:fail
|
||||||
|
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||||
|
rem the _cmd.exe /c_ return code!
|
||||||
|
set EXIT_CODE=%ERRORLEVEL%
|
||||||
|
if %EXIT_CODE% equ 0 set EXIT_CODE=1
|
||||||
|
if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE%
|
||||||
|
exit /b %EXIT_CODE%
|
||||||
|
|
||||||
|
:mainEnd
|
||||||
|
if "%OS%"=="Windows_NT" endlocal
|
||||||
|
|
||||||
|
:omega
|
1
settings.gradle.kts
Normal file
1
settings.gradle.kts
Normal file
@ -0,0 +1 @@
|
|||||||
|
rootProject.name = "qr-access-admin"
|
1
src/main/frontend/generated/flow/generated-flow-imports.d.ts
vendored
Normal file
1
src/main/frontend/generated/flow/generated-flow-imports.d.ts
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
export {}
|
12
src/main/frontend/generated/flow/generated-flow-imports.js
Normal file
12
src/main/frontend/generated/flow/generated-flow-imports.js
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import '@vaadin/polymer-legacy-adapter/style-modules.js';
|
||||||
|
import '@vaadin/app-layout/src/vaadin-app-layout.js';
|
||||||
|
import '@vaadin/vertical-layout/src/vaadin-vertical-layout.js';
|
||||||
|
const loadOnDemand = (key) => { return Promise.resolve(0); }
|
||||||
|
window.Vaadin = window.Vaadin || {};
|
||||||
|
window.Vaadin.Flow = window.Vaadin.Flow || {};
|
||||||
|
window.Vaadin.Flow.loadOnDemand = loadOnDemand;
|
||||||
|
window.Vaadin.Flow.resetFocus = () => {
|
||||||
|
let ae=document.activeElement;
|
||||||
|
while(ae&&ae.shadowRoot) ae = ae.shadowRoot.activeElement;
|
||||||
|
return !ae || ae.blur() || ae.focus() || true;
|
||||||
|
}
|
@ -0,0 +1,14 @@
|
|||||||
|
import { injectGlobalWebcomponentCss } from 'Frontend/generated/jar-resources/theme-util.js';
|
||||||
|
|
||||||
|
import '@vaadin/polymer-legacy-adapter/style-modules.js';
|
||||||
|
import '@vaadin/app-layout/src/vaadin-app-layout.js';
|
||||||
|
import '@vaadin/vertical-layout/src/vaadin-vertical-layout.js';
|
||||||
|
const loadOnDemand = (key) => { return Promise.resolve(0); }
|
||||||
|
window.Vaadin = window.Vaadin || {};
|
||||||
|
window.Vaadin.Flow = window.Vaadin.Flow || {};
|
||||||
|
window.Vaadin.Flow.loadOnDemand = loadOnDemand;
|
||||||
|
window.Vaadin.Flow.resetFocus = () => {
|
||||||
|
let ae=document.activeElement;
|
||||||
|
while(ae&&ae.shadowRoot) ae = ae.shadowRoot.activeElement;
|
||||||
|
return !ae || ae.blur() || ae.focus() || true;
|
||||||
|
}
|
77
src/main/frontend/generated/jar-resources/Flow.d.ts
vendored
Normal file
77
src/main/frontend/generated/jar-resources/Flow.d.ts
vendored
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
export interface FlowConfig {
|
||||||
|
imports?: () => Promise<any>;
|
||||||
|
}
|
||||||
|
interface AppConfig {
|
||||||
|
productionMode: boolean;
|
||||||
|
appId: string;
|
||||||
|
uidl: any;
|
||||||
|
}
|
||||||
|
interface AppInitResponse {
|
||||||
|
appConfig: AppConfig;
|
||||||
|
pushScript?: string;
|
||||||
|
}
|
||||||
|
interface Router {
|
||||||
|
render: (ctx: NavigationParameters, shouldUpdateHistory: boolean) => Promise<void>;
|
||||||
|
}
|
||||||
|
interface HTMLRouterContainer extends HTMLElement {
|
||||||
|
onBeforeEnter?: (ctx: NavigationParameters, cmd: PreventAndRedirectCommands, router: Router) => void | Promise<any>;
|
||||||
|
onBeforeLeave?: (ctx: NavigationParameters, cmd: PreventCommands, router: Router) => void | Promise<any>;
|
||||||
|
serverConnected?: (cancel: boolean, url?: NavigationParameters) => void;
|
||||||
|
serverPaused?: () => void;
|
||||||
|
}
|
||||||
|
interface FlowRoute {
|
||||||
|
action: (params: NavigationParameters) => Promise<HTMLRouterContainer>;
|
||||||
|
path: string;
|
||||||
|
}
|
||||||
|
export interface NavigationParameters {
|
||||||
|
pathname: string;
|
||||||
|
search?: string;
|
||||||
|
}
|
||||||
|
export interface PreventCommands {
|
||||||
|
prevent: () => any;
|
||||||
|
continue?: () => any;
|
||||||
|
}
|
||||||
|
export interface PreventAndRedirectCommands extends PreventCommands {
|
||||||
|
redirect: (route: string) => any;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Client API for flow UI operations.
|
||||||
|
*/
|
||||||
|
export declare class Flow {
|
||||||
|
config: FlowConfig;
|
||||||
|
response?: AppInitResponse;
|
||||||
|
pathname: string;
|
||||||
|
container: HTMLRouterContainer;
|
||||||
|
private isActive;
|
||||||
|
private baseRegex;
|
||||||
|
private appShellTitle;
|
||||||
|
private navigation;
|
||||||
|
constructor(config?: FlowConfig);
|
||||||
|
/**
|
||||||
|
* Return a `route` object for vaadin-router in an one-element array.
|
||||||
|
*
|
||||||
|
* The `FlowRoute` object `path` property handles any route,
|
||||||
|
* and the `action` returns the flow container without updating the content,
|
||||||
|
* delaying the actual Flow server call to the `onBeforeEnter` phase.
|
||||||
|
*
|
||||||
|
* This is a specific API for its use with `vaadin-router`.
|
||||||
|
*/
|
||||||
|
get serverSideRoutes(): [FlowRoute];
|
||||||
|
loadingStarted(): void;
|
||||||
|
loadingFinished(): void;
|
||||||
|
private get action();
|
||||||
|
private flowLeave;
|
||||||
|
private flowNavigate;
|
||||||
|
private getFlowRoutePath;
|
||||||
|
private getFlowRouteQuery;
|
||||||
|
private flowInit;
|
||||||
|
private loadScript;
|
||||||
|
private findNonce;
|
||||||
|
private injectAppIdScript;
|
||||||
|
private flowInitClient;
|
||||||
|
private flowInitUi;
|
||||||
|
private addConnectionIndicator;
|
||||||
|
private offlineStubAction;
|
||||||
|
private isFlowClientLoaded;
|
||||||
|
}
|
||||||
|
export {};
|
394
src/main/frontend/generated/jar-resources/Flow.js
Normal file
394
src/main/frontend/generated/jar-resources/Flow.js
Normal file
@ -0,0 +1,394 @@
|
|||||||
|
import { ConnectionIndicator, ConnectionState } from '@vaadin/common-frontend';
|
||||||
|
class FlowUiInitializationError extends Error {
|
||||||
|
}
|
||||||
|
// flow uses body for keeping references
|
||||||
|
const flowRoot = window.document.body;
|
||||||
|
const $wnd = window;
|
||||||
|
const ROOT_NODE_ID = 1; // See StateTree.java
|
||||||
|
function getClients() {
|
||||||
|
return Object.keys($wnd.Vaadin.Flow.clients)
|
||||||
|
.filter((key) => key !== 'TypeScript')
|
||||||
|
.map((id) => $wnd.Vaadin.Flow.clients[id]);
|
||||||
|
}
|
||||||
|
function sendEvent(eventName, data) {
|
||||||
|
getClients().forEach((client) => client.sendEventMessage(ROOT_NODE_ID, eventName, data));
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Client API for flow UI operations.
|
||||||
|
*/
|
||||||
|
export class Flow {
|
||||||
|
constructor(config) {
|
||||||
|
this.response = undefined;
|
||||||
|
this.pathname = '';
|
||||||
|
// flag used to inform Testbench whether a server route is in progress
|
||||||
|
this.isActive = false;
|
||||||
|
this.baseRegex = /^\//;
|
||||||
|
this.navigation = '';
|
||||||
|
flowRoot.$ = flowRoot.$ || [];
|
||||||
|
this.config = config || {};
|
||||||
|
// TB checks for the existence of window.Vaadin.Flow in order
|
||||||
|
// to consider that TB needs to wait for `initFlow()`.
|
||||||
|
$wnd.Vaadin = $wnd.Vaadin || {};
|
||||||
|
$wnd.Vaadin.Flow = $wnd.Vaadin.Flow || {};
|
||||||
|
$wnd.Vaadin.Flow.clients = {
|
||||||
|
TypeScript: {
|
||||||
|
isActive: () => this.isActive
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// Regular expression used to remove the app-context
|
||||||
|
const elm = document.head.querySelector('base');
|
||||||
|
this.baseRegex = new RegExp(`^${
|
||||||
|
// IE11 does not support document.baseURI
|
||||||
|
(document.baseURI || (elm && elm.href) || '/').replace(/^https?:\/\/[^/]+/i, '')}`);
|
||||||
|
this.appShellTitle = document.title;
|
||||||
|
// Put a vaadin-connection-indicator in the dom
|
||||||
|
this.addConnectionIndicator();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Return a `route` object for vaadin-router in an one-element array.
|
||||||
|
*
|
||||||
|
* The `FlowRoute` object `path` property handles any route,
|
||||||
|
* and the `action` returns the flow container without updating the content,
|
||||||
|
* delaying the actual Flow server call to the `onBeforeEnter` phase.
|
||||||
|
*
|
||||||
|
* This is a specific API for its use with `vaadin-router`.
|
||||||
|
*/
|
||||||
|
get serverSideRoutes() {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
path: '(.*)',
|
||||||
|
action: this.action
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
loadingStarted() {
|
||||||
|
// Make Testbench know that server request is in progress
|
||||||
|
this.isActive = true;
|
||||||
|
$wnd.Vaadin.connectionState.loadingStarted();
|
||||||
|
}
|
||||||
|
loadingFinished() {
|
||||||
|
// Make Testbench know that server request has finished
|
||||||
|
this.isActive = false;
|
||||||
|
$wnd.Vaadin.connectionState.loadingFinished();
|
||||||
|
if ($wnd.Vaadin.listener) {
|
||||||
|
// Listeners registered, do not register again.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$wnd.Vaadin.listener = {};
|
||||||
|
// Listen for click on router-links -> 'link' navigation trigger
|
||||||
|
// and on <a> nodes -> 'client' navigation trigger.
|
||||||
|
// Use capture phase to detect prevented / stopped events.
|
||||||
|
document.addEventListener('click', (_e) => {
|
||||||
|
if (_e.target) {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
|
// @ts-ignore
|
||||||
|
if (_e.target.hasAttribute('router-link')) {
|
||||||
|
this.navigation = 'link';
|
||||||
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||||
|
// @ts-ignore
|
||||||
|
}
|
||||||
|
else if (_e.composedPath().some((node) => node.nodeName === 'A')) {
|
||||||
|
this.navigation = 'client';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
capture: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
get action() {
|
||||||
|
// Return a function which is bound to the flow instance, thus we can use
|
||||||
|
// the syntax `...serverSideRoutes` in vaadin-router.
|
||||||
|
return async (params) => {
|
||||||
|
// Store last action pathname so as we can check it in events
|
||||||
|
this.pathname = params.pathname;
|
||||||
|
if ($wnd.Vaadin.connectionState.online) {
|
||||||
|
try {
|
||||||
|
await this.flowInit();
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
if (error instanceof FlowUiInitializationError) {
|
||||||
|
// error initializing Flow: assume connection lost
|
||||||
|
$wnd.Vaadin.connectionState.state = ConnectionState.CONNECTION_LOST;
|
||||||
|
return this.offlineStubAction();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// insert an offline stub
|
||||||
|
return this.offlineStubAction();
|
||||||
|
}
|
||||||
|
// When an action happens, navigation will be resolved `onBeforeEnter`
|
||||||
|
this.container.onBeforeEnter = (ctx, cmd) => this.flowNavigate(ctx, cmd);
|
||||||
|
// For covering the 'server -> client' use case
|
||||||
|
this.container.onBeforeLeave = (ctx, cmd) => this.flowLeave(ctx, cmd);
|
||||||
|
return this.container;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
// Send a remote call to `JavaScriptBootstrapUI` to check
|
||||||
|
// whether navigation has to be cancelled.
|
||||||
|
async flowLeave(ctx, cmd) {
|
||||||
|
// server -> server, viewing offline stub, or browser is offline
|
||||||
|
const { connectionState } = $wnd.Vaadin;
|
||||||
|
if (this.pathname === ctx.pathname || !this.isFlowClientLoaded() || connectionState.offline) {
|
||||||
|
return Promise.resolve({});
|
||||||
|
}
|
||||||
|
// 'server -> client'
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
this.loadingStarted();
|
||||||
|
// The callback to run from server side to cancel navigation
|
||||||
|
this.container.serverConnected = (cancel) => {
|
||||||
|
var _a;
|
||||||
|
resolve(cmd && cancel ? cmd.prevent() : (_a = cmd === null || cmd === void 0 ? void 0 : cmd.continue) === null || _a === void 0 ? void 0 : _a.call(cmd));
|
||||||
|
this.loadingFinished();
|
||||||
|
};
|
||||||
|
// Call server side to check whether we can leave the view
|
||||||
|
sendEvent('ui-leave-navigation', { route: this.getFlowRoutePath(ctx), query: this.getFlowRouteQuery(ctx) });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// Send the remote call to `JavaScriptBootstrapUI` to render the flow
|
||||||
|
// route specified by the context
|
||||||
|
async flowNavigate(ctx, cmd) {
|
||||||
|
if (this.response) {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
this.loadingStarted();
|
||||||
|
// The callback to run from server side once the view is ready
|
||||||
|
this.container.serverConnected = (cancel, redirectContext) => {
|
||||||
|
var _a;
|
||||||
|
if (cmd && cancel) {
|
||||||
|
resolve(cmd.prevent());
|
||||||
|
}
|
||||||
|
else if (cmd && cmd.redirect && redirectContext) {
|
||||||
|
resolve(cmd.redirect(redirectContext.pathname));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
(_a = cmd === null || cmd === void 0 ? void 0 : cmd.continue) === null || _a === void 0 ? void 0 : _a.call(cmd);
|
||||||
|
this.container.style.display = '';
|
||||||
|
resolve(this.container);
|
||||||
|
}
|
||||||
|
this.loadingFinished();
|
||||||
|
};
|
||||||
|
this.container.serverPaused = () => {
|
||||||
|
this.loadingFinished();
|
||||||
|
};
|
||||||
|
// Call server side to navigate to the given route
|
||||||
|
sendEvent('ui-navigate', {
|
||||||
|
route: this.getFlowRoutePath(ctx),
|
||||||
|
query: this.getFlowRouteQuery(ctx),
|
||||||
|
appShellTitle: this.appShellTitle,
|
||||||
|
historyState: history.state,
|
||||||
|
trigger: this.navigation
|
||||||
|
});
|
||||||
|
// Default to history navigation trigger.
|
||||||
|
// Link and client cases are handled by click listener in loadingFinished().
|
||||||
|
this.navigation = 'history';
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// No server response => offline or erroneous connection
|
||||||
|
return Promise.resolve(this.container);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
getFlowRoutePath(context) {
|
||||||
|
return decodeURIComponent(context.pathname).replace(this.baseRegex, '');
|
||||||
|
}
|
||||||
|
getFlowRouteQuery(context) {
|
||||||
|
return (context.search && context.search.substring(1)) || '';
|
||||||
|
}
|
||||||
|
// import flow client modules and initialize UI in server side.
|
||||||
|
async flowInit() {
|
||||||
|
// Do not start flow twice
|
||||||
|
if (!this.isFlowClientLoaded()) {
|
||||||
|
$wnd.Vaadin.Flow.nonce = this.findNonce();
|
||||||
|
// show flow progress indicator
|
||||||
|
this.loadingStarted();
|
||||||
|
// Initialize server side UI
|
||||||
|
this.response = await this.flowInitUi();
|
||||||
|
const { pushScript, appConfig } = this.response;
|
||||||
|
if (typeof pushScript === 'string') {
|
||||||
|
await this.loadScript(pushScript);
|
||||||
|
}
|
||||||
|
const { appId } = appConfig;
|
||||||
|
// we use a custom tag for the flow app container
|
||||||
|
// This must be created before bootstrapMod.init is called as that call
|
||||||
|
// can handle a UIDL from the server, which relies on the container being available
|
||||||
|
const tag = `flow-container-${appId.toLowerCase()}`;
|
||||||
|
const serverCreatedContainer = document.querySelector(tag);
|
||||||
|
if (serverCreatedContainer) {
|
||||||
|
this.container = serverCreatedContainer;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.container = document.createElement(tag);
|
||||||
|
this.container.id = appId;
|
||||||
|
}
|
||||||
|
flowRoot.$[appId] = this.container;
|
||||||
|
// Load bootstrap script with server side parameters
|
||||||
|
const bootstrapMod = await import('./FlowBootstrap');
|
||||||
|
bootstrapMod.init(this.response);
|
||||||
|
// Load custom modules defined by user
|
||||||
|
if (typeof this.config.imports === 'function') {
|
||||||
|
this.injectAppIdScript(appId);
|
||||||
|
await this.config.imports();
|
||||||
|
}
|
||||||
|
// Load flow-client module
|
||||||
|
const clientMod = await import('./FlowClient');
|
||||||
|
await this.flowInitClient(clientMod);
|
||||||
|
// hide flow progress indicator
|
||||||
|
this.loadingFinished();
|
||||||
|
}
|
||||||
|
// It might be that components created from server expect that their content has been rendered.
|
||||||
|
// Appending eagerly the container we avoid these kind of errors.
|
||||||
|
// Note that the client router will move this container to the outlet if the navigation succeed
|
||||||
|
if (this.container && !this.container.isConnected) {
|
||||||
|
this.container.style.display = 'none';
|
||||||
|
document.body.appendChild(this.container);
|
||||||
|
}
|
||||||
|
return this.response;
|
||||||
|
}
|
||||||
|
async loadScript(url) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const script = document.createElement('script');
|
||||||
|
script.onload = () => resolve();
|
||||||
|
script.onerror = reject;
|
||||||
|
script.src = url;
|
||||||
|
const { nonce } = $wnd.Vaadin.Flow;
|
||||||
|
if (nonce !== undefined) {
|
||||||
|
script.setAttribute('nonce', nonce);
|
||||||
|
}
|
||||||
|
document.body.appendChild(script);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
findNonce() {
|
||||||
|
let nonce;
|
||||||
|
const scriptTags = document.head.getElementsByTagName('script');
|
||||||
|
for (const scriptTag of scriptTags) {
|
||||||
|
if (scriptTag.nonce) {
|
||||||
|
nonce = scriptTag.nonce;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nonce;
|
||||||
|
}
|
||||||
|
injectAppIdScript(appId) {
|
||||||
|
const appIdWithoutHashCode = appId.substring(0, appId.lastIndexOf('-'));
|
||||||
|
const scriptAppId = document.createElement('script');
|
||||||
|
scriptAppId.type = 'module';
|
||||||
|
scriptAppId.setAttribute('data-app-id', appIdWithoutHashCode);
|
||||||
|
const { nonce } = $wnd.Vaadin.Flow;
|
||||||
|
if (nonce !== undefined) {
|
||||||
|
scriptAppId.setAttribute('nonce', nonce);
|
||||||
|
}
|
||||||
|
document.body.append(scriptAppId);
|
||||||
|
}
|
||||||
|
// After the flow-client javascript module has been loaded, this initializes flow UI
|
||||||
|
// in the browser.
|
||||||
|
async flowInitClient(clientMod) {
|
||||||
|
clientMod.init();
|
||||||
|
// client init is async, we need to loop until initialized
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
const intervalId = setInterval(() => {
|
||||||
|
// client `isActive() == true` while initializing or processing
|
||||||
|
const initializing = getClients().reduce((prev, client) => prev || client.isActive(), false);
|
||||||
|
if (!initializing) {
|
||||||
|
clearInterval(intervalId);
|
||||||
|
resolve();
|
||||||
|
}
|
||||||
|
}, 5);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// Returns the `appConfig` object
|
||||||
|
async flowInitUi() {
|
||||||
|
// appConfig was sent in the index.html request
|
||||||
|
const initial = $wnd.Vaadin && $wnd.Vaadin.TypeScript && $wnd.Vaadin.TypeScript.initial;
|
||||||
|
if (initial) {
|
||||||
|
$wnd.Vaadin.TypeScript.initial = undefined;
|
||||||
|
return Promise.resolve(initial);
|
||||||
|
}
|
||||||
|
// send a request to the `JavaScriptBootstrapHandler`
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const xhr = new XMLHttpRequest();
|
||||||
|
const httpRequest = xhr;
|
||||||
|
const requestPath = `?v-r=init&location=${encodeURIComponent(this.getFlowRoutePath(location))}&query=${encodeURIComponent(this.getFlowRouteQuery(location))}`;
|
||||||
|
httpRequest.open('GET', requestPath);
|
||||||
|
httpRequest.onerror = () => reject(new FlowUiInitializationError(`Invalid server response when initializing Flow UI.
|
||||||
|
${httpRequest.status}
|
||||||
|
${httpRequest.responseText}`));
|
||||||
|
httpRequest.onload = () => {
|
||||||
|
const contentType = httpRequest.getResponseHeader('content-type');
|
||||||
|
if (contentType && contentType.indexOf('application/json') !== -1) {
|
||||||
|
resolve(JSON.parse(httpRequest.responseText));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
httpRequest.onerror();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
httpRequest.send();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// Create shared connection state store and connection indicator
|
||||||
|
addConnectionIndicator() {
|
||||||
|
// add connection indicator to DOM
|
||||||
|
ConnectionIndicator.create();
|
||||||
|
// Listen to browser online/offline events and update the loading indicator accordingly.
|
||||||
|
// Note: if flow-client is loaded, it instead handles the state transitions.
|
||||||
|
$wnd.addEventListener('online', () => {
|
||||||
|
if (!this.isFlowClientLoaded()) {
|
||||||
|
// Send an HTTP HEAD request for sw.js to verify server reachability.
|
||||||
|
// We do not expect sw.js to be cached, so the request goes to the
|
||||||
|
// server rather than being served from local cache.
|
||||||
|
// Require network-level failure to revert the state to CONNECTION_LOST
|
||||||
|
// (HTTP error code is ok since it still verifies server's presence).
|
||||||
|
$wnd.Vaadin.connectionState.state = ConnectionState.RECONNECTING;
|
||||||
|
const http = new XMLHttpRequest();
|
||||||
|
http.open('HEAD', 'sw.js');
|
||||||
|
http.onload = () => {
|
||||||
|
$wnd.Vaadin.connectionState.state = ConnectionState.CONNECTED;
|
||||||
|
};
|
||||||
|
http.onerror = () => {
|
||||||
|
$wnd.Vaadin.connectionState.state = ConnectionState.CONNECTION_LOST;
|
||||||
|
};
|
||||||
|
// Postpone request to reduce potential net::ERR_INTERNET_DISCONNECTED
|
||||||
|
// errors that sometimes occurs even if browser says it is online
|
||||||
|
setTimeout(() => http.send(), 50);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
$wnd.addEventListener('offline', () => {
|
||||||
|
if (!this.isFlowClientLoaded()) {
|
||||||
|
$wnd.Vaadin.connectionState.state = ConnectionState.CONNECTION_LOST;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
async offlineStubAction() {
|
||||||
|
const offlineStub = document.createElement('iframe');
|
||||||
|
const offlineStubPath = './offline-stub.html';
|
||||||
|
offlineStub.setAttribute('src', offlineStubPath);
|
||||||
|
offlineStub.setAttribute('style', 'width: 100%; height: 100%; border: 0');
|
||||||
|
this.response = undefined;
|
||||||
|
let onlineListener;
|
||||||
|
const removeOfflineStubAndOnlineListener = () => {
|
||||||
|
if (onlineListener !== undefined) {
|
||||||
|
$wnd.Vaadin.connectionState.removeStateChangeListener(onlineListener);
|
||||||
|
onlineListener = undefined;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
offlineStub.onBeforeEnter = (ctx, _cmds, router) => {
|
||||||
|
onlineListener = () => {
|
||||||
|
if ($wnd.Vaadin.connectionState.online) {
|
||||||
|
removeOfflineStubAndOnlineListener();
|
||||||
|
router.render(ctx, false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
$wnd.Vaadin.connectionState.addStateChangeListener(onlineListener);
|
||||||
|
};
|
||||||
|
offlineStub.onBeforeLeave = (_ctx, _cmds, _router) => {
|
||||||
|
removeOfflineStubAndOnlineListener();
|
||||||
|
};
|
||||||
|
return offlineStub;
|
||||||
|
}
|
||||||
|
isFlowClientLoaded() {
|
||||||
|
return this.response !== undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//# sourceMappingURL=Flow.js.map
|
1
src/main/frontend/generated/jar-resources/Flow.js.map
Normal file
1
src/main/frontend/generated/jar-resources/Flow.js.map
Normal file
File diff suppressed because one or more lines are too long
1
src/main/frontend/generated/jar-resources/FlowBootstrap.d.ts
vendored
Normal file
1
src/main/frontend/generated/jar-resources/FlowBootstrap.d.ts
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
export const init: (appInitResponse: any) => void;
|
291
src/main/frontend/generated/jar-resources/FlowBootstrap.js
Normal file
291
src/main/frontend/generated/jar-resources/FlowBootstrap.js
Normal file
@ -0,0 +1,291 @@
|
|||||||
|
/* This is a copy of the regular `BootstrapHandler.js` in the flow-server
|
||||||
|
module, but with the following modifications:
|
||||||
|
- The main function is exported as an ES module for lazy initialization.
|
||||||
|
- Application configuration is passed as a parameter instead of using
|
||||||
|
replacement placeholders as in the regular bootstrapping.
|
||||||
|
- It reuses `Vaadin.Flow.clients` if exists.
|
||||||
|
- Fixed lint errors.
|
||||||
|
*/
|
||||||
|
const init = function (appInitResponse) {
|
||||||
|
window.Vaadin = window.Vaadin || {};
|
||||||
|
window.Vaadin.Flow = window.Vaadin.Flow || {};
|
||||||
|
|
||||||
|
var apps = {};
|
||||||
|
var widgetsets = {};
|
||||||
|
|
||||||
|
var log;
|
||||||
|
if (typeof window.console === undefined || !window.location.search.match(/[&?]debug(&|$)/)) {
|
||||||
|
/* If no console.log present, just use a no-op */
|
||||||
|
log = function () {};
|
||||||
|
} else if (typeof window.console.log === 'function') {
|
||||||
|
/* If it's a function, use it with apply */
|
||||||
|
log = function () {
|
||||||
|
window.console.log.apply(window.console, arguments);
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
/* In IE, its a native function for which apply is not defined, but it works
|
||||||
|
without a proper 'this' reference */
|
||||||
|
log = window.console.log;
|
||||||
|
}
|
||||||
|
|
||||||
|
var isInitializedInDom = function (appId) {
|
||||||
|
var appDiv = document.getElementById(appId);
|
||||||
|
if (!appDiv) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (var i = 0; i < appDiv.childElementCount; i++) {
|
||||||
|
var className = appDiv.childNodes[i].className;
|
||||||
|
/* If the app div contains a child with the class
|
||||||
|
'v-app-loading' we have only received the HTML
|
||||||
|
but not yet started the widget set
|
||||||
|
(UIConnector removes the v-app-loading div). */
|
||||||
|
if (className && className.indexOf('v-app-loading') != -1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Needed for Testbench compatibility, but prevents any Vaadin 7 app from
|
||||||
|
* bootstrapping unless the legacy vaadinBootstrap.js file is loaded before
|
||||||
|
* this script.
|
||||||
|
*/
|
||||||
|
window.Vaadin = window.Vaadin || {};
|
||||||
|
window.Vaadin.Flow = window.Vaadin.Flow || {};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Needed for wrapping custom javascript functionality in the components (i.e. connectors)
|
||||||
|
*/
|
||||||
|
window.Vaadin.Flow.tryCatchWrapper = function (originalFunction, component) {
|
||||||
|
return function () {
|
||||||
|
try {
|
||||||
|
// eslint-disable-next-line
|
||||||
|
const result = originalFunction.apply(this, arguments);
|
||||||
|
return result;
|
||||||
|
} catch (error) {
|
||||||
|
console.error(
|
||||||
|
`There seems to be an error in ${component}:
|
||||||
|
${error.message}
|
||||||
|
Please submit an issue to https://github.com/vaadin/flow-components/issues/new/choose`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!window.Vaadin.Flow.initApplication) {
|
||||||
|
window.Vaadin.Flow.clients = window.Vaadin.Flow.clients || {};
|
||||||
|
|
||||||
|
window.Vaadin.Flow.initApplication = function (appId, config) {
|
||||||
|
var testbenchId = appId.replace(/-\d+$/, '');
|
||||||
|
|
||||||
|
if (apps[appId]) {
|
||||||
|
if (
|
||||||
|
window.Vaadin &&
|
||||||
|
window.Vaadin.Flow &&
|
||||||
|
window.Vaadin.Flow.clients &&
|
||||||
|
window.Vaadin.Flow.clients[testbenchId] &&
|
||||||
|
window.Vaadin.Flow.clients[testbenchId].initializing
|
||||||
|
) {
|
||||||
|
throw new Error('Application ' + appId + ' is already being initialized');
|
||||||
|
}
|
||||||
|
if (isInitializedInDom(appId)) {
|
||||||
|
if (appInitResponse.appConfig.productionMode) {
|
||||||
|
throw new Error('Application ' + appId + ' already initialized');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove old contents for Flow
|
||||||
|
var appDiv = document.getElementById(appId);
|
||||||
|
for (var i = 0; i < appDiv.childElementCount; i++) {
|
||||||
|
appDiv.childNodes[i].remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
// For devMode reset app config and restart widgetset as client
|
||||||
|
// is up and running after hrm update.
|
||||||
|
const getConfig = function (name) {
|
||||||
|
return config[name];
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Export public data */
|
||||||
|
const app = {
|
||||||
|
getConfig: getConfig
|
||||||
|
};
|
||||||
|
apps[appId] = app;
|
||||||
|
|
||||||
|
if (widgetsets['client'].callback) {
|
||||||
|
log('Starting from bootstrap', appId);
|
||||||
|
widgetsets['client'].callback(appId);
|
||||||
|
} else {
|
||||||
|
log('Setting pending startup', appId);
|
||||||
|
widgetsets['client'].pendingApps.push(appId);
|
||||||
|
}
|
||||||
|
return apps[appId];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
log('init application', appId, config);
|
||||||
|
|
||||||
|
window.Vaadin.Flow.clients[testbenchId] = {
|
||||||
|
isActive: function () {
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
initializing: true,
|
||||||
|
productionMode: mode
|
||||||
|
};
|
||||||
|
|
||||||
|
var getConfig = function (name) {
|
||||||
|
var value = config[name];
|
||||||
|
return value;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Export public data */
|
||||||
|
var app = {
|
||||||
|
getConfig: getConfig
|
||||||
|
};
|
||||||
|
apps[appId] = app;
|
||||||
|
|
||||||
|
if (!window.name) {
|
||||||
|
window.name = appId + '-' + Math.random();
|
||||||
|
}
|
||||||
|
|
||||||
|
var widgetset = 'client';
|
||||||
|
widgetsets[widgetset] = {
|
||||||
|
pendingApps: []
|
||||||
|
};
|
||||||
|
if (widgetsets[widgetset].callback) {
|
||||||
|
log('Starting from bootstrap', appId);
|
||||||
|
widgetsets[widgetset].callback(appId);
|
||||||
|
} else {
|
||||||
|
log('Setting pending startup', appId);
|
||||||
|
widgetsets[widgetset].pendingApps.push(appId);
|
||||||
|
}
|
||||||
|
|
||||||
|
return app;
|
||||||
|
};
|
||||||
|
window.Vaadin.Flow.getAppIds = function () {
|
||||||
|
var ids = [];
|
||||||
|
for (var id in apps) {
|
||||||
|
if (Object.prototype.hasOwnProperty.call(apps, id)) {
|
||||||
|
ids.push(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ids;
|
||||||
|
};
|
||||||
|
window.Vaadin.Flow.getApp = function (appId) {
|
||||||
|
return apps[appId];
|
||||||
|
};
|
||||||
|
window.Vaadin.Flow.registerWidgetset = function (widgetset, callback) {
|
||||||
|
log('Widgetset registered', widgetset);
|
||||||
|
var ws = widgetsets[widgetset];
|
||||||
|
if (ws && ws.pendingApps) {
|
||||||
|
ws.callback = callback;
|
||||||
|
for (var i = 0; i < ws.pendingApps.length; i++) {
|
||||||
|
var appId = ws.pendingApps[i];
|
||||||
|
log('Starting from register widgetset', appId);
|
||||||
|
callback(appId);
|
||||||
|
}
|
||||||
|
ws.pendingApps = null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
window.Vaadin.Flow.getBrowserDetailsParameters = function () {
|
||||||
|
var params = {};
|
||||||
|
|
||||||
|
/* Screen height and width */
|
||||||
|
params['v-sh'] = window.screen.height;
|
||||||
|
params['v-sw'] = window.screen.width;
|
||||||
|
/* Browser window dimensions */
|
||||||
|
params['v-wh'] = window.innerHeight;
|
||||||
|
params['v-ww'] = window.innerWidth;
|
||||||
|
/* Body element dimensions */
|
||||||
|
params['v-bh'] = document.body.clientHeight;
|
||||||
|
params['v-bw'] = document.body.clientWidth;
|
||||||
|
|
||||||
|
/* Current time */
|
||||||
|
var date = new Date();
|
||||||
|
params['v-curdate'] = date.getTime();
|
||||||
|
|
||||||
|
/* Current timezone offset (including DST shift) */
|
||||||
|
var tzo1 = date.getTimezoneOffset();
|
||||||
|
|
||||||
|
/* Compare the current tz offset with the first offset from the end
|
||||||
|
of the year that differs --- if less that, we are in DST, otherwise
|
||||||
|
we are in normal time */
|
||||||
|
var dstDiff = 0;
|
||||||
|
var rawTzo = tzo1;
|
||||||
|
for (var m = 12; m > 0; m--) {
|
||||||
|
date.setUTCMonth(m);
|
||||||
|
var tzo2 = date.getTimezoneOffset();
|
||||||
|
if (tzo1 != tzo2) {
|
||||||
|
dstDiff = tzo1 > tzo2 ? tzo1 - tzo2 : tzo2 - tzo1;
|
||||||
|
rawTzo = tzo1 > tzo2 ? tzo1 : tzo2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Time zone offset */
|
||||||
|
params['v-tzo'] = tzo1;
|
||||||
|
|
||||||
|
/* DST difference */
|
||||||
|
params['v-dstd'] = dstDiff;
|
||||||
|
|
||||||
|
/* Time zone offset without DST */
|
||||||
|
params['v-rtzo'] = rawTzo;
|
||||||
|
|
||||||
|
/* DST in effect? */
|
||||||
|
params['v-dston'] = tzo1 != rawTzo;
|
||||||
|
|
||||||
|
/* Time zone id (if available) */
|
||||||
|
try {
|
||||||
|
params['v-tzid'] = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
||||||
|
} catch (err) {
|
||||||
|
params['v-tzid'] = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Window name */
|
||||||
|
if (window.name) {
|
||||||
|
params['v-wn'] = window.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Detect touch device support */
|
||||||
|
var supportsTouch = false;
|
||||||
|
try {
|
||||||
|
document.createEvent('TouchEvent');
|
||||||
|
supportsTouch = true;
|
||||||
|
} catch (e) {
|
||||||
|
/* Chrome and IE10 touch detection */
|
||||||
|
supportsTouch = 'ontouchstart' in window || typeof navigator.msMaxTouchPoints !== 'undefined';
|
||||||
|
}
|
||||||
|
params['v-td'] = supportsTouch;
|
||||||
|
|
||||||
|
/* Device Pixel Ratio */
|
||||||
|
params['v-pr'] = window.devicePixelRatio;
|
||||||
|
|
||||||
|
if (navigator.platform) {
|
||||||
|
params['v-np'] = navigator.platform;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Stringify each value (they are parsed on the server side) */
|
||||||
|
Object.keys(params).forEach(function (key) {
|
||||||
|
var value = params[key];
|
||||||
|
if (typeof value !== 'undefined') {
|
||||||
|
params[key] = value.toString();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return params;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
log('Flow bootstrap loaded');
|
||||||
|
if (appInitResponse.appConfig.productionMode && typeof window.__gwtStatsEvent != 'function') {
|
||||||
|
window.Vaadin.Flow.gwtStatsEvents = [];
|
||||||
|
window.__gwtStatsEvent = function (event) {
|
||||||
|
window.Vaadin.Flow.gwtStatsEvents.push(event);
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
var config = appInitResponse.appConfig;
|
||||||
|
var mode = appInitResponse.appConfig.productionMode;
|
||||||
|
window.Vaadin.Flow.initApplication(config.appId, config);
|
||||||
|
};
|
||||||
|
|
||||||
|
export { init };
|
1
src/main/frontend/generated/jar-resources/FlowClient.d.ts
vendored
Normal file
1
src/main/frontend/generated/jar-resources/FlowClient.d.ts
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
export const init: () => void;
|
1073
src/main/frontend/generated/jar-resources/FlowClient.js
Normal file
1073
src/main/frontend/generated/jar-resources/FlowClient.js
Normal file
File diff suppressed because one or more lines are too long
@ -0,0 +1,12 @@
|
|||||||
|
import { Outlet } from 'react-router-dom';
|
||||||
|
import { ReactAdapterElement } from "Frontend/generated/flow/ReactAdapter.js";
|
||||||
|
import React from "react";
|
||||||
|
|
||||||
|
class ReactRouterOutletElement extends ReactAdapterElement {
|
||||||
|
protected render(): React.ReactElement | null {
|
||||||
|
return <Outlet />;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
customElements.define('react-router-outlet', ReactRouterOutletElement);
|
277
src/main/frontend/generated/jar-resources/comboBoxConnector.js
Normal file
277
src/main/frontend/generated/jar-resources/comboBoxConnector.js
Normal file
@ -0,0 +1,277 @@
|
|||||||
|
import { Debouncer } from '@polymer/polymer/lib/utils/debounce.js';
|
||||||
|
import { timeOut } from '@polymer/polymer/lib/utils/async.js';
|
||||||
|
import { ComboBoxPlaceholder } from '@vaadin/combo-box/src/vaadin-combo-box-placeholder.js';
|
||||||
|
|
||||||
|
window.Vaadin.Flow.comboBoxConnector = {}
|
||||||
|
window.Vaadin.Flow.comboBoxConnector.initLazy = (comboBox) => {
|
||||||
|
// Check whether the connector was already initialized for the ComboBox
|
||||||
|
if (comboBox.$connector) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
comboBox.$connector = {};
|
||||||
|
|
||||||
|
// holds pageIndex -> callback pairs of subsequent indexes (current active range)
|
||||||
|
const pageCallbacks = {};
|
||||||
|
let cache = {};
|
||||||
|
let lastFilter = '';
|
||||||
|
const placeHolder = new window.Vaadin.ComboBoxPlaceholder();
|
||||||
|
|
||||||
|
const serverFacade = (() => {
|
||||||
|
// Private variables
|
||||||
|
let lastFilterSentToServer = '';
|
||||||
|
let dataCommunicatorResetNeeded = false;
|
||||||
|
|
||||||
|
// Public methods
|
||||||
|
const needsDataCommunicatorReset = () => (dataCommunicatorResetNeeded = true);
|
||||||
|
const getLastFilterSentToServer = () => lastFilterSentToServer;
|
||||||
|
const requestData = (startIndex, endIndex, params) => {
|
||||||
|
const count = endIndex - startIndex;
|
||||||
|
const filter = params.filter;
|
||||||
|
|
||||||
|
comboBox.$server.setRequestedRange(startIndex, count, filter);
|
||||||
|
lastFilterSentToServer = filter;
|
||||||
|
if (dataCommunicatorResetNeeded) {
|
||||||
|
comboBox.$server.resetDataCommunicator();
|
||||||
|
dataCommunicatorResetNeeded = false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return {
|
||||||
|
needsDataCommunicatorReset,
|
||||||
|
getLastFilterSentToServer,
|
||||||
|
requestData
|
||||||
|
};
|
||||||
|
})();
|
||||||
|
|
||||||
|
const clearPageCallbacks = (pages = Object.keys(pageCallbacks)) => {
|
||||||
|
// Flush and empty the existing requests
|
||||||
|
pages.forEach((page) => {
|
||||||
|
pageCallbacks[page]([], comboBox.size);
|
||||||
|
delete pageCallbacks[page];
|
||||||
|
|
||||||
|
// Empty the comboBox's internal cache without invoking observers by filling
|
||||||
|
// the filteredItems array with placeholders (comboBox will request for data when it
|
||||||
|
// encounters a placeholder)
|
||||||
|
const pageStart = parseInt(page) * comboBox.pageSize;
|
||||||
|
const pageEnd = pageStart + comboBox.pageSize;
|
||||||
|
const end = Math.min(pageEnd, comboBox.filteredItems.length);
|
||||||
|
for (let i = pageStart; i < end; i++) {
|
||||||
|
comboBox.filteredItems[i] = placeHolder;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
comboBox.dataProvider = function (params, callback) {
|
||||||
|
if (params.pageSize != comboBox.pageSize) {
|
||||||
|
throw 'Invalid pageSize';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (comboBox._clientSideFilter) {
|
||||||
|
// For clientside filter we first make sure we have all data which we also
|
||||||
|
// filter based on comboBox.filter. While later we only filter clientside data.
|
||||||
|
|
||||||
|
if (cache[0]) {
|
||||||
|
performClientSideFilter(cache[0], params.filter, callback);
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
// If client side filter is enabled then we need to first ask all data
|
||||||
|
// and filter it on client side, otherwise next time when user will
|
||||||
|
// input another filter, eg. continue to type, the local cache will be only
|
||||||
|
// what was received for the first filter, which may not be the whole
|
||||||
|
// data from server (keep in mind that client side filter is enabled only
|
||||||
|
// when the items count does not exceed one page).
|
||||||
|
params.filter = '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const filterChanged = params.filter !== lastFilter;
|
||||||
|
if (filterChanged) {
|
||||||
|
cache = {};
|
||||||
|
lastFilter = params.filter;
|
||||||
|
this._filterDebouncer = Debouncer.debounce(this._filterDebouncer, timeOut.after(500), () => {
|
||||||
|
if (serverFacade.getLastFilterSentToServer() === params.filter) {
|
||||||
|
// Fixes the case when the filter changes
|
||||||
|
// to something else and back to the original value
|
||||||
|
// within debounce timeout, and the
|
||||||
|
// DataCommunicator thinks it doesn't need to send data
|
||||||
|
serverFacade.needsDataCommunicatorReset();
|
||||||
|
}
|
||||||
|
if (params.filter !== lastFilter) {
|
||||||
|
throw new Error("Expected params.filter to be '" + lastFilter + "' but was '" + params.filter + "'");
|
||||||
|
}
|
||||||
|
// Remove the debouncer before clearing page callbacks.
|
||||||
|
// This makes sure that they are executed.
|
||||||
|
this._filterDebouncer = undefined;
|
||||||
|
// Call the method again after debounce.
|
||||||
|
clearPageCallbacks();
|
||||||
|
comboBox.dataProvider(params, callback);
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Postpone the execution of new callbacks if there is an active debouncer.
|
||||||
|
// They will be executed when the page callbacks are cleared within the debouncer.
|
||||||
|
if (this._filterDebouncer) {
|
||||||
|
pageCallbacks[params.page] = callback;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cache[params.page]) {
|
||||||
|
// This may happen after skipping pages by scrolling fast
|
||||||
|
commitPage(params.page, callback);
|
||||||
|
} else {
|
||||||
|
pageCallbacks[params.page] = callback;
|
||||||
|
const maxRangeCount = Math.max(params.pageSize * 2, 500); // Max item count in active range
|
||||||
|
const activePages = Object.keys(pageCallbacks).map((page) => parseInt(page));
|
||||||
|
const rangeMin = Math.min(...activePages);
|
||||||
|
const rangeMax = Math.max(...activePages);
|
||||||
|
|
||||||
|
if (activePages.length * params.pageSize > maxRangeCount) {
|
||||||
|
if (params.page === rangeMin) {
|
||||||
|
clearPageCallbacks([String(rangeMax)]);
|
||||||
|
} else {
|
||||||
|
clearPageCallbacks([String(rangeMin)]);
|
||||||
|
}
|
||||||
|
comboBox.dataProvider(params, callback);
|
||||||
|
} else if (rangeMax - rangeMin + 1 !== activePages.length) {
|
||||||
|
// Wasn't a sequential page index, clear the cache so combo-box will request for new pages
|
||||||
|
clearPageCallbacks();
|
||||||
|
} else {
|
||||||
|
// The requested page was sequential, extend the requested range
|
||||||
|
const startIndex = params.pageSize * rangeMin;
|
||||||
|
const endIndex = params.pageSize * (rangeMax + 1);
|
||||||
|
|
||||||
|
serverFacade.requestData(startIndex, endIndex, params);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
comboBox.$connector.clear = (start, length) => {
|
||||||
|
const firstPageToClear = Math.floor(start / comboBox.pageSize);
|
||||||
|
const numberOfPagesToClear = Math.ceil(length / comboBox.pageSize);
|
||||||
|
|
||||||
|
for (let i = firstPageToClear; i < firstPageToClear + numberOfPagesToClear; i++) {
|
||||||
|
delete cache[i];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
comboBox.$connector.filter = (item, filter) => {
|
||||||
|
filter = filter ? filter.toString().toLowerCase() : '';
|
||||||
|
return comboBox._getItemLabel(item, comboBox.itemLabelPath).toString().toLowerCase().indexOf(filter) > -1;
|
||||||
|
};
|
||||||
|
|
||||||
|
comboBox.$connector.set = (index, items, filter) => {
|
||||||
|
if (filter != serverFacade.getLastFilterSentToServer()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (index % comboBox.pageSize != 0) {
|
||||||
|
throw 'Got new data to index ' + index + ' which is not aligned with the page size of ' + comboBox.pageSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (index === 0 && items.length === 0 && pageCallbacks[0]) {
|
||||||
|
// Makes sure that the dataProvider callback is called even when server
|
||||||
|
// returns empty data set (no items match the filter).
|
||||||
|
cache[0] = [];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const firstPageToSet = index / comboBox.pageSize;
|
||||||
|
const updatedPageCount = Math.ceil(items.length / comboBox.pageSize);
|
||||||
|
|
||||||
|
for (let i = 0; i < updatedPageCount; i++) {
|
||||||
|
let page = firstPageToSet + i;
|
||||||
|
let slice = items.slice(i * comboBox.pageSize, (i + 1) * comboBox.pageSize);
|
||||||
|
|
||||||
|
cache[page] = slice;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
comboBox.$connector.updateData = (items) => {
|
||||||
|
const itemsMap = new Map(items.map((item) => [item.key, item]));
|
||||||
|
|
||||||
|
comboBox.filteredItems = comboBox.filteredItems.map((item) => {
|
||||||
|
return itemsMap.get(item.key) || item;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
comboBox.$connector.updateSize = function (newSize) {
|
||||||
|
if (!comboBox._clientSideFilter) {
|
||||||
|
// FIXME: It may be that this size set is unnecessary, since when
|
||||||
|
// providing data to combobox via callback we may use data's size.
|
||||||
|
// However, if this size reflect the whole data size, including
|
||||||
|
// data not fetched yet into client side, and combobox expect it
|
||||||
|
// to be set as such, the at least, we don't need it in case the
|
||||||
|
// filter is clientSide only, since it'll increase the height of
|
||||||
|
// the popup at only at first user filter to this size, while the
|
||||||
|
// filtered items count are less.
|
||||||
|
comboBox.size = newSize;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
comboBox.$connector.reset = function () {
|
||||||
|
clearPageCallbacks();
|
||||||
|
cache = {};
|
||||||
|
comboBox.clearCache();
|
||||||
|
};
|
||||||
|
|
||||||
|
comboBox.$connector.confirm = function (id, filter) {
|
||||||
|
if (filter != serverFacade.getLastFilterSentToServer()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We're done applying changes from this batch, resolve pending
|
||||||
|
// callbacks
|
||||||
|
let activePages = Object.getOwnPropertyNames(pageCallbacks);
|
||||||
|
for (let i = 0; i < activePages.length; i++) {
|
||||||
|
let page = activePages[i];
|
||||||
|
|
||||||
|
if (cache[page]) {
|
||||||
|
commitPage(page, pageCallbacks[page]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Let server know we're done
|
||||||
|
comboBox.$server.confirmUpdate(id);
|
||||||
|
};
|
||||||
|
|
||||||
|
const commitPage = function (page, callback) {
|
||||||
|
let data = cache[page];
|
||||||
|
|
||||||
|
if (comboBox._clientSideFilter) {
|
||||||
|
performClientSideFilter(data, comboBox.filter, callback);
|
||||||
|
} else {
|
||||||
|
// Remove the data if server-side filtering, but keep it for client-side
|
||||||
|
// filtering
|
||||||
|
delete cache[page];
|
||||||
|
|
||||||
|
// FIXME: It may be that we ought to provide data.length instead of
|
||||||
|
// comboBox.size and remove updateSize function.
|
||||||
|
callback(data, comboBox.size);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Perform filter on client side (here) using the items from specified page
|
||||||
|
// and submitting the filtered items to specified callback.
|
||||||
|
// The filter used is the one from combobox, not the lastFilter stored since
|
||||||
|
// that may not reflect user's input.
|
||||||
|
const performClientSideFilter = function (page, filter, callback) {
|
||||||
|
let filteredItems = page;
|
||||||
|
|
||||||
|
if (filter) {
|
||||||
|
filteredItems = page.filter((item) => comboBox.$connector.filter(item, filter));
|
||||||
|
}
|
||||||
|
|
||||||
|
callback(filteredItems, filteredItems.length);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Prevent setting the custom value as the 'value'-prop automatically
|
||||||
|
comboBox.addEventListener('custom-value-set', (e) => e.preventDefault());
|
||||||
|
|
||||||
|
comboBox.itemClassNameGenerator = function (item) {
|
||||||
|
return item.className || '';
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
window.Vaadin.ComboBoxPlaceholder = ComboBoxPlaceholder;
|
@ -0,0 +1,122 @@
|
|||||||
|
function getContainer(appId, nodeId) {
|
||||||
|
try {
|
||||||
|
return window.Vaadin.Flow.clients[appId].getByNodeId(nodeId);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Could not get node %s from app %s', nodeId, appId);
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the connector for a context menu element.
|
||||||
|
*
|
||||||
|
* @param {HTMLElement} contextMenu
|
||||||
|
* @param {string} appId
|
||||||
|
*/
|
||||||
|
function initLazy(contextMenu, appId) {
|
||||||
|
if (contextMenu.$connector) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
contextMenu.$connector = {
|
||||||
|
/**
|
||||||
|
* Generates and assigns the items to the context menu.
|
||||||
|
*
|
||||||
|
* @param {number} nodeId
|
||||||
|
*/
|
||||||
|
generateItems(nodeId) {
|
||||||
|
const items = generateItemsTree(appId, nodeId);
|
||||||
|
|
||||||
|
contextMenu.items = items;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates an items tree compatible with the context-menu web component
|
||||||
|
* by traversing the given Flow DOM tree of context menu item nodes
|
||||||
|
* whose root node is identified by the `nodeId` argument.
|
||||||
|
*
|
||||||
|
* The app id is required to access the store of Flow DOM nodes.
|
||||||
|
*
|
||||||
|
* @param {string} appId
|
||||||
|
* @param {number} nodeId
|
||||||
|
*/
|
||||||
|
function generateItemsTree(appId, nodeId) {
|
||||||
|
const container = getContainer(appId, nodeId);
|
||||||
|
if (!container) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Array.from(container.children).map((child) => {
|
||||||
|
const item = {
|
||||||
|
component: child,
|
||||||
|
checked: child._checked,
|
||||||
|
keepOpen: child._keepOpen,
|
||||||
|
className: child.className,
|
||||||
|
theme: child.__theme
|
||||||
|
};
|
||||||
|
// Do not hardcode tag name to allow `vaadin-menu-bar-item`
|
||||||
|
if (child._hasVaadinItemMixin && child._containerNodeId) {
|
||||||
|
item.children = generateItemsTree(appId, child._containerNodeId);
|
||||||
|
}
|
||||||
|
child._item = item;
|
||||||
|
return item;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the checked state for a context menu item.
|
||||||
|
*
|
||||||
|
* This method is supposed to be called when the context menu item is closed,
|
||||||
|
* so there is no need for triggering a re-render eagarly.
|
||||||
|
*
|
||||||
|
* @param {HTMLElement} component
|
||||||
|
* @param {boolean} checked
|
||||||
|
*/
|
||||||
|
function setChecked(component, checked) {
|
||||||
|
if (component._item) {
|
||||||
|
component._item.checked = checked;
|
||||||
|
|
||||||
|
// Set the attribute in the connector to show the checkmark
|
||||||
|
// without having to re-render the whole menu while opened.
|
||||||
|
if (component._item.keepOpen) {
|
||||||
|
component.toggleAttribute('menu-item-checked', checked);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the keep open state for a context menu item.
|
||||||
|
*
|
||||||
|
* @param {HTMLElement} component
|
||||||
|
* @param {boolean} keepOpen
|
||||||
|
*/
|
||||||
|
function setKeepOpen(component, keepOpen) {
|
||||||
|
if (component._item) {
|
||||||
|
component._item.keepOpen = keepOpen;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the theme for a context menu item.
|
||||||
|
*
|
||||||
|
* This method is supposed to be called when the context menu item is closed,
|
||||||
|
* so there is no need for triggering a re-render eagarly.
|
||||||
|
*
|
||||||
|
* @param {HTMLElement} component
|
||||||
|
* @param {string | undefined | null} theme
|
||||||
|
*/
|
||||||
|
function setTheme(component, theme) {
|
||||||
|
if (component._item) {
|
||||||
|
component._item.theme = theme;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
window.Vaadin.Flow.contextMenuConnector = {
|
||||||
|
initLazy,
|
||||||
|
generateItemsTree,
|
||||||
|
setChecked,
|
||||||
|
setKeepOpen,
|
||||||
|
setTheme
|
||||||
|
};
|
@ -0,0 +1,62 @@
|
|||||||
|
import * as Gestures from '@vaadin/component-base/src/gestures.js';
|
||||||
|
|
||||||
|
function init(target) {
|
||||||
|
if (target.$contextMenuTargetConnector) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
target.$contextMenuTargetConnector = {
|
||||||
|
openOnHandler(e) {
|
||||||
|
// used by Grid to prevent context menu on selection column click
|
||||||
|
if (target.preventContextMenu && target.preventContextMenu(e)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
this.$contextMenuTargetConnector.openEvent = e;
|
||||||
|
let detail = {};
|
||||||
|
if (target.getContextMenuBeforeOpenDetail) {
|
||||||
|
detail = target.getContextMenuBeforeOpenDetail(e);
|
||||||
|
}
|
||||||
|
target.dispatchEvent(
|
||||||
|
new CustomEvent('vaadin-context-menu-before-open', {
|
||||||
|
detail: detail
|
||||||
|
})
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
updateOpenOn(eventType) {
|
||||||
|
this.removeListener();
|
||||||
|
this.openOnEventType = eventType;
|
||||||
|
|
||||||
|
customElements.whenDefined('vaadin-context-menu').then(() => {
|
||||||
|
if (Gestures.gestures[eventType]) {
|
||||||
|
Gestures.addListener(target, eventType, this.openOnHandler);
|
||||||
|
} else {
|
||||||
|
target.addEventListener(eventType, this.openOnHandler);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
removeListener() {
|
||||||
|
if (this.openOnEventType) {
|
||||||
|
if (Gestures.gestures[this.openOnEventType]) {
|
||||||
|
Gestures.removeListener(target, this.openOnEventType, this.openOnHandler);
|
||||||
|
} else {
|
||||||
|
target.removeEventListener(this.openOnEventType, this.openOnHandler);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
openMenu(contextMenu) {
|
||||||
|
contextMenu.open(this.openEvent);
|
||||||
|
},
|
||||||
|
|
||||||
|
removeConnector() {
|
||||||
|
this.removeListener();
|
||||||
|
target.$contextMenuTargetConnector = undefined;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
window.Vaadin.Flow.contextMenuTargetConnector = { init };
|
1
src/main/frontend/generated/jar-resources/copilot.js
Normal file
1
src/main/frontend/generated/jar-resources/copilot.js
Normal file
@ -0,0 +1 @@
|
|||||||
|
import "./copilot/copilot-xjoIJFQc.js";
|
@ -0,0 +1,24 @@
|
|||||||
|
import { M as t, b as n } from "./copilot-xjoIJFQc.js";
|
||||||
|
class o extends t {
|
||||||
|
constructor() {
|
||||||
|
super(...arguments), this.eventBusRemovers = [], this.messageHandlers = {};
|
||||||
|
}
|
||||||
|
createRenderRoot() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
onEventBus(e, s) {
|
||||||
|
this.eventBusRemovers.push(n.on(e, s));
|
||||||
|
}
|
||||||
|
disconnectedCallback() {
|
||||||
|
super.disconnectedCallback(), this.eventBusRemovers.forEach((e) => e());
|
||||||
|
}
|
||||||
|
onCommand(e, s) {
|
||||||
|
this.messageHandlers[e] = s;
|
||||||
|
}
|
||||||
|
handleMessage(e) {
|
||||||
|
return this.messageHandlers[e.command] ? (this.messageHandlers[e.command].call(this, e), !0) : !1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
export {
|
||||||
|
o as B
|
||||||
|
};
|
@ -0,0 +1,70 @@
|
|||||||
|
import { x as p, U as c, _ as g, $ as f, n as u } from "./copilot-xjoIJFQc.js";
|
||||||
|
import { r as h } from "./state-9-chcL5F.js";
|
||||||
|
import { B as m } from "./base-panel-CTLXjjmN.js";
|
||||||
|
import { i as v } from "./icons-AkLm3oZf.js";
|
||||||
|
const b = "copilot-features-panel{padding:var(--space-100);font:var(--font-xsmall);display:grid;grid-template-columns:auto 1fr;gap:var(--space-50);height:auto}copilot-features-panel a{display:flex;align-items:center;gap:var(--space-50);white-space:nowrap}copilot-features-panel a svg{height:12px;width:12px;min-height:12px;min-width:12px}";
|
||||||
|
var F = Object.defineProperty, $ = Object.getOwnPropertyDescriptor, d = (e, t, a, o) => {
|
||||||
|
for (var s = o > 1 ? void 0 : o ? $(t, a) : t, r = e.length - 1, l; r >= 0; r--)
|
||||||
|
(l = e[r]) && (s = (o ? l(t, a, s) : l(s)) || s);
|
||||||
|
return o && s && F(t, a, s), s;
|
||||||
|
};
|
||||||
|
const n = window.Vaadin.devTools;
|
||||||
|
let i = class extends m {
|
||||||
|
constructor() {
|
||||||
|
super(...arguments), this.features = [], this.handleFeatureFlags = (e) => {
|
||||||
|
this.features = e.data.features;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
connectedCallback() {
|
||||||
|
super.connectedCallback(), this.onCommand("featureFlags", this.handleFeatureFlags);
|
||||||
|
}
|
||||||
|
render() {
|
||||||
|
return p` <style>
|
||||||
|
${b}
|
||||||
|
</style>
|
||||||
|
${this.features.map(
|
||||||
|
(e) => p`
|
||||||
|
<copilot-toggle-button
|
||||||
|
.title="${e.title}"
|
||||||
|
?checked=${e.enabled}
|
||||||
|
@on-change=${(t) => this.toggleFeatureFlag(t, e)}>
|
||||||
|
</copilot-toggle-button>
|
||||||
|
<a class="ahreflike" href="${e.moreInfoLink}" title="Learn more" target="_blank"
|
||||||
|
>learn more ${v.linkExternal}</a
|
||||||
|
>
|
||||||
|
`
|
||||||
|
)}`;
|
||||||
|
}
|
||||||
|
toggleFeatureFlag(e, t) {
|
||||||
|
const a = e.target.checked;
|
||||||
|
c("use-feature", { source: "toggle", enabled: a, id: t.id }), n.frontendConnection ? (n.frontendConnection.send("setFeature", { featureId: t.id, enabled: a }), g({
|
||||||
|
type: f.INFORMATION,
|
||||||
|
message: `“${t.title}” ${a ? "enabled" : "disabled"}`,
|
||||||
|
details: t.requiresServerRestart ? "This feature requires a server restart" : void 0,
|
||||||
|
dismissId: `feature${t.id}${a ? "Enabled" : "Disabled"}`
|
||||||
|
})) : n.log("error", `Unable to toggle feature ${t.title}: No server connection available`);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
d([
|
||||||
|
h()
|
||||||
|
], i.prototype, "features", 2);
|
||||||
|
i = d([
|
||||||
|
u("copilot-features-panel")
|
||||||
|
], i);
|
||||||
|
const w = {
|
||||||
|
header: "Features",
|
||||||
|
expanded: !1,
|
||||||
|
panelOrder: 35,
|
||||||
|
panel: "right",
|
||||||
|
floating: !1,
|
||||||
|
tag: "copilot-features-panel",
|
||||||
|
helpUrl: "https://vaadin.com/docs/latest/flow/configuration/feature-flags"
|
||||||
|
}, x = {
|
||||||
|
init(e) {
|
||||||
|
e.addPanel(w);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
window.Vaadin.copilot.plugins.push(x);
|
||||||
|
export {
|
||||||
|
i as CopilotFeaturesPanel
|
||||||
|
};
|
@ -0,0 +1,168 @@
|
|||||||
|
import { x as d, b as c, p as h, U as f, s as v, P as b, y as m, n as g } from "./copilot-xjoIJFQc.js";
|
||||||
|
import { r as p } from "./state-9-chcL5F.js";
|
||||||
|
import { m as y, e as k } from "./overlay-monkeypatch-CXhp9hXg.js";
|
||||||
|
import { B as x } from "./base-panel-CTLXjjmN.js";
|
||||||
|
import { i as w } from "./icons-AkLm3oZf.js";
|
||||||
|
const $ = "copilot-feedback-panel{display:flex;flex-direction:column;font:var(--font-xsmall);--vaadin-input-field-label-font-size: var(--font-size-1);padding:var(--space-200);gap:var(--space-200);justify-content:space-between}copilot-feedback-panel>p{margin:0}copilot-feedback-panel .dialog-footer{display:flex;gap:var(--space-100)}copilot-feedback-panel vaadin-select,copilot-feedback-panel vaadin-text-area,copilot-feedback-panel vaadin-text-field{padding-top:0;--lumo-text-field-size: 1.75rem;--vaadin-input-field-label-font-size: var(--font-size-2);--vaadin-input-field-background: none;--vaadin-input-field-border-color: transparent;--vaadin-input-field-border-width: 1px;--vaadin-input-field-border-color: var(--border-color-high-contrast);--vaadin-input-field-hover-highlight: var(--gray-100);--vaadin-input-field-hover-highlight-opacity: 1}copilot-feedback-panel vaadin-text-area>textarea{max-height:7em}copilot-feedback-panel vaadin-text-area>textarea{padding:var(--space-100) 0;font:var(--font-xsmall)}copilot-feedback-panel vaadin-text-area:hover::part(input-field){background-color:var(--gray-100)}copilot-feedback-panel vaadin-text-field>input{font:var(--font-xsmall)}copilot-feedback-panel vaadin-select::part(input-field){border-radius:var(--radius-1);flex:1;padding:0 var(--space-50)}copilot-feedback-panel vaadin-select[focus-ring]::part(input-field){box-shadow:none;outline:2px solid var(--selection-color);outline-offset:-2px}copilot-feedback-panel vaadin-select-value-button{padding:0 var(--space-50)}copilot-feedback-panel vaadin-select-item{--_lumo-selected-item-height: 1.75rem;--_lumo-selected-item-padding: 0;font:var(--font-xsmall)}copilot-feedback-panel vaadin-select-item:not([disabled]):hover{background:transparent;color:var(--color-high-contrast)}copilot-feedback-panel vaadin-combo-box-item:not([disabled]):hover{background:transparent;color:var(--color-high-contrast)}";
|
||||||
|
var A = Object.defineProperty, P = Object.getOwnPropertyDescriptor, o = (e, t, l, n) => {
|
||||||
|
for (var a = n > 1 ? void 0 : n ? P(t, l) : t, s = e.length - 1, r; s >= 0; s--)
|
||||||
|
(r = e[s]) && (a = (n ? r(t, l, a) : r(a)) || a);
|
||||||
|
return n && a && A(t, l, a), a;
|
||||||
|
};
|
||||||
|
const u = "https://github.com/vaadin/copilot/issues/new", T = "?template=feature_request.md&title=%5BFEATURE%5D", F = "A short, concise description of the bug and why you consider it a bug. Any details like exceptions and logs can be helpful as well.", D = "Please provide as many details as possible, this will help us deliver a fix as soon as possible.%0AThank you!%0A%0A%23%23%23 Description of the Bug%0A%0A{description}%0A%0A%23%23%23 Expected Behavior%0A%0AA description of what you would expect to happen. (Sometimes it is clear what the expected outcome is if something does not work, other times, it is not super clear.)%0A%0A%23%23%23 Minimal Reproducible Example%0A%0AWe would appreciate the minimum code with which we can reproduce the issue.%0A%0A%23%23%23 Versions%0A{versionsInfo}";
|
||||||
|
let i = class extends x {
|
||||||
|
constructor() {
|
||||||
|
super(), this.description = "", this.items = [
|
||||||
|
{
|
||||||
|
label: "Report a Bug",
|
||||||
|
value: "bug",
|
||||||
|
ghTitle: "[BUG]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Ask a Question",
|
||||||
|
value: "question",
|
||||||
|
ghTitle: "[QUESTION]"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Share an Idea",
|
||||||
|
value: "idea",
|
||||||
|
ghTitle: "[FEATURE]"
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
render() {
|
||||||
|
return d`<style>
|
||||||
|
${$}</style
|
||||||
|
>${this.renderContent()}${this.renderFooter()}`;
|
||||||
|
}
|
||||||
|
firstUpdated() {
|
||||||
|
y(this);
|
||||||
|
}
|
||||||
|
renderContent() {
|
||||||
|
return this.message === void 0 ? d`
|
||||||
|
<p>
|
||||||
|
Your insights are incredibly valuable to us. Whether you’ve encountered a hiccup, have questions, or ideas
|
||||||
|
to make our platform better, we're all ears! If you wish, leave your email and we’ll get back to you. You
|
||||||
|
can even share your code snippet with us for a clearer picture.
|
||||||
|
</p>
|
||||||
|
<vaadin-select
|
||||||
|
label="What's on your mind?"
|
||||||
|
theme="feedback"
|
||||||
|
.items="${this.items}"
|
||||||
|
.value="${this.items[0].value}"
|
||||||
|
@value-changed=${(e) => {
|
||||||
|
this.type = e.detail.value;
|
||||||
|
}}>
|
||||||
|
</vaadin-select>
|
||||||
|
<vaadin-text-area
|
||||||
|
.value="${this.description}"
|
||||||
|
@keydown=${this.keyDown}
|
||||||
|
@focus=${() => {
|
||||||
|
this.descriptionField.invalid = !1, this.descriptionField.placeholder = "";
|
||||||
|
}}
|
||||||
|
@value-changed=${(e) => {
|
||||||
|
this.description = e.detail.value;
|
||||||
|
}}
|
||||||
|
label="Tell Us More"
|
||||||
|
helper-text="Describe what you're experiencing, wondering about, or envisioning. The more you share, the better we can understand and act on your feedback"></vaadin-text-area>
|
||||||
|
<vaadin-text-field
|
||||||
|
@keydown=${this.keyDown}
|
||||||
|
@value-changed=${(e) => {
|
||||||
|
this.email = e.detail.value;
|
||||||
|
}}
|
||||||
|
id="email"
|
||||||
|
label="Your Email (Optional)"
|
||||||
|
helper-text="Leave your email if you’d like us to follow up. Totally optional, but we’d love to keep the conversation going."></vaadin-text-field>
|
||||||
|
` : d`<p>${this.message}</p>`;
|
||||||
|
}
|
||||||
|
renderFooter() {
|
||||||
|
return this.message === void 0 ? d`
|
||||||
|
<div class="dialog-footer">
|
||||||
|
<vaadin-button
|
||||||
|
theme="tertiary"
|
||||||
|
@click="${() => c.emit("system-info-with-callback", {
|
||||||
|
callback: (e) => this.openGithub(e, this),
|
||||||
|
notify: !1
|
||||||
|
})}">
|
||||||
|
<span style="display: flex" slot="prefix">${w.github}</span>
|
||||||
|
Create GitHub issue
|
||||||
|
</vaadin-button>
|
||||||
|
<div style="flex-grow: 1"></div>
|
||||||
|
<vaadin-button theme="tertiary" @click="${this.close}">Cancel</vaadin-button>
|
||||||
|
<vaadin-button theme="primary" @click="${this.submit}">Submit</vaadin-button>
|
||||||
|
</div>
|
||||||
|
` : d` <div class="footer">
|
||||||
|
<vaadin-button @click="${this.close}">Close</vaadin-button>
|
||||||
|
</div>`;
|
||||||
|
}
|
||||||
|
close() {
|
||||||
|
h.updatePanel("copilot-feedback-panel", {
|
||||||
|
floating: !1
|
||||||
|
});
|
||||||
|
}
|
||||||
|
submit() {
|
||||||
|
if (f("feedback"), this.description.trim() === "") {
|
||||||
|
this.descriptionField.invalid = !0, this.descriptionField.placeholder = "Please tell us more before sending", this.descriptionField.value = "";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const e = {
|
||||||
|
description: this.description,
|
||||||
|
email: this.email,
|
||||||
|
type: this.type
|
||||||
|
};
|
||||||
|
c.emit("system-info-with-callback", {
|
||||||
|
callback: (t) => v(`${b}feedback`, { ...e, versions: t }),
|
||||||
|
notify: !1
|
||||||
|
}), this.parentNode?.style.setProperty("--section-height", "150px"), this.message = "Thank you for sharing feedback.";
|
||||||
|
}
|
||||||
|
keyDown(e) {
|
||||||
|
(e.key === "Backspace" || e.key === "Delete") && e.stopPropagation();
|
||||||
|
}
|
||||||
|
openGithub(e, t) {
|
||||||
|
if (this.type === "idea") {
|
||||||
|
window.open(`${u}${T}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const l = e.replace(/\n/g, "%0A"), n = `${t.items.find((r) => r.value === this.type)?.ghTitle}`, a = t.description !== "" ? t.description : F, s = D.replace("{description}", a).replace("{versionsInfo}", l);
|
||||||
|
window.open(`${u}?title=${n}&body=${s}`, "_blank")?.focus();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
o([
|
||||||
|
p()
|
||||||
|
], i.prototype, "description", 2);
|
||||||
|
o([
|
||||||
|
p()
|
||||||
|
], i.prototype, "type", 2);
|
||||||
|
o([
|
||||||
|
p()
|
||||||
|
], i.prototype, "email", 2);
|
||||||
|
o([
|
||||||
|
p()
|
||||||
|
], i.prototype, "message", 2);
|
||||||
|
o([
|
||||||
|
p()
|
||||||
|
], i.prototype, "items", 2);
|
||||||
|
o([
|
||||||
|
k("vaadin-text-area")
|
||||||
|
], i.prototype, "descriptionField", 2);
|
||||||
|
i = o([
|
||||||
|
g("copilot-feedback-panel")
|
||||||
|
], i);
|
||||||
|
const E = m({
|
||||||
|
header: "Help Us Improve!",
|
||||||
|
tag: "copilot-feedback-panel",
|
||||||
|
width: 500,
|
||||||
|
height: 500,
|
||||||
|
floatingPosition: {
|
||||||
|
top: 50,
|
||||||
|
left: 50
|
||||||
|
}
|
||||||
|
}), U = {
|
||||||
|
init(e) {
|
||||||
|
e.addPanel(E);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
window.Vaadin.copilot.plugins.push(U);
|
||||||
|
export {
|
||||||
|
i as CopilotFeedbackPanel
|
||||||
|
};
|
File diff suppressed because one or more lines are too long
@ -0,0 +1,241 @@
|
|||||||
|
import { a as P, a5 as H, z as C, U, D as N, j as g, x as d, a6 as I, E as j, H as B, G as L, _ as O, $ as q, M as J, b as M, n as T } from "./copilot-xjoIJFQc.js";
|
||||||
|
import { r as A } from "./state-9-chcL5F.js";
|
||||||
|
import { B as V } from "./base-panel-CTLXjjmN.js";
|
||||||
|
import { i as y } from "./icons-AkLm3oZf.js";
|
||||||
|
const W = "copilot-info-panel{--dev-tools-red-color: red;--dev-tools-grey-color: gray;--dev-tools-green-color: green;position:relative}copilot-info-panel div.info-tray{display:flex;flex-direction:column;gap:10px}copilot-info-panel vaadin-button{margin-inline:var(--lumo-space-l)}copilot-info-panel dl{display:grid;grid-template-columns:auto auto;gap:0;margin:var(--space-100) var(--space-50);font:var(--font-xsmall)}copilot-info-panel dl>dt,copilot-info-panel dl>dd{padding:3px 10px;margin:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}copilot-info-panel dd.live-reload-status>span{overflow:hidden;text-overflow:ellipsis;display:block;color:var(--status-color)}copilot-info-panel dd span.hidden{display:none}copilot-info-panel dd span.true{color:var(--dev-tools-green-color);font-size:large}copilot-info-panel dd span.false{color:var(--dev-tools-red-color);font-size:large}copilot-info-panel code{white-space:nowrap;-webkit-user-select:all;user-select:all}copilot-info-panel .checks{display:inline-grid;grid-template-columns:auto 1fr;gap:var(--space-50)}copilot-info-panel span.hint{font-size:var(--font-size-0);background:var(--gray-50);padding:var(--space-75);border-radius:var(--radius-2)}";
|
||||||
|
var D, E;
|
||||||
|
function _() {
|
||||||
|
return E || (E = 1, D = function() {
|
||||||
|
var e = document.getSelection();
|
||||||
|
if (!e.rangeCount)
|
||||||
|
return function() {
|
||||||
|
};
|
||||||
|
for (var t = document.activeElement, n = [], i = 0; i < e.rangeCount; i++)
|
||||||
|
n.push(e.getRangeAt(i));
|
||||||
|
switch (t.tagName.toUpperCase()) {
|
||||||
|
// .toUpperCase handles XHTML
|
||||||
|
case "INPUT":
|
||||||
|
case "TEXTAREA":
|
||||||
|
t.blur();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
t = null;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return e.removeAllRanges(), function() {
|
||||||
|
e.type === "Caret" && e.removeAllRanges(), e.rangeCount || n.forEach(function(l) {
|
||||||
|
e.addRange(l);
|
||||||
|
}), t && t.focus();
|
||||||
|
};
|
||||||
|
}), D;
|
||||||
|
}
|
||||||
|
var k, $;
|
||||||
|
function z() {
|
||||||
|
if ($) return k;
|
||||||
|
$ = 1;
|
||||||
|
var e = _(), t = {
|
||||||
|
"text/plain": "Text",
|
||||||
|
"text/html": "Url",
|
||||||
|
default: "Text"
|
||||||
|
}, n = "Copy to clipboard: #{key}, Enter";
|
||||||
|
function i(a) {
|
||||||
|
var o = (/mac os x/i.test(navigator.userAgent) ? "⌘" : "Ctrl") + "+C";
|
||||||
|
return a.replace(/#{\s*key\s*}/g, o);
|
||||||
|
}
|
||||||
|
function l(a, o) {
|
||||||
|
var s, u, f, v, p, r, h = !1;
|
||||||
|
o || (o = {}), s = o.debug || !1;
|
||||||
|
try {
|
||||||
|
f = e(), v = document.createRange(), p = document.getSelection(), r = document.createElement("span"), r.textContent = a, r.ariaHidden = "true", r.style.all = "unset", r.style.position = "fixed", r.style.top = 0, r.style.clip = "rect(0, 0, 0, 0)", r.style.whiteSpace = "pre", r.style.webkitUserSelect = "text", r.style.MozUserSelect = "text", r.style.msUserSelect = "text", r.style.userSelect = "text", r.addEventListener("copy", function(c) {
|
||||||
|
if (c.stopPropagation(), o.format)
|
||||||
|
if (c.preventDefault(), typeof c.clipboardData > "u") {
|
||||||
|
s && console.warn("unable to use e.clipboardData"), s && console.warn("trying IE specific stuff"), window.clipboardData.clearData();
|
||||||
|
var x = t[o.format] || t.default;
|
||||||
|
window.clipboardData.setData(x, a);
|
||||||
|
} else
|
||||||
|
c.clipboardData.clearData(), c.clipboardData.setData(o.format, a);
|
||||||
|
o.onCopy && (c.preventDefault(), o.onCopy(c.clipboardData));
|
||||||
|
}), document.body.appendChild(r), v.selectNodeContents(r), p.addRange(v);
|
||||||
|
var R = document.execCommand("copy");
|
||||||
|
if (!R)
|
||||||
|
throw new Error("copy command was unsuccessful");
|
||||||
|
h = !0;
|
||||||
|
} catch (c) {
|
||||||
|
s && console.error("unable to copy using execCommand: ", c), s && console.warn("trying IE specific stuff");
|
||||||
|
try {
|
||||||
|
window.clipboardData.setData(o.format || "text", a), o.onCopy && o.onCopy(window.clipboardData), h = !0;
|
||||||
|
} catch (x) {
|
||||||
|
s && console.error("unable to copy using clipboardData: ", x), s && console.error("falling back to prompt"), u = i("message" in o ? o.message : n), window.prompt(u, a);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
p && (typeof p.removeRange == "function" ? p.removeRange(v) : p.removeAllRanges()), r && document.body.removeChild(r), f();
|
||||||
|
}
|
||||||
|
return h;
|
||||||
|
}
|
||||||
|
return k = l, k;
|
||||||
|
}
|
||||||
|
var F = z();
|
||||||
|
const G = /* @__PURE__ */ P(F);
|
||||||
|
var K = Object.defineProperty, X = Object.getOwnPropertyDescriptor, w = (e, t, n, i) => {
|
||||||
|
for (var l = i > 1 ? void 0 : i ? X(t, n) : t, a = e.length - 1, o; a >= 0; a--)
|
||||||
|
(o = e[a]) && (l = (i ? o(t, n, l) : o(l)) || l);
|
||||||
|
return i && l && K(t, n, l), l;
|
||||||
|
};
|
||||||
|
let b = class extends V {
|
||||||
|
constructor() {
|
||||||
|
super(...arguments), this.serverInfo = [], this.clientInfo = [{ name: "Browser", version: navigator.userAgent }], this.handleServerInfoEvent = (e) => {
|
||||||
|
const t = JSON.parse(e.data.info);
|
||||||
|
this.serverInfo = t.versions, H().then((n) => {
|
||||||
|
n && (this.clientInfo.unshift({ name: "Vaadin Employee", version: "true", more: void 0 }), this.requestUpdate("clientInfo"));
|
||||||
|
}), C() === "success" && U("hotswap-active", { value: N() });
|
||||||
|
};
|
||||||
|
}
|
||||||
|
connectedCallback() {
|
||||||
|
super.connectedCallback(), this.onCommand("copilot-info", this.handleServerInfoEvent), this.onEventBus("system-info-with-callback", (e) => {
|
||||||
|
e.detail.callback(this.getInfoForClipboard(e.detail.notify));
|
||||||
|
}), this.reaction(
|
||||||
|
() => g.idePluginState,
|
||||||
|
() => {
|
||||||
|
this.requestUpdate("serverInfo");
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
getIndex(e) {
|
||||||
|
return this.serverInfo.findIndex((t) => t.name === e);
|
||||||
|
}
|
||||||
|
render() {
|
||||||
|
return d`<style>
|
||||||
|
${W}
|
||||||
|
</style>
|
||||||
|
<div class="info-tray">
|
||||||
|
<dl>
|
||||||
|
${[...this.serverInfo, ...this.clientInfo].map(
|
||||||
|
(e) => d`
|
||||||
|
<dt>${e.name}</dt>
|
||||||
|
<dd title="${e.version}" style="${e.name === "Java Hotswap" ? "white-space: normal" : ""}">
|
||||||
|
${this.renderValue(e.version)} ${e.more}
|
||||||
|
</dd>
|
||||||
|
`
|
||||||
|
)}
|
||||||
|
${this.renderDevWorkflowSection()}
|
||||||
|
</dl>
|
||||||
|
${this.renderDevelopmentWorkflowButton()}
|
||||||
|
</div>`;
|
||||||
|
}
|
||||||
|
renderDevWorkflowSection() {
|
||||||
|
const e = C(), t = this.getIdePluginLabelText(g.idePluginState), n = this.getHotswapAgentLabelText(e);
|
||||||
|
return d`
|
||||||
|
<dt>Java Hotswap</dt>
|
||||||
|
<dd>${m(e === "success")} ${n}</dd>
|
||||||
|
${I() !== "unsupported" ? d`<dt>IDE Plugin</dt>
|
||||||
|
<dd>${m(I() === "success")} ${t}</dd>` : j}
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
renderDevelopmentWorkflowButton() {
|
||||||
|
const e = B();
|
||||||
|
let t = "", n = null;
|
||||||
|
return e.status === "success" ? (t = "More details...", n = y.successColorful) : e.status === "warning" ? (t = "Improve Development Workflow...", n = y.warningColorful) : e.status === "error" && (t = "Fix Development Workflow...", n = d`<span style="color: var(--red)">${y.error}</span>`), d`
|
||||||
|
<vaadin-button
|
||||||
|
id="development-workflow-guide"
|
||||||
|
@click="${() => {
|
||||||
|
L();
|
||||||
|
}}">
|
||||||
|
<span slot="prefix"> ${n}</span>
|
||||||
|
${t}</vaadin-button
|
||||||
|
>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
getHotswapAgentLabelText(e) {
|
||||||
|
return e === "success" ? "Java Hotswap is enabled" : e === "error" ? "Hotswap is partially enabled" : "Hotswap is not enabled";
|
||||||
|
}
|
||||||
|
getIdePluginLabelText(e) {
|
||||||
|
if (I() !== "success")
|
||||||
|
return "Not installed";
|
||||||
|
if (e?.version) {
|
||||||
|
let t = null;
|
||||||
|
return e?.ide && (e?.ide === "intellij" ? t = "IntelliJ" : e?.ide === "vscode" ? t = "VS Code" : e?.ide === "eclipse" && (t = "Eclipse")), t ? `${e?.version} ${t}` : e?.version;
|
||||||
|
}
|
||||||
|
return "Not installed";
|
||||||
|
}
|
||||||
|
renderValue(e) {
|
||||||
|
return e === "false" ? m(!1) : e === "true" ? m(!0) : e;
|
||||||
|
}
|
||||||
|
getInfoForClipboard(e) {
|
||||||
|
const t = this.renderRoot.querySelectorAll(".info-tray dt"), l = Array.from(t).map((a) => ({
|
||||||
|
key: a.textContent.trim(),
|
||||||
|
value: a.nextElementSibling.textContent.trim()
|
||||||
|
})).filter((a) => a.key !== "Live reload").filter((a) => !a.key.startsWith("Vaadin Emplo")).map((a) => {
|
||||||
|
const { key: o } = a;
|
||||||
|
let { value: s } = a;
|
||||||
|
if (o === "IDE Plugin")
|
||||||
|
s = this.getIdePluginLabelText(g.idePluginState) ?? "false";
|
||||||
|
else if (o === "Java Hotswap") {
|
||||||
|
const u = g.jdkInfo?.jrebel, f = C();
|
||||||
|
u && f === "success" ? s = "JRebel is in use" : s = this.getHotswapAgentLabelText(f);
|
||||||
|
}
|
||||||
|
return `${o}: ${s}`;
|
||||||
|
}).join(`
|
||||||
|
`);
|
||||||
|
return e && O({
|
||||||
|
type: q.INFORMATION,
|
||||||
|
message: "Environment information copied to clipboard",
|
||||||
|
dismissId: "versionInfoCopied"
|
||||||
|
}), l.trim();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
w([
|
||||||
|
A()
|
||||||
|
], b.prototype, "serverInfo", 2);
|
||||||
|
w([
|
||||||
|
A()
|
||||||
|
], b.prototype, "clientInfo", 2);
|
||||||
|
b = w([
|
||||||
|
T("copilot-info-panel")
|
||||||
|
], b);
|
||||||
|
let S = class extends J {
|
||||||
|
createRenderRoot() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
connectedCallback() {
|
||||||
|
super.connectedCallback(), this.style.display = "flex";
|
||||||
|
}
|
||||||
|
render() {
|
||||||
|
return d`<button title="Copy to clipboard" aria-label="Copy to clipboard" theme="icon tertiary">
|
||||||
|
<span
|
||||||
|
@click=${() => {
|
||||||
|
M.emit("system-info-with-callback", {
|
||||||
|
callback: G,
|
||||||
|
notify: !0
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
>${y.copy}</span
|
||||||
|
>
|
||||||
|
</button>`;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
S = w([
|
||||||
|
T("copilot-info-actions")
|
||||||
|
], S);
|
||||||
|
const Q = {
|
||||||
|
header: "Info",
|
||||||
|
expanded: !1,
|
||||||
|
panelOrder: 15,
|
||||||
|
panel: "right",
|
||||||
|
floating: !1,
|
||||||
|
tag: "copilot-info-panel",
|
||||||
|
actionsTag: "copilot-info-actions",
|
||||||
|
eager: !0
|
||||||
|
// Render even when collapsed as error handling depends on this
|
||||||
|
}, Y = {
|
||||||
|
init(e) {
|
||||||
|
e.addPanel(Q);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
window.Vaadin.copilot.plugins.push(Y);
|
||||||
|
function m(e) {
|
||||||
|
return e ? d`<span class="true">☑</span>` : d`<span class="false">☒</span>`;
|
||||||
|
}
|
||||||
|
export {
|
||||||
|
S as Actions,
|
||||||
|
b as CopilotInfoPanel
|
||||||
|
};
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,221 @@
|
|||||||
|
import { j as M, a1 as T, a2 as w, Y as p, x as l, $ as c, a3 as S, U as L, M as D, b as R, a4 as C, n as y } from "./copilot-xjoIJFQc.js";
|
||||||
|
import { r as $ } from "./state-9-chcL5F.js";
|
||||||
|
import { B as I } from "./base-panel-CTLXjjmN.js";
|
||||||
|
import { i as n } from "./icons-AkLm3oZf.js";
|
||||||
|
const q = "copilot-log-panel{padding:var(--space-100);font:var(--font-xsmall);display:flex;flex-direction:column;gap:var(--space-50);overflow-y:auto;max-width:100vw}copilot-log-panel .row{display:flex;align-items:flex-start;padding:var(--space-50) var(--space-100);border-radius:var(--radius-2);gap:var(--space-100)}copilot-log-panel .row.information{background-color:var(--blue-50)}copilot-log-panel .row.warning{background-color:var(--yellow-50)}copilot-log-panel .row.error{background-color:var(--red-50)}copilot-log-panel .type{margin-top:var(--space-25)}copilot-log-panel .type.error{color:var(--red)}copilot-log-panel .type.warning{color:var(--yellow)}copilot-log-panel .type.info{color:var(--color)}copilot-log-panel .message{display:flex;flex-direction:column;flex-grow:1;gap:var(--space-25);overflow:hidden}copilot-log-panel .message>*:not(.expanded){white-space:nowrap;overflow:hidden;text-overflow:ellipsis;width:100%}copilot-log-panel .message>.expanded{overflow-wrap:break-word}copilot-log-panel .firstrow{display:flex;align-items:baseline;gap:.5em;flex-direction:column}copilot-log-panel .firstrowmessage{width:100%;overflow:hidden;text-overflow:ellipsis}copilot-log-panel button{padding:0;border:0;background:transparent}copilot-log-panel svg{height:12px;width:12px}copilot-log-panel .secondrow,copilot-log-panel .timestamp{font-size:var(--font-size-0);line-height:var(--line-height-1)}copilot-log-panel .expand span{height:12px;width:12px}";
|
||||||
|
var A = Object.defineProperty, B = Object.getOwnPropertyDescriptor, h = (e, t, a, o) => {
|
||||||
|
for (var s = o > 1 ? void 0 : o ? B(t, a) : t, d = e.length - 1, i; d >= 0; d--)
|
||||||
|
(i = e[d]) && (s = (o ? i(t, a, s) : i(s)) || s);
|
||||||
|
return o && s && A(t, a, s), s;
|
||||||
|
};
|
||||||
|
class _ {
|
||||||
|
constructor() {
|
||||||
|
this.showTimestamps = !1, C(this);
|
||||||
|
}
|
||||||
|
toggleShowTimestamps() {
|
||||||
|
this.showTimestamps = !this.showTimestamps;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const g = new _();
|
||||||
|
let r = class extends I {
|
||||||
|
constructor() {
|
||||||
|
super(...arguments), this.unreadErrors = !1, this.messages = [], this.nextMessageId = 1, this.transitionDuration = 0, this.errorHandlersAdded = !1;
|
||||||
|
}
|
||||||
|
connectedCallback() {
|
||||||
|
super.connectedCallback(), this.onCommand("log", (e) => {
|
||||||
|
this.handleLogEventData({ type: e.data.type, message: e.data.message });
|
||||||
|
}), this.onEventBus("log", (e) => this.handleLogEvent(e)), this.onEventBus("update-log", (e) => this.updateLog(e.detail)), this.onEventBus("notification-shown", (e) => this.handleNotification(e)), this.onEventBus("clear-log", () => this.clear()), this.reaction(
|
||||||
|
() => M.sectionPanelResizing,
|
||||||
|
() => {
|
||||||
|
this.requestUpdate();
|
||||||
|
}
|
||||||
|
), this.transitionDuration = parseInt(
|
||||||
|
window.getComputedStyle(this).getPropertyValue("--dev-tools-transition-duration"),
|
||||||
|
10
|
||||||
|
), this.errorHandlersAdded || (T((e) => {
|
||||||
|
this.log(e.type, e.message, !!e.internal, e.details, e.link);
|
||||||
|
}), w.forEach((e) => {
|
||||||
|
this.log(e.type, e.message, !!e.internal, e.details, e.link);
|
||||||
|
}), w.length = 0, this.errorHandlersAdded = !0);
|
||||||
|
}
|
||||||
|
clear() {
|
||||||
|
this.messages = [];
|
||||||
|
}
|
||||||
|
handleNotification(e) {
|
||||||
|
this.log(e.detail.type, e.detail.message, !0, e.detail.details, e.detail.link);
|
||||||
|
}
|
||||||
|
handleLogEvent(e) {
|
||||||
|
this.handleLogEventData(e.detail);
|
||||||
|
}
|
||||||
|
handleLogEventData(e) {
|
||||||
|
this.log(
|
||||||
|
e.type,
|
||||||
|
e.message,
|
||||||
|
!!e.internal,
|
||||||
|
e.details,
|
||||||
|
e.link,
|
||||||
|
p(e.expandedMessage),
|
||||||
|
p(e.expandedDetails),
|
||||||
|
e.id
|
||||||
|
);
|
||||||
|
}
|
||||||
|
activate() {
|
||||||
|
this.unreadErrors = !1, this.updateComplete.then(() => {
|
||||||
|
const e = this.renderRoot.querySelector(".message:last-child");
|
||||||
|
e && e.scrollIntoView();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
render() {
|
||||||
|
return l`<style>
|
||||||
|
${q}
|
||||||
|
</style>
|
||||||
|
${this.messages.map((e) => this.renderMessage(e))} `;
|
||||||
|
}
|
||||||
|
renderMessage(e) {
|
||||||
|
let t, a, o;
|
||||||
|
return e.type === c.ERROR ? (t = "error", o = n.exclamationMark, a = "Error") : e.type === c.WARNING ? (t = "warning", o = n.warning, a = "Warning") : (t = "info", o = n.info, a = "Info"), e.internal && (t += " internal"), l`
|
||||||
|
<div
|
||||||
|
data-id="${e.id}"
|
||||||
|
class="row ${e.type} ${e.details || e.link ? "has-details" : ""}">
|
||||||
|
<span class="type ${t}" title="${a}">${o}</span>
|
||||||
|
<div class="message" @click=${() => this.toggleExpanded(e)}>
|
||||||
|
<span class="firstrow">
|
||||||
|
<span class="timestamp" ?hidden=${!g.showTimestamps}>${U(e.timestamp)}</span>
|
||||||
|
<span class="firstrowmessage"
|
||||||
|
>${e.expanded && e.expandedMessage ? e.expandedMessage : e.message}
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
${e.expanded ? l` <span class="secondrow expanded">${e.expandedDetails ?? e.details}</span>` : l`<span class="secondrow" ?hidden="${!e.details && !e.link}"
|
||||||
|
>${p(e.details)}
|
||||||
|
${e.link ? l`<a class="ahreflike" href="${e.link}" target="_blank">Learn more</a>` : ""}</span
|
||||||
|
>`}
|
||||||
|
</div>
|
||||||
|
<button
|
||||||
|
aria-label="Expand details"
|
||||||
|
theme="icon tertiary"
|
||||||
|
class="expand"
|
||||||
|
@click=${() => this.toggleExpanded(e)}
|
||||||
|
?hidden=${!this.canBeExpanded(e)}>
|
||||||
|
<span>${e.expanded ? n.chevronDown : n.chevronRight}</span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
log(e, t, a, o, s, d, i, E) {
|
||||||
|
const k = this.nextMessageId;
|
||||||
|
this.nextMessageId += 1, i || (i = t);
|
||||||
|
const f = {
|
||||||
|
id: k,
|
||||||
|
type: e,
|
||||||
|
message: t,
|
||||||
|
details: o,
|
||||||
|
link: s,
|
||||||
|
dontShowAgain: !1,
|
||||||
|
deleted: !1,
|
||||||
|
expanded: !1,
|
||||||
|
expandedMessage: d,
|
||||||
|
expandedDetails: i,
|
||||||
|
timestamp: /* @__PURE__ */ new Date(),
|
||||||
|
internal: a,
|
||||||
|
userId: E
|
||||||
|
};
|
||||||
|
for (this.messages.push(f); this.messages.length > r.MAX_LOG_ROWS; )
|
||||||
|
this.messages.shift();
|
||||||
|
return this.requestUpdate(), this.updateComplete.then(() => {
|
||||||
|
const m = this.renderRoot.querySelector(".message:last-child");
|
||||||
|
m ? (setTimeout(() => m.scrollIntoView({ behavior: "smooth" }), this.transitionDuration), this.unreadErrors = !1) : e === c.ERROR && (this.unreadErrors = !0);
|
||||||
|
}), f;
|
||||||
|
}
|
||||||
|
updateLog(e) {
|
||||||
|
let t = this.messages.find((a) => a.userId === e.id);
|
||||||
|
t || (t = this.log(c.INFORMATION, "<Log message to update was not found>", !1)), Object.assign(t, e), S(t.expandedDetails) && (t.expandedDetails = p(t.expandedDetails)), this.requestUpdate();
|
||||||
|
}
|
||||||
|
updated() {
|
||||||
|
const e = this.querySelector(".row:last-child");
|
||||||
|
e && this.isTooLong(e.querySelector(".firstrowmessage")) && e.querySelector("button.expand")?.removeAttribute("hidden");
|
||||||
|
}
|
||||||
|
toggleExpanded(e) {
|
||||||
|
this.canBeExpanded(e) && (e.expanded = !e.expanded, this.requestUpdate()), L("use-log", { source: "toggleExpanded" });
|
||||||
|
}
|
||||||
|
canBeExpanded(e) {
|
||||||
|
if (e.expandedMessage || e.expanded)
|
||||||
|
return !0;
|
||||||
|
const t = this.querySelector(`[data\\-id="${e.id}"]`)?.querySelector(
|
||||||
|
".firstrowmessage"
|
||||||
|
);
|
||||||
|
return this.isTooLong(t);
|
||||||
|
}
|
||||||
|
isTooLong(e) {
|
||||||
|
return e && e.offsetWidth < e.scrollWidth;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
r.MAX_LOG_ROWS = 1e3;
|
||||||
|
h([
|
||||||
|
$()
|
||||||
|
], r.prototype, "unreadErrors", 2);
|
||||||
|
h([
|
||||||
|
$()
|
||||||
|
], r.prototype, "messages", 2);
|
||||||
|
r = h([
|
||||||
|
y("copilot-log-panel")
|
||||||
|
], r);
|
||||||
|
let x = class extends D {
|
||||||
|
createRenderRoot() {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
connectedCallback() {
|
||||||
|
super.connectedCallback(), this.style.display = "flex";
|
||||||
|
}
|
||||||
|
render() {
|
||||||
|
return l`
|
||||||
|
<button title="Clear log" aria-label="Clear log" theme="icon tertiary">
|
||||||
|
<span
|
||||||
|
@click=${() => {
|
||||||
|
R.emit("clear-log", {});
|
||||||
|
}}
|
||||||
|
>${n.trash}</span
|
||||||
|
>
|
||||||
|
</button>
|
||||||
|
<button title="Toggle timestamps" aria-label="Toggle timestamps" theme="icon tertiary">
|
||||||
|
<span
|
||||||
|
class="${g.showTimestamps ? "on" : "off"}"
|
||||||
|
@click=${() => {
|
||||||
|
g.toggleShowTimestamps();
|
||||||
|
}}
|
||||||
|
>${n.clock}</span
|
||||||
|
>
|
||||||
|
</button>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
x = h([
|
||||||
|
y("copilot-log-panel-actions")
|
||||||
|
], x);
|
||||||
|
const b = {
|
||||||
|
header: "Log",
|
||||||
|
expanded: !0,
|
||||||
|
panelOrder: 0,
|
||||||
|
panel: "bottom",
|
||||||
|
floating: !1,
|
||||||
|
tag: "copilot-log-panel",
|
||||||
|
actionsTag: "copilot-log-panel-actions"
|
||||||
|
}, P = {
|
||||||
|
init(e) {
|
||||||
|
e.addPanel(b);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
window.Vaadin.copilot.plugins.push(P);
|
||||||
|
const v = { hour: "numeric", minute: "numeric", second: "numeric", fractionalSecondDigits: 3 };
|
||||||
|
let u;
|
||||||
|
try {
|
||||||
|
u = new Intl.DateTimeFormat(navigator.language, v);
|
||||||
|
} catch (e) {
|
||||||
|
console.error("Failed to create date time formatter for ", navigator.language, e), u = new Intl.DateTimeFormat("en-US", v);
|
||||||
|
}
|
||||||
|
function U(e) {
|
||||||
|
return u.format(e);
|
||||||
|
}
|
||||||
|
export {
|
||||||
|
x as Actions,
|
||||||
|
r as CopilotLogPanel
|
||||||
|
};
|
@ -0,0 +1,55 @@
|
|||||||
|
import { n as u, x as d, R as h, K as l, y as g } from "./copilot-xjoIJFQc.js";
|
||||||
|
import { B as f } from "./base-panel-CTLXjjmN.js";
|
||||||
|
import { i as e } from "./icons-AkLm3oZf.js";
|
||||||
|
const m = "copilot-shortcuts-panel{font:var(--font-xsmall);padding:var(--space-200);display:flex;flex-direction:column;gap:var(--space-50)}copilot-shortcuts-panel h3{font:var(--font-xsmall-semibold);margin:0;padding:0}copilot-shortcuts-panel h3:not(:first-of-type){margin-top:var(--space-200)}copilot-shortcuts-panel ul{list-style:none;margin:0;padding:0 var(--space-50);display:flex;flex-direction:column}copilot-shortcuts-panel ul li{display:flex;align-items:center;gap:var(--space-150);padding:var(--space-75) 0}copilot-shortcuts-panel ul li:not(:last-of-type){border-bottom:1px dashed var(--border-color)}copilot-shortcuts-panel ul li svg{height:16px;width:16px}copilot-shortcuts-panel ul li .kbds{flex:1;text-align:right}copilot-shortcuts-panel kbd{display:inline-block;border-radius:var(--radius-1);border:1px solid var(--border-color);min-width:1em;min-height:1em;text-align:center;margin:0 .1em;padding:.25em;box-sizing:border-box;font-size:var(--font-size-1);font-family:var(--font-family);line-height:1}";
|
||||||
|
var $ = Object.defineProperty, b = Object.getOwnPropertyDescriptor, v = (i, s, n, a) => {
|
||||||
|
for (var t = a > 1 ? void 0 : a ? b(s, n) : s, r = i.length - 1, p; r >= 0; r--)
|
||||||
|
(p = i[r]) && (t = (a ? p(s, n, t) : p(t)) || t);
|
||||||
|
return a && t && $(s, n, t), t;
|
||||||
|
};
|
||||||
|
let c = class extends f {
|
||||||
|
render() {
|
||||||
|
return d`<style>
|
||||||
|
${m}
|
||||||
|
</style>
|
||||||
|
<h3>Global</h3>
|
||||||
|
<ul>
|
||||||
|
<li>${e.vaadinLogo} Copilot ${o(l.toggleCopilot)}</li>
|
||||||
|
<li>${e.terminal} Command window ${o(l.toggleCommandWindow)}</li>
|
||||||
|
<li>${e.undo} Undo ${o(l.undo)}</li>
|
||||||
|
<li>${e.redo} Redo ${o(l.redo)}</li>
|
||||||
|
</ul>
|
||||||
|
<h3>Selected component</h3>
|
||||||
|
<ul>
|
||||||
|
<li>${e.code} Go to source ${o(l.goToSource)}</li>
|
||||||
|
<li>${e.copy} Copy ${o(l.copy)}</li>
|
||||||
|
<li>${e.paste} Paste ${o(l.paste)}</li>
|
||||||
|
<li>${e.duplicate} Duplicate ${o(l.duplicate)}</li>
|
||||||
|
<li>${e.userUp} Select parent ${o(l.selectParent)}</li>
|
||||||
|
<li>${e.userLeft} Select previous sibling ${o(l.selectPreviousSibling)}</li>
|
||||||
|
<li>${e.userRight} Select first child / next sibling ${o(l.selectNextSibling)}</li>
|
||||||
|
<li>${e.trash} Delete ${o(l.delete)}</li>
|
||||||
|
</ul>`;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
c = v([
|
||||||
|
u("copilot-shortcuts-panel")
|
||||||
|
], c);
|
||||||
|
function o(i) {
|
||||||
|
return d`<span class="kbds">${h(i)}</span>`;
|
||||||
|
}
|
||||||
|
const x = g({
|
||||||
|
header: "Keyboard Shortcuts",
|
||||||
|
tag: "copilot-shortcuts-panel",
|
||||||
|
width: 400,
|
||||||
|
height: 550,
|
||||||
|
floatingPosition: {
|
||||||
|
top: 50,
|
||||||
|
left: 50
|
||||||
|
}
|
||||||
|
}), y = {
|
||||||
|
init(i) {
|
||||||
|
i.addPanel(x);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
window.Vaadin.copilot.plugins.push(y);
|
File diff suppressed because one or more lines are too long
@ -0,0 +1,463 @@
|
|||||||
|
import { a9 as o } from "./copilot-xjoIJFQc.js";
|
||||||
|
const r = {
|
||||||
|
popup: o`
|
||||||
|
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path
|
||||||
|
d="M14 6.00001V2.00001M14 2.00001H10M14 2.00001L8 8M6.66667 2H5.2C4.07989 2 3.51984 2 3.09202 2.21799C2.71569 2.40973 2.40973 2.71569 2.21799 3.09202C2 3.51984 2 4.07989 2 5.2V10.8C2 11.9201 2 12.4801 2.21799 12.908C2.40973 13.2843 2.71569 13.5903 3.09202 13.782C3.51984 14 4.07989 14 5.2 14H10.8C11.9201 14 12.4801 14 12.908 13.782C13.2843 13.5903 13.5903 13.2843 13.782 12.908C14 12.4801 14 11.9201 14 10.8V9.33333"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round" />
|
||||||
|
</svg>
|
||||||
|
`,
|
||||||
|
dock: o`
|
||||||
|
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M6 12L10 8L6 4" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" />
|
||||||
|
</svg>
|
||||||
|
`,
|
||||||
|
close: o`
|
||||||
|
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M12.75 5.25L5.25 12.75M5.25 5.25L12.75 12.75" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>
|
||||||
|
`,
|
||||||
|
minus: o`
|
||||||
|
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M3.33333 8H12.6667" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" />
|
||||||
|
</svg>
|
||||||
|
`,
|
||||||
|
plus: o`
|
||||||
|
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path
|
||||||
|
d="M7.99999 3.33334V12.6667M3.33333 8.00001H12.6667"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round" />
|
||||||
|
</svg>
|
||||||
|
`,
|
||||||
|
arrowLeft: o`
|
||||||
|
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path
|
||||||
|
d="M13.3333 8H2.66667M2.66667 8L6.66667 12M2.66667 8L6.66667 4"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round" />
|
||||||
|
</svg>
|
||||||
|
`,
|
||||||
|
chevronLeft: o`
|
||||||
|
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M11.25 13.5L6.75 9L11.25 4.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>
|
||||||
|
`,
|
||||||
|
chevronRight: o`
|
||||||
|
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M6.75 13.5L11.25 9L6.75 4.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>
|
||||||
|
`,
|
||||||
|
chevronDown: o`
|
||||||
|
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M4.5 6.75L9 11.25L13.5 6.75" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>
|
||||||
|
`,
|
||||||
|
chevronUp: o`
|
||||||
|
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M13.5 11.25L9 6.75L4.5 11.25" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>
|
||||||
|
`,
|
||||||
|
edit: o`
|
||||||
|
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path
|
||||||
|
d="M12.0001 6.66667L9.33344 4.00001M1.66675 14.3333L3.92299 14.0827C4.19865 14.052 4.33648 14.0367 4.46531 13.995C4.57961 13.958 4.68838 13.9057 4.78867 13.8396C4.90171 13.765 4.99977 13.667 5.1959 13.4709L14.0001 4.66667C14.7365 3.93029 14.7365 2.73639 14.0001 2.00001C13.2637 1.26363 12.0698 1.26363 11.3334 2.00001L2.52923 10.8042C2.33311 11.0003 2.23505 11.0983 2.16051 11.2114C2.09437 11.3117 2.04209 11.4205 2.00509 11.5348C1.96339 11.6636 1.94807 11.8014 1.91744 12.0771L1.66675 14.3333Z"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round" />
|
||||||
|
</svg>
|
||||||
|
`,
|
||||||
|
editAlt: o`
|
||||||
|
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g clip-path="url(#clip0_171_17)">
|
||||||
|
<path
|
||||||
|
d="M7.33325 2.66665H4.53325C3.41315 2.66665 2.85309 2.66665 2.42527 2.88464C2.04895 3.07639 1.74299 3.38235 1.55124 3.75867C1.33325 4.1865 1.33325 4.74655 1.33325 5.86665V11.4667C1.33325 12.5867 1.33325 13.1468 1.55124 13.5747C1.74299 13.9509 2.04895 14.2569 2.42527 14.4487C2.85309 14.6667 3.41315 14.6667 4.53325 14.6667H10.1333C11.2534 14.6667 11.8134 14.6667 12.2413 14.4487C12.6176 14.2569 12.9235 13.9509 13.1153 13.5747C13.3333 13.1468 13.3333 12.5867 13.3333 11.4667V8.66667M5.33323 10.6667H6.4496C6.77572 10.6667 6.93879 10.6667 7.09225 10.6298C7.22825 10.5971 7.35832 10.5433 7.47765 10.4702C7.61219 10.3877 7.72752 10.2724 7.95812 10.0418L14.3333 3.66665C14.8855 3.11437 14.8855 2.21894 14.3333 1.66665C13.781 1.11437 12.8855 1.11437 12.3333 1.66665L5.95807 8.0418C5.72747 8.2724 5.61217 8.38773 5.52971 8.52227C5.45661 8.6416 5.40274 8.7716 5.37007 8.90767C5.33323 9.06113 5.33323 9.2242 5.33323 9.55033V10.6667Z"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round" />
|
||||||
|
</g>
|
||||||
|
<defs>
|
||||||
|
<clipPath id="clip0_171_17">
|
||||||
|
<rect width="16" height="16" fill="white" />
|
||||||
|
</clipPath>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
||||||
|
`,
|
||||||
|
code: o`<svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M14 2.26953V6.40007C14 6.96012 14 7.24015 14.109 7.45406C14.2049 7.64222 14.3578 7.7952 14.546 7.89108C14.7599 8.00007 15.0399 8.00007 15.6 8.00007H19.7305M14 17.5L16.5 15L14 12.5M10 12.5L7.5 15L10 17.5M20 9.98822V17.2C20 18.8802 20 19.7202 19.673 20.362C19.3854 20.9265 18.9265 21.3854 18.362 21.673C17.7202 22 16.8802 22 15.2 22H8.8C7.11984 22 6.27976 22 5.63803 21.673C5.07354 21.3854 4.6146 20.9265 4.32698 20.362C4 19.7202 4 18.8802 4 17.2V6.8C4 5.11984 4 4.27976 4.32698 3.63803C4.6146 3.07354 5.07354 2.6146 5.63803 2.32698C6.27976 2 7.11984 2 8.8 2H12.0118C12.7455 2 13.1124 2 13.4577 2.08289C13.7638 2.15638 14.0564 2.27759 14.3249 2.44208C14.6276 2.6276 14.887 2.88703 15.4059 3.40589L18.5941 6.59411C19.113 7.11297 19.3724 7.3724 19.5579 7.67515C19.7224 7.94356 19.8436 8.2362 19.9171 8.5423C20 8.88757 20 9.25445 20 9.98822Z" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>
|
||||||
|
`,
|
||||||
|
codeAlt: o`<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path
|
||||||
|
d="M3.33341 12.3333C3.33341 12.6429 3.33341 12.7977 3.35053 12.9277C3.46868 13.8252 4.17489 14.5314 5.07236 14.6495C5.20233 14.6666 5.35713 14.6666 5.66675 14.6666H10.8001C11.9202 14.6666 12.4802 14.6666 12.9081 14.4486C13.2844 14.2569 13.5903 13.951 13.7821 13.5746C14.0001 13.1468 14.0001 12.5868 14.0001 11.4666V6.65879C14.0001 6.16961 14.0001 5.92503 13.9448 5.69485C13.8958 5.49078 13.815 5.29569 13.7053 5.11675C13.5817 4.91491 13.4087 4.74195 13.0628 4.39605L10.9373 2.27057C10.5914 1.92467 10.4185 1.75171 10.2167 1.62803C10.0377 1.51837 9.84261 1.43757 9.63855 1.38857C9.40835 1.33331 9.16375 1.33331 8.67461 1.33331H5.66675C5.35713 1.33331 5.20233 1.33331 5.07236 1.35043C4.17489 1.46858 3.46868 2.17479 3.35053 3.07226C3.33341 3.20223 3.33341 3.35703 3.33341 3.66665M6.00008 9.66665L7.66675 7.99998L6.00008 6.33331M3.33341 6.33331L1.66675 7.99998L3.33341 9.66665"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="1"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round" />
|
||||||
|
</svg>
|
||||||
|
`,
|
||||||
|
trash: o`<svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M16 6V5.2C16 4.0799 16 3.51984 15.782 3.09202C15.5903 2.71569 15.2843 2.40973 14.908 2.21799C14.4802 2 13.9201 2 12.8 2H11.2C10.0799 2 9.51984 2 9.09202 2.21799C8.71569 2.40973 8.40973 2.71569 8.21799 3.09202C8 3.51984 8 4.0799 8 5.2V6M10 11.5V16.5M14 11.5V16.5M3 6H21M19 6V17.2C19 18.8802 19 19.7202 18.673 20.362C18.3854 20.9265 17.9265 21.3854 17.362 21.673C16.7202 22 15.8802 22 14.2 22H9.8C8.11984 22 7.27976 22 6.63803 21.673C6.07354 21.3854 5.6146 20.9265 5.32698 20.362C5 19.7202 5 18.8802 5 17.2V6" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>`,
|
||||||
|
clock: o`<svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M12 6V12L16 14M22 12C22 17.5228 17.5228 22 12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2C17.5228 2 22 6.47715 22 12Z" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>`,
|
||||||
|
exclamationMark: o`<svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M12 8V12M12 16H12.01M22 12C22 17.5228 17.5228 22 12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2C17.5228 2 22 6.47715 22 12Z" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>`,
|
||||||
|
warning: o`<svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M11.9998 8.99999V13M11.9998 17H12.0098M10.6151 3.89171L2.39019 18.0983C1.93398 18.8863 1.70588 19.2803 1.73959 19.6037C1.769 19.8857 1.91677 20.142 2.14613 20.3088C2.40908 20.5 2.86435 20.5 3.77487 20.5H20.2246C21.1352 20.5 21.5904 20.5 21.8534 20.3088C22.0827 20.142 22.2305 19.8857 22.2599 19.6037C22.2936 19.2803 22.0655 18.8863 21.6093 18.0983L13.3844 3.89171C12.9299 3.10654 12.7026 2.71396 12.4061 2.58211C12.1474 2.4671 11.8521 2.4671 11.5935 2.58211C11.2969 2.71396 11.0696 3.10655 10.6151 3.89171Z" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>`,
|
||||||
|
refresh: o`
|
||||||
|
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M14.6667 6.66667C14.6667 6.66667 13.33 4.84548 12.2441 3.75883C11.1582 2.67218 9.6576 2 8 2C4.68629 2 2 4.68629 2 8C2 11.3137 4.68629 14 8 14C10.7354 14 13.0433 12.1695 13.7655 9.66667M14.6667 6.66667V2.66667M14.6667 6.66667H10.6667" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>
|
||||||
|
`,
|
||||||
|
save: o`
|
||||||
|
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M4.66667 2V4.26667C4.66667 4.64003 4.66667 4.82672 4.73933 4.96933C4.80325 5.09477 4.90523 5.19675 5.03067 5.26067C5.17328 5.33333 5.35997 5.33333 5.73333 5.33333H10.2667C10.6401 5.33333 10.8267 5.33333 10.9693 5.26067C11.0948 5.19675 11.1967 5.09477 11.2607 4.96933C11.3333 4.82672 11.3333 4.64003 11.3333 4.26667V2.66667M11.3333 14V9.73333C11.3333 9.35993 11.3333 9.17327 11.2607 9.03067C11.1967 8.9052 11.0948 8.80327 10.9693 8.73933C10.8267 8.66667 10.6401 8.66667 10.2667 8.66667H5.73333C5.35997 8.66667 5.17328 8.66667 5.03067 8.73933C4.90523 8.80327 4.80325 8.9052 4.73933 9.03067C4.66667 9.17327 4.66667 9.35993 4.66667 9.73333V14M14 6.21699V10.8C14 11.9201 14 12.4801 13.782 12.908C13.5903 13.2843 13.2843 13.5903 12.908 13.782C12.4801 14 11.9201 14 10.8 14H5.2C4.07989 14 3.51984 14 3.09202 13.782C2.71569 13.5903 2.40973 13.2843 2.21799 12.908C2 12.4801 2 11.9201 2 10.8V5.2C2 4.07989 2 3.51984 2.21799 3.09202C2.40973 2.71569 2.71569 2.40973 3.09202 2.21799C3.51984 2 4.07989 2 5.2 2H9.783C10.1091 2 10.2722 2 10.4257 2.03684C10.5617 2.0695 10.6917 2.12337 10.8111 2.19648C10.9456 2.27893 11.0609 2.39423 11.2915 2.62484L13.3751 4.70849C13.6057 4.9391 13.7211 5.0544 13.8035 5.18895C13.8766 5.30825 13.9305 5.43831 13.9631 5.57436C14 5.72781 14 5.89087 14 6.21699Z" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>
|
||||||
|
`,
|
||||||
|
info: o`<svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M12 16V12M12 8H12.01M22 12C22 17.5228 17.5228 22 12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2C17.5228 2 22 6.47715 22 12Z" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>`,
|
||||||
|
github: o`
|
||||||
|
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g clip-path="url(#clip0_202_25)">
|
||||||
|
<path fill-rule="evenodd" clip-rule="evenodd" d="M7.97616 0C3.56555 0 0 3.59184 0 8.03543C0 11.5874 2.28457 14.5941 5.45388 15.6583C5.85012 15.7383 5.99527 15.4854 5.99527 15.2727C5.99527 15.0864 5.9822 14.4478 5.9822 13.7825C3.76343 14.2616 3.30139 12.8247 3.30139 12.8247C2.94482 11.8934 2.41649 11.654 2.41649 11.654C1.69029 11.1618 2.46939 11.1618 2.46939 11.1618C3.27494 11.215 3.69763 11.9866 3.69763 11.9866C4.41061 13.2104 5.55951 12.8647 6.02171 12.6518C6.08767 12.1329 6.2991 11.7737 6.52359 11.5742C4.75396 11.3879 2.89208 10.6962 2.89208 7.60963C2.89208 6.73159 3.20882 6.01322 3.71069 5.45453C3.63151 5.25502 3.35412 4.43004 3.79004 3.32588C3.79004 3.32588 4.46351 3.11298 5.98204 4.15069C6.63218 3.9748 7.30265 3.88532 7.97616 3.88457C8.64963 3.88457 9.33616 3.9778 9.97012 4.15069C11.4888 3.11298 12.1623 3.32588 12.1623 3.32588C12.5982 4.43004 12.3207 5.25502 12.2415 5.45453C12.7566 6.01322 13.0602 6.73159 13.0602 7.60963C13.0602 10.6962 11.1984 11.3745 9.41551 11.5742C9.70612 11.8269 9.9569 12.3058 9.9569 13.0642C9.9569 14.1417 9.94384 15.0065 9.94384 15.2725C9.94384 15.4854 10.0891 15.7383 10.4852 15.6584C13.6545 14.594 15.9391 11.5874 15.9391 8.03543C15.9522 3.59184 12.3736 0 7.97616 0Z" fill="currentColor" />
|
||||||
|
</g>
|
||||||
|
<defs>
|
||||||
|
<clipPath id="clip0_202_25">
|
||||||
|
<rect width="16" height="15.6735" fill="white" />
|
||||||
|
</clipPath>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
||||||
|
`,
|
||||||
|
play: o`
|
||||||
|
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M3.33334 3.32634C3.33334 2.6789 3.33334 2.35518 3.46833 2.17674C3.58593 2.02128 3.76568 1.92508 3.96027 1.91346C4.18363 1.90012 4.45298 2.07969 4.99168 2.43882L12.0021 7.1124C12.4472 7.40914 12.6697 7.55754 12.7473 7.74454C12.8151 7.90807 12.8151 8.0918 12.7473 8.25534C12.6697 8.44234 12.4472 8.59067 12.0021 8.88747L4.99168 13.561C4.45298 13.9201 4.18363 14.0997 3.96027 14.0864C3.76568 14.0748 3.58593 13.9786 3.46833 13.8231C3.33334 13.6447 3.33334 13.3209 3.33334 12.6735V3.32634Z" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>
|
||||||
|
`,
|
||||||
|
loading: o`
|
||||||
|
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M8 1.5V3.16667M8 12V14.6667M3.83333 8H1.5M14.1667 8H13.1667M12.3047 12.3047L11.8333 11.8333M12.4428 3.61053L11.5 4.55333M3.28105 12.7189L5.16667 10.8333M3.41912 3.47245L4.83333 4.88667" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>
|
||||||
|
`,
|
||||||
|
error: o`
|
||||||
|
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g clip-path="url(#clip0_216_291)">
|
||||||
|
<path d="M8 5.33334V8.00001M14.6667 8.00001C14.6667 11.6819 11.6819 14.6667 8 14.6667C4.31809 14.6667 1.33333 11.6819 1.33333 8.00001C1.33333 4.31811 4.31809 1.33334 8 1.33334C11.6819 1.33334 14.6667 4.31811 14.6667 8.00001Z" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<circle cx="8" cy="10.67" r="0.5" fill="currentColor"/>
|
||||||
|
</g>
|
||||||
|
<defs>
|
||||||
|
<clipPath id="clip0_216_291">
|
||||||
|
<rect width="16" height="16" fill="white"/>
|
||||||
|
</clipPath>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
||||||
|
`,
|
||||||
|
help: o`
|
||||||
|
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g clip-path="url(#clip0_226_27)">
|
||||||
|
<path d="M6.06 6.00001C6.21673 5.55446 6.52609 5.17875 6.93333 4.93943C7.34053 4.70012 7.81926 4.61264 8.2848 4.69248C8.75033 4.77234 9.17253 5.01436 9.47673 5.3757C9.78086 5.73703 9.9474 6.19436 9.94666 6.66668C9.94666 8.00001 7.94666 8.66668 7.94666 8.66668M14.6667 8.00001C14.6667 11.6819 11.6819 14.6667 8 14.6667C4.31809 14.6667 1.33333 11.6819 1.33333 8.00001C1.33333 4.31811 4.31809 1.33334 8 1.33334C11.6819 1.33334 14.6667 4.31811 14.6667 8.00001Z" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<circle cx="8" cy="11.33" r="0.5" fill="currentColor"/>
|
||||||
|
</g>
|
||||||
|
<defs>
|
||||||
|
<clipPath id="clip0_226_27">
|
||||||
|
<rect width="16" height="16" fill="white"/>
|
||||||
|
</clipPath>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
||||||
|
`,
|
||||||
|
copy: o`<svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M10.5 2.0028C9.82495 2.01194 9.4197 2.05103 9.09202 2.21799C8.71569 2.40973 8.40973 2.71569 8.21799 3.09202C8.05103 3.4197 8.01194 3.82495 8.0028 4.5M19.5 2.0028C20.1751 2.01194 20.5803 2.05103 20.908 2.21799C21.2843 2.40973 21.5903 2.71569 21.782 3.09202C21.949 3.4197 21.9881 3.82494 21.9972 4.49999M21.9972 13.5C21.9881 14.175 21.949 14.5803 21.782 14.908C21.5903 15.2843 21.2843 15.5903 20.908 15.782C20.5803 15.949 20.1751 15.9881 19.5 15.9972M22 7.99999V9.99999M14.0001 2H16M5.2 22H12.8C13.9201 22 14.4802 22 14.908 21.782C15.2843 21.5903 15.5903 21.2843 15.782 20.908C16 20.4802 16 19.9201 16 18.8V11.2C16 10.0799 16 9.51984 15.782 9.09202C15.5903 8.71569 15.2843 8.40973 14.908 8.21799C14.4802 8 13.9201 8 12.8 8H5.2C4.0799 8 3.51984 8 3.09202 8.21799C2.71569 8.40973 2.40973 8.71569 2.21799 9.09202C2 9.51984 2 10.0799 2 11.2V18.8C2 19.9201 2 20.4802 2.21799 20.908C2.40973 21.2843 2.71569 21.5903 3.09202 21.782C3.51984 22 4.07989 22 5.2 22Z" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>`,
|
||||||
|
paste: o`<svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M16 4C16.93 4 17.395 4 17.7765 4.10222C18.8117 4.37962 19.6204 5.18827 19.8978 6.22354C20 6.60504 20 7.07003 20 8V17.2C20 18.8802 20 19.7202 19.673 20.362C19.3854 20.9265 18.9265 21.3854 18.362 21.673C17.7202 22 16.8802 22 15.2 22H8.8C7.11984 22 6.27976 22 5.63803 21.673C5.07354 21.3854 4.6146 20.9265 4.32698 20.362C4 19.7202 4 18.8802 4 17.2V8C4 7.07003 4 6.60504 4.10222 6.22354C4.37962 5.18827 5.18827 4.37962 6.22354 4.10222C6.60504 4 7.07003 4 8 4M9.6 6H14.4C14.9601 6 15.2401 6 15.454 5.89101C15.6422 5.79513 15.7951 5.64215 15.891 5.45399C16 5.24008 16 4.96005 16 4.4V3.6C16 3.03995 16 2.75992 15.891 2.54601C15.7951 2.35785 15.6422 2.20487 15.454 2.10899C15.2401 2 14.9601 2 14.4 2H9.6C9.03995 2 8.75992 2 8.54601 2.10899C8.35785 2.20487 8.20487 2.35785 8.10899 2.54601C8 2.75992 8 3.03995 8 3.6V4.4C8 4.96005 8 5.24008 8.10899 5.45399C8.20487 5.64215 8.35785 5.79513 8.54601 5.89101C8.75992 6 9.03995 6 9.6 6Z" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>`,
|
||||||
|
duplicate: o`<svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M8 8V5.2C8 4.0799 8 3.51984 8.21799 3.09202C8.40973 2.71569 8.71569 2.40973 9.09202 2.21799C9.51984 2 10.0799 2 11.2 2H18.8C19.9201 2 20.4802 2 20.908 2.21799C21.2843 2.40973 21.5903 2.71569 21.782 3.09202C22 3.51984 22 4.0799 22 5.2V12.8C22 13.9201 22 14.4802 21.782 14.908C21.5903 15.2843 21.2843 15.5903 20.908 15.782C20.4802 16 19.9201 16 18.8 16H16M5.2 22H12.8C13.9201 22 14.4802 22 14.908 21.782C15.2843 21.5903 15.5903 21.2843 15.782 20.908C16 20.4802 16 19.9201 16 18.8V11.2C16 10.0799 16 9.51984 15.782 9.09202C15.5903 8.71569 15.2843 8.40973 14.908 8.21799C14.4802 8 13.9201 8 12.8 8H5.2C4.0799 8 3.51984 8 3.09202 8.21799C2.71569 8.40973 2.40973 8.71569 2.21799 9.09202C2 9.51984 2 10.0799 2 11.2V18.8C2 19.9201 2 20.4802 2.21799 20.908C2.40973 21.2843 2.71569 21.5903 3.09202 21.782C3.51984 22 4.07989 22 5.2 22Z" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>`,
|
||||||
|
overlay: o`
|
||||||
|
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<g clip-path="url(#clip0_211_179)">
|
||||||
|
<path d="M1.33325 3.46665C1.33325 2.71991 1.33325 2.34654 1.47858 2.06133C1.60641 1.81044 1.81038 1.60647 2.06127 1.47864C2.34648 1.33331 2.71985 1.33331 3.46659 1.33331H8.53325C9.27998 1.33331 9.65338 1.33331 9.93858 1.47864C10.1895 1.60647 10.3935 1.81044 10.5213 2.06133C10.6666 2.34654 10.6666 2.71991 10.6666 3.46665V8.53331C10.6666 9.28005 10.6666 9.65345 10.5213 9.93865C10.3935 10.1895 10.1895 10.3935 9.93858 10.5213C9.65338 10.6666 9.27998 10.6666 8.53325 10.6666H3.46659C2.71985 10.6666 2.34648 10.6666 2.06127 10.5213C1.81038 10.3935 1.60641 10.1895 1.47858 9.93865C1.33325 9.65345 1.33325 9.28005 1.33325 8.53331V3.46665Z" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" />
|
||||||
|
<path d="M5.33325 7.46665C5.33325 6.71991 5.33325 6.34654 5.47858 6.06133C5.60641 5.81044 5.81038 5.60647 6.06127 5.47864C6.34648 5.33331 6.71985 5.33331 7.46659 5.33331H12.5333C13.28 5.33331 13.6534 5.33331 13.9386 5.47864C14.1895 5.60647 14.3935 5.81044 14.5213 6.06133C14.6666 6.34654 14.6666 6.71991 14.6666 7.46665V12.5333C14.6666 13.28 14.6666 13.6534 14.5213 13.9386C14.3935 14.1895 14.1895 14.3935 13.9386 14.5213C13.6534 14.6666 13.28 14.6666 12.5333 14.6666H7.46659C6.71985 14.6666 6.34648 14.6666 6.06127 14.5213C5.81038 14.3935 5.60641 14.1895 5.47858 13.9386C5.33325 13.6534 5.33325 13.28 5.33325 12.5333V7.46665Z" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" />
|
||||||
|
</g>
|
||||||
|
<defs>
|
||||||
|
<clipPath id="clip0_211_179">
|
||||||
|
<rect width="16" height="16" fill="white" />
|
||||||
|
</clipPath>
|
||||||
|
</defs>
|
||||||
|
</svg>
|
||||||
|
`,
|
||||||
|
linkExternal: o`<svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M21 9L21 3M21 3H15M21 3L13 11M10 5H7.8C6.11984 5 5.27976 5 4.63803 5.32698C4.07354 5.6146 3.6146 6.07354 3.32698 6.63803C3 7.27976 3 8.11984 3 9.8V16.2C3 17.8802 3 18.7202 3.32698 19.362C3.6146 19.9265 4.07354 20.3854 4.63803 20.673C5.27976 21 6.11984 21 7.8 21H14.2C15.8802 21 16.7202 21 17.362 20.673C17.9265 20.3854 18.3854 19.9265 18.673 19.362C19 18.7202 19 17.8802 19 16.2V14" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>`,
|
||||||
|
locked: o`<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M11.3333 7.33333V5.33333C11.3333 3.49239 9.84093 2 8 2C6.15905 2 4.66667 3.49239 4.66667 5.33333C4.66667 5.33333 4.66667 6.55228 4.66667 7.33333" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" />
|
||||||
|
<path d="M5.86667 14H10.1333C11.2535 14 11.8135 14 12.2413 13.782C12.6177 13.5903 12.9236 13.2843 13.1153 12.908C13.3333 12.4801 13.3333 11.9201 13.3333 10.8V10.5333C13.3333 9.41321 13.3333 8.85321 13.1153 8.42534C12.9236 8.04901 12.6177 7.74308 12.2413 7.55134C11.8135 7.33334 11.2535 7.33334 10.1333 7.33334H5.86667C4.74656 7.33334 4.18651 7.33334 3.75869 7.55134C3.38236 7.74308 3.0764 8.04901 2.88465 8.42534C2.66667 8.85321 2.66667 9.41321 2.66667 10.5333V10.8C2.66667 11.9201 2.66667 12.4801 2.88465 12.908C3.0764 13.2843 3.38236 13.5903 3.75869 13.782C4.18651 14 4.74656 14 5.86667 14Z" fill="currentColor" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" />
|
||||||
|
</svg>`,
|
||||||
|
unlocked: o`<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M4.66666 7.33333V5.33333C4.66666 3.49239 6.15905 2 8 2C9.61266 2 10.9578 3.14517 11.2667 4.66667M5.86666 14H10.1333C11.2535 14 11.8135 14 12.2413 13.782C12.6177 13.5903 12.9236 13.2843 13.1153 12.908C13.3333 12.4801 13.3333 11.9201 13.3333 10.8V10.5333C13.3333 9.4132 13.3333 8.8532 13.1153 8.42533C12.9236 8.049 12.6177 7.74307 12.2413 7.55133C11.8135 7.33333 11.2535 7.33333 10.1333 7.33333H5.86666C4.74656 7.33333 4.1865 7.33333 3.75868 7.55133C3.38236 7.74307 3.0764 8.049 2.88465 8.42533C2.66666 8.8532 2.66666 9.4132 2.66666 10.5333V10.8C2.66666 11.9201 2.66666 12.4801 2.88465 12.908C3.0764 13.2843 3.38236 13.5903 3.75868 13.782C4.1865 14 4.74656 14 5.86666 14Z" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" />
|
||||||
|
</svg>`,
|
||||||
|
rhombus: o`<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M2.88562 9.88559C2.22559 9.22556 1.89557 8.89554 1.77193 8.515C1.66316 8.18026 1.66316 7.81968 1.77193 7.48494C1.89557 7.1044 2.22559 6.77438 2.88562 6.11435L6.18545 2.81452C6.8455 2.15447 7.17548 1.82449 7.55605 1.70082C7.89079 1.59205 8.25136 1.59207 8.58609 1.70084C8.96664 1.82448 9.29666 2.15449 9.95669 2.81452L13.2565 6.11435C13.9166 6.7744 14.2465 7.10438 14.3702 7.48496C14.479 7.8197 14.479 8.18024 14.3702 8.51498C14.2465 8.89556 13.9166 9.22554 13.2565 9.88559L9.95669 13.1854C9.29666 13.8454 8.96664 14.1755 8.58609 14.2991C8.25136 14.4079 7.89079 14.4079 7.55605 14.2991C7.17548 14.1754 6.8455 13.8455 6.18545 13.1854L2.88562 9.88559Z" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>`,
|
||||||
|
atom: o`<svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M11.9995 12.0001H12.0095M15.535 15.5357C10.8488 20.222 5.46685 22.438 3.51423 20.4854C1.56161 18.5328 3.77769 13.1509 8.46398 8.46461C13.1503 3.77832 18.5322 1.56224 20.4848 3.51486C22.4374 5.46748 20.2213 10.8494 15.535 15.5357ZM15.535 8.46443C20.2213 13.1507 22.4374 18.5326 20.4848 20.4852C18.5321 22.4379 13.1502 20.2218 8.46394 15.5355C3.77765 10.8492 1.56157 5.4673 3.51419 3.51468C5.46681 1.56206 10.8487 3.77814 15.535 8.46443ZM12.4995 12.0001C12.4995 12.2763 12.2757 12.5001 11.9995 12.5001C11.7234 12.5001 11.4995 12.2763 11.4995 12.0001C11.4995 11.724 11.7234 11.5001 11.9995 11.5001C12.2757 11.5001 12.4995 11.724 12.4995 12.0001Z" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>`,
|
||||||
|
codeSnippet: o`<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M10.6667 12L14.6667 8L10.6667 4M5.33333 4L1.33333 8L5.33333 12" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>`,
|
||||||
|
thumbsUp: o`<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M4.66667 14.6667V7.33334M1.33334 8.66668V13.3333C1.33334 14.0697 1.93029 14.6667 2.66667 14.6667H11.6175C12.6047 14.6667 13.4441 13.9465 13.5943 12.9708L14.3122 8.30414C14.4986 7.09261 13.5612 6.00001 12.3355 6.00001H10C9.6318 6.00001 9.33334 5.70153 9.33334 5.33334V2.97724C9.33334 2.06934 8.59734 1.33334 7.68947 1.33334C7.47287 1.33334 7.27667 1.46088 7.18874 1.65876L4.84263 6.93741C4.73563 7.17821 4.49688 7.33334 4.23342 7.33334H2.66667C1.93029 7.33334 1.33334 7.93028 1.33334 8.66668Z" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>`,
|
||||||
|
thumbsUpFilled: o`<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M4.66666 14.6667V7.33334ZM1.33333 8.66668V13.3333C1.33333 14.0697 1.93028 14.6667 2.66666 14.6667H11.6175C12.6047 14.6667 13.4441 13.9465 13.5943 12.9708L14.3122 8.30414C14.4986 7.09261 13.5612 6.00001 12.3355 6.00001H10C9.6318 6.00001 9.33333 5.70153 9.33333 5.33334V2.97724C9.33333 2.06934 8.59733 1.33334 7.68946 1.33334C7.47286 1.33334 7.27666 1.46088 7.18873 1.65876L4.84262 6.93741C4.73562 7.17821 4.49688 7.33334 4.23342 7.33334H2.66666C1.93028 7.33334 1.33333 7.93028 1.33333 8.66668Z" fill="currentColor"/>
|
||||||
|
<path d="M4.66666 14.6667V7.33334M1.33333 8.66668V13.3333C1.33333 14.0697 1.93028 14.6667 2.66666 14.6667H11.6175C12.6047 14.6667 13.4441 13.9465 13.5943 12.9708L14.3122 8.30414C14.4986 7.09261 13.5612 6.00001 12.3355 6.00001H10C9.6318 6.00001 9.33333 5.70153 9.33333 5.33334V2.97724C9.33333 2.06934 8.59733 1.33334 7.68946 1.33334C7.47286 1.33334 7.27666 1.46088 7.18873 1.65876L4.84262 6.93741C4.73562 7.17821 4.49688 7.33334 4.23342 7.33334H2.66666C1.93028 7.33334 1.33333 7.93028 1.33333 8.66668Z" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>`,
|
||||||
|
thumbsDown: o`<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M11.3334 1.33334V8.66668M14.6667 6.53334V3.46668C14.6667 2.71994 14.6667 2.34657 14.5214 2.06136C14.3935 1.81047 14.1896 1.6065 13.9387 1.47867C13.6535 1.33334 13.2801 1.33334 12.5334 1.33334H5.41204C4.43772 1.33334 3.95056 1.33334 3.55709 1.51163C3.2103 1.66877 2.91557 1.92162 2.70753 2.24049C2.47148 2.60227 2.39741 3.08377 2.24926 4.04676L1.90054 6.31342C1.70514 7.58354 1.60743 8.21861 1.79591 8.71274C1.96133 9.14648 2.27247 9.50914 2.67599 9.73861C3.13572 10 3.77826 10 5.06333 10H5.60004C5.97341 10 6.16009 10 6.3027 10.0727C6.42814 10.1366 6.53013 10.2385 6.59404 10.364C6.66674 10.5066 6.66674 10.6933 6.66674 11.0667V13.0228C6.66674 13.9307 7.40267 14.6667 8.3106 14.6667C8.52714 14.6667 8.7234 14.5391 8.81134 14.3413L11.0519 9.30014C11.1537 9.07081 11.2047 8.95621 11.2852 8.87214C11.3564 8.79781 11.4439 8.74101 11.5407 8.70614C11.6502 8.66668 11.7757 8.66668 12.0265 8.66668H12.5334C13.2801 8.66668 13.6535 8.66668 13.9387 8.52134C14.1896 8.39354 14.3935 8.18954 14.5214 7.93868C14.6667 7.65348 14.6667 7.28008 14.6667 6.53334Z" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>`,
|
||||||
|
thumbsDownFilled: o`<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M11.3334 1.33334V8.66668ZM14.6667 6.53334V3.46668C14.6667 2.71994 14.6667 2.34657 14.5214 2.06136C14.3935 1.81047 14.1896 1.6065 13.9387 1.47867C13.6535 1.33334 13.2801 1.33334 12.5334 1.33334H5.41204C4.43772 1.33334 3.95056 1.33334 3.55708 1.51163C3.2103 1.66877 2.91556 1.92162 2.70752 2.24049C2.47148 2.60227 2.3974 3.08377 2.24925 4.04676L1.90053 6.31342C1.70513 7.58354 1.60742 8.21861 1.7959 8.71274C1.96132 9.14648 2.27246 9.50914 2.67598 9.73861C3.13572 10 3.77826 10 5.06332 10H5.60003C5.9734 10 6.16008 10 6.30269 10.0727C6.42814 10.1366 6.53012 10.2385 6.59404 10.364C6.66673 10.5066 6.66673 10.6933 6.66673 11.0667V13.0228C6.66673 13.9307 7.40266 14.6667 8.3106 14.6667C8.52713 14.6667 8.7234 14.5391 8.81133 14.3413L11.0519 9.30014C11.1537 9.07081 11.2047 8.95621 11.2852 8.87214C11.3564 8.79781 11.4439 8.74101 11.5407 8.70614C11.6502 8.66668 11.7757 8.66668 12.0265 8.66668H12.5334C13.2801 8.66668 13.6535 8.66668 13.9387 8.52134C14.1896 8.39354 14.3935 8.18954 14.5214 7.93868C14.6667 7.65348 14.6667 7.28008 14.6667 6.53334Z" fill="currentColor"/>
|
||||||
|
<path d="M11.3334 1.33334V8.66668M14.6667 6.53334V3.46668C14.6667 2.71994 14.6667 2.34657 14.5214 2.06136C14.3935 1.81047 14.1896 1.6065 13.9387 1.47867C13.6535 1.33334 13.2801 1.33334 12.5334 1.33334H5.41204C4.43772 1.33334 3.95056 1.33334 3.55708 1.51163C3.2103 1.66877 2.91556 1.92162 2.70752 2.24049C2.47148 2.60227 2.3974 3.08377 2.24925 4.04676L1.90053 6.31342C1.70513 7.58354 1.60742 8.21861 1.7959 8.71274C1.96132 9.14648 2.27246 9.50914 2.67598 9.73861C3.13572 10 3.77826 10 5.06332 10H5.60003C5.9734 10 6.16008 10 6.30269 10.0727C6.42814 10.1366 6.53012 10.2385 6.59404 10.364C6.66673 10.5066 6.66673 10.6933 6.66673 11.0667V13.0228C6.66673 13.9307 7.40266 14.6667 8.3106 14.6667C8.52713 14.6667 8.7234 14.5391 8.81133 14.3413L11.0519 9.30014C11.1537 9.07081 11.2047 8.95621 11.2852 8.87214C11.3564 8.79781 11.4439 8.74101 11.5407 8.70614C11.6502 8.66668 11.7757 8.66668 12.0265 8.66668H12.5334C13.2801 8.66668 13.6535 8.66668 13.9387 8.52134C14.1896 8.39354 14.3935 8.18954 14.5214 7.93868C14.6667 7.65348 14.6667 7.28008 14.6667 6.53334Z" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>`,
|
||||||
|
check: o`<svg width="100%" height="100%" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M20 6L9 17L4 12" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>`,
|
||||||
|
vaadinLogo: o`
|
||||||
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M3 3C2.55 3 2.25 3.3 2.25 3.75V5.625C2.25 7.05 3.45 8.25 4.875 8.25H10.1997C10.7997 8.25 11.25 8.70029 11.25 9.30029V9.75C11.25 10.2 11.55 10.5 12 10.5C12.45 10.5 12.75 10.2 12.75 9.75V9.30029C12.75 8.70029 13.2003 8.25 13.8003 8.25H19.125C20.55 8.25 21.75 7.05 21.75 5.625V3.75C21.75 3.3 21.45 3 21 3C20.55 3 20.25 3.3 20.25 3.75V4.19971C20.25 4.79971 19.7997 5.25 19.1997 5.25H14.25C12.975 5.25 12 6.225 12 7.5C12 6.225 11.025 5.25 9.75 5.25H4.80029C4.20029 5.25 3.75 4.79971 3.75 4.19971V3.75C3.75 3.3 3.45 3 3 3ZM7.76367 11.2705C7.62187 11.2834 7.48184 11.3244 7.35059 11.3994C6.82559 11.6994 6.59941 12.3744 6.89941 12.8994L11.0244 20.3994C11.1744 20.7744 11.625 21 12 21C12.375 21 12.8256 20.7744 12.9756 20.3994L17.1006 12.8994C17.4006 12.3744 17.1744 11.6994 16.6494 11.3994C16.1244 11.0994 15.4494 11.3256 15.1494 11.8506L12 17.5503L8.85059 11.8506C8.62559 11.4568 8.18906 11.2318 7.76367 11.2705Z" fill="currentColor"/>
|
||||||
|
</svg>
|
||||||
|
`,
|
||||||
|
cancel: o`
|
||||||
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M12 22C17.5228 22 22 17.5228 22 12C22 6.47715 17.5228 2 12 2C6.47715 2 2 6.47715 2 12C2 17.5228 6.47715 22 12 22Z" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<path d="M8 9.6C8 9.03995 8 8.75992 8.10899 8.54601C8.20487 8.35785 8.35785 8.20487 8.54601 8.10899C8.75992 8 9.03995 8 9.6 8H14.4C14.9601 8 15.2401 8 15.454 8.10899C15.6422 8.20487 15.7951 8.35785 15.891 8.54601C16 8.75992 16 9.03995 16 9.6V14.4C16 14.9601 16 15.2401 15.891 15.454C15.7951 15.6422 15.6422 15.7951 15.454 15.891C15.2401 16 14.9601 16 14.4 16H9.6C9.03995 16 8.75992 16 8.54601 15.891C8.35785 15.7951 8.20487 15.6422 8.10899 15.454C8 15.2401 8 14.9601 8 14.4V9.6Z" fill="currentColor" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>
|
||||||
|
`,
|
||||||
|
x: o`
|
||||||
|
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M11.3333 4.66666L4.66667 11.3333M4.66667 4.66666L11.3333 11.3333" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>
|
||||||
|
`,
|
||||||
|
rotatingSpinner: o`
|
||||||
|
<svg width="24" height="24" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M12,1A11,11,0,1,0,23,12,11,11,0,0,0,12,1Zm0,19a8,8,0,1,1,8-8A8,8,0,0,1,12,20Z" opacity=".25" fill="currentColor"/>
|
||||||
|
<path fill="currentColor" d="M10.14,1.16a11,11,0,0,0-9,8.92A1.59,1.59,0,0,0,2.46,12,1.52,1.52,0,0,0,4.11,10.7a8,8,0,0,1,6.66-6.61A1.42,1.42,0,0,0,12,2.69h0A1.57,1.57,0,0,0,10.14,1.16Z">
|
||||||
|
<animateTransform attributeName="transform" type="rotate" dur="0.75s" values="0 12 12;360 12 12" repeatCount="indefinite"/>
|
||||||
|
</path>
|
||||||
|
</svg>
|
||||||
|
`,
|
||||||
|
dockLeft: o`
|
||||||
|
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M6 2V14M5.2 2H10.8C11.9201 2 12.4801 2 12.908 2.21799C13.2843 2.40973 13.5903 2.71569 13.782 3.09202C14 3.51984 14 4.07989 14 5.2V10.8C14 11.9201 14 12.4801 13.782 12.908C13.5903 13.2843 13.2843 13.5903 12.908 13.782C12.4801 14 11.9201 14 10.8 14H5.2C4.07989 14 3.51984 14 3.09202 13.782C2.71569 13.5903 2.40973 13.2843 2.21799 12.908C2 12.4801 2 11.9201 2 10.8V5.2C2 4.07989 2 3.51984 2.21799 3.09202C2.40973 2.71569 2.71569 2.40973 3.09202 2.21799C3.51984 2 4.07989 2 5.2 2Z" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>
|
||||||
|
`,
|
||||||
|
dockBottom: o`
|
||||||
|
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M3 15H21M7.8 3H16.2C17.8802 3 18.7202 3 19.362 3.32698C19.9265 3.6146 20.3854 4.07354 20.673 4.63803C21 5.27976 21 6.11984 21 7.8V16.2C21 17.8802 21 18.7202 20.673 19.362C20.3854 19.9265 19.9265 20.3854 19.362 20.673C18.7202 21 17.8802 21 16.2 21H7.8C6.11984 21 5.27976 21 4.63803 20.673C4.07354 20.3854 3.6146 19.9265 3.32698 19.362C3 18.7202 3 17.8802 3 16.2V7.8C3 6.11984 3 5.27976 3.32698 4.63803C3.6146 4.07354 4.07354 3.6146 4.63803 3.32698C5.27976 3 6.11984 3 7.8 3Z" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>
|
||||||
|
`,
|
||||||
|
dockRight: o`
|
||||||
|
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M10 2V14M5.2 2H10.8C11.9201 2 12.4801 2 12.908 2.21799C13.2843 2.40973 13.5903 2.71569 13.782 3.09202C14 3.51984 14 4.07989 14 5.2V10.8C14 11.9201 14 12.4801 13.782 12.908C13.5903 13.2843 13.2843 13.5903 12.908 13.782C12.4801 14 11.9201 14 10.8 14H5.2C4.07989 14 3.51984 14 3.09202 13.782C2.71569 13.5903 2.40973 13.2843 2.21799 12.908C2 12.4801 2 11.9201 2 10.8V5.2C2 4.07989 2 3.51984 2.21799 3.09202C2.40973 2.71569 2.71569 2.40973 3.09202 2.21799C3.51984 2 4.07989 2 5.2 2Z" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>
|
||||||
|
|
||||||
|
`,
|
||||||
|
tabOrder: o`<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M14 14V2M2 8H11.3333M11.3333 8L6.66667 3.33333M11.3333 8L6.66667 12.6667" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>`,
|
||||||
|
terminal: o`<svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M4 17L10 11L4 5M12 19H20" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>`,
|
||||||
|
undo: o`<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M2 6.00001H11C12.6569 6.00001 14 7.34314 14 9.00001C14 10.6569 12.6569 12 11 12H8M2 6.00001L4.66667 3.33334M2 6.00001L4.66667 8.66668" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>`,
|
||||||
|
redo: o`<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M14 6.00001H5C3.34315 6.00001 2 7.34314 2 9.00001C2 10.6569 3.34315 12 5 12H8M14 6.00001L11.3333 3.33334M14 6.00001L11.3333 8.66668" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>`,
|
||||||
|
userUp: o`<svg width="100%" height="100%" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M16 18L19 15M19 15L22 18M19 15V21M12 15.5H7.5C6.10444 15.5 5.40665 15.5 4.83886 15.6722C3.56045 16.06 2.56004 17.0605 2.17224 18.3389C2 18.9067 2 19.6044 2 21M14.5 7.5C14.5 9.98528 12.4853 12 10 12C7.51472 12 5.5 9.98528 5.5 7.5C5.5 5.01472 7.51472 3 10 3C12.4853 3 14.5 5.01472 14.5 7.5Z" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>`,
|
||||||
|
userLeft: o`<svg width="100%" height="100%" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M19 21L16 18M16 18L19 15M16 18H22M12 15.5H7.5C6.10444 15.5 5.40665 15.5 4.83886 15.6722C3.56045 16.06 2.56004 17.0605 2.17224 18.3389C2 18.9067 2 19.6044 2 21M14.5 7.5C14.5 9.98528 12.4853 12 10 12C7.51472 12 5.5 9.98528 5.5 7.5C5.5 5.01472 7.51472 3 10 3C12.4853 3 14.5 5.01472 14.5 7.5Z" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>`,
|
||||||
|
userRight: o`<svg width="100%" height="100%" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M19 21L22 18M22 18L19 15M22 18H16M12 15.5H7.5C6.10444 15.5 5.40665 15.5 4.83886 15.6722C3.56045 16.06 2.56004 17.0605 2.17224 18.3389C2 18.9067 2 19.6044 2 21M14.5 7.5C14.5 9.98528 12.4853 12 10 12C7.51472 12 5.5 9.98528 5.5 7.5C5.5 5.01472 7.51472 3 10 3C12.4853 3 14.5 5.01472 14.5 7.5Z" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>`,
|
||||||
|
padding: o`
|
||||||
|
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M12 2H4M12 14H4" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<rect x="5.5" y="5.5" width="5" height="5" rx="1.5" stroke="currentColor"/>
|
||||||
|
<path d="M14 12V4M2 12V4" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>`,
|
||||||
|
paddingTop: o`
|
||||||
|
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M12 2H4" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<rect x="5.5" y="5.5" width="5" height="5" rx="1.5" stroke="currentColor"/>
|
||||||
|
</svg>
|
||||||
|
`,
|
||||||
|
paddingRight: o`
|
||||||
|
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<rect x="5.5" y="5.5" width="5" height="5" rx="1.5" stroke="currentColor"/>
|
||||||
|
<path d="M14 12V4" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>
|
||||||
|
`,
|
||||||
|
paddingBottom: o`
|
||||||
|
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M12 14H4" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<rect x="5.5" y="5.5" width="5" height="5" rx="1.5" stroke="currentColor"/>
|
||||||
|
</svg>
|
||||||
|
`,
|
||||||
|
paddingLeft: o`
|
||||||
|
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<rect x="5.5" y="5.5" width="5" height="5" rx="1.5" stroke="currentColor"/>
|
||||||
|
<path d="M2 12V4" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>
|
||||||
|
`,
|
||||||
|
paddingVertical: o`
|
||||||
|
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M12 2H4M12 14H4" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<rect x="5.5" y="5.5" width="5" height="5" rx="1.5" stroke="currentColor"/>
|
||||||
|
</svg>
|
||||||
|
`,
|
||||||
|
paddingHorizontal: o`
|
||||||
|
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<rect x="5.5" y="5.5" width="5" height="5" rx="1.5" stroke="currentColor"/>
|
||||||
|
<path d="M14 12V4M2 12V4" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>
|
||||||
|
`,
|
||||||
|
maximize: o`
|
||||||
|
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M5.33333 2H5.2C4.07989 2 3.51984 2 3.09202 2.21799C2.71569 2.40973 2.40973 2.71569 2.21799 3.09202C2 3.51984 2 4.07989 2 5.2V5.33333M5.33333 14H5.2C4.07989 14 3.51984 14 3.09202 13.782C2.71569 13.5903 2.40973 13.2843 2.21799 12.908C2 12.4801 2 11.9201 2 10.8V10.6667M14 5.33333V5.2C14 4.07989 14 3.51984 13.782 3.09202C13.5903 2.71569 13.2843 2.40973 12.908 2.21799C12.4801 2 11.9201 2 10.8 2H10.6667M14 10.6667V10.8C14 11.9201 14 12.4801 13.782 12.908C13.5903 13.2843 13.2843 13.5903 12.908 13.782C12.4801 14 11.9201 14 10.8 14H10.6667" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>
|
||||||
|
`,
|
||||||
|
gapHorizontal: o`
|
||||||
|
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M14 14V2M2 14V2M6 5.33333V10.6667C6 11.2879 6 11.5985 6.10149 11.8436C6.23682 12.1703 6.49639 12.4299 6.82307 12.5652C7.06813 12.6667 7.37873 12.6667 8 12.6667C8.62127 12.6667 8.93187 12.6667 9.17693 12.5652C9.5036 12.4299 9.7632 12.1703 9.89853 11.8436C10 11.5985 10 11.2879 10 10.6667V5.33333C10 4.71208 10 4.40145 9.89853 4.15642C9.7632 3.82972 9.5036 3.57015 9.17693 3.43483C8.93187 3.33333 8.62127 3.33333 8 3.33333C7.37873 3.33333 7.06813 3.33333 6.82307 3.43483C6.49639 3.57015 6.23682 3.82972 6.10149 4.15642C6 4.40145 6 4.71208 6 5.33333Z" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>
|
||||||
|
`,
|
||||||
|
gapVertical: o`
|
||||||
|
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M14 2H2M14 14H2M3.33333 8C3.33333 7.37873 3.33333 7.06813 3.43483 6.82307C3.57015 6.49639 3.82972 6.23682 4.15642 6.10149C4.40145 6 4.71208 6 5.33333 6H10.6667C11.2879 6 11.5985 6 11.8436 6.10149C12.1703 6.23682 12.4299 6.49639 12.5652 6.82307C12.6667 7.06813 12.6667 7.37873 12.6667 8C12.6667 8.62127 12.6667 8.93187 12.5652 9.17693C12.4299 9.5036 12.1703 9.7632 11.8436 9.89853C11.5985 10 11.2879 10 10.6667 10H5.33333C4.71208 10 4.40145 10 4.15642 9.89853C3.82972 9.7632 3.57015 9.5036 3.43483 9.17693C3.33333 8.93187 3.33333 8.62127 3.33333 8Z" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>
|
||||||
|
`,
|
||||||
|
select: o`<svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M21 9.5V7.8C21 6.11984 21 5.27976 20.673 4.63803C20.3854 4.07354 19.9265 3.6146 19.362 3.32698C18.7202 3 17.8802 3 16.2 3H7.8C6.11984 3 5.27976 3 4.63803 3.32698C4.07354 3.6146 3.6146 4.07354 3.32698 4.63803C3 5.27976 3 6.11984 3 7.8V16.2C3 17.8802 3 18.7202 3.32698 19.362C3.6146 19.9265 4.07354 20.3854 4.63803 20.673C5.27976 21 6.11984 21 7.8 21H9.5M17.3862 17.7113L15.6879 20.8653C15.4103 21.3808 15.2715 21.6386 15.1023 21.7059C14.9555 21.7643 14.7896 21.7498 14.6551 21.6668C14.5001 21.5712 14.4081 21.2933 14.2241 20.7375L11.5004 12.5113C11.3392 12.0245 11.2586 11.7812 11.3166 11.6191C11.367 11.478 11.478 11.367 11.6191 11.3166C11.7812 11.2586 12.0245 11.3392 12.5113 11.5004L20.7374 14.2241C21.2933 14.4082 21.5712 14.5002 21.6668 14.6551C21.7498 14.7897 21.7642 14.9555 21.7058 15.1024C21.6386 15.2715 21.3808 15.4103 20.8652 15.6879L17.7113 17.3862C17.6328 17.4285 17.5935 17.4497 17.5591 17.4768C17.5286 17.501 17.501 17.5286 17.4768 17.5591C17.4497 17.5935 17.4285 17.6328 17.3862 17.7113Z" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>`,
|
||||||
|
click: o`<svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M9 3.5V2M5.06066 5.06066L4 4M5.06066 13L4 14.0607M13 5.06066L14.0607 4M3.5 9H2M15.8645 16.1896L13.3727 20.817C13.0881 21.3457 12.9457 21.61 12.7745 21.6769C12.6259 21.7349 12.4585 21.7185 12.324 21.6328C12.1689 21.534 12.0806 21.2471 11.9038 20.6733L8.44519 9.44525C8.3008 8.97651 8.2286 8.74213 8.28669 8.58383C8.33729 8.44595 8.44595 8.33729 8.58383 8.2867C8.74213 8.22861 8.9765 8.3008 9.44525 8.44519L20.6732 11.9038C21.247 12.0806 21.5339 12.169 21.6327 12.324C21.7185 12.4586 21.7348 12.6259 21.6768 12.7745C21.61 12.9458 21.3456 13.0881 20.817 13.3728L16.1896 15.8645C16.111 15.9068 16.0717 15.9279 16.0374 15.9551C16.0068 15.9792 15.9792 16.0068 15.9551 16.0374C15.9279 16.0717 15.9068 16.111 15.8645 16.1896Z" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>`,
|
||||||
|
wrap: o`<svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M21 9.25H15M21 4H3M21 14.75H15M21 20H3M4.6 16H9.4C9.96005 16 10.2401 16 10.454 15.891C10.6422 15.7951 10.7951 15.6422 10.891 15.454C11 15.2401 11 14.9601 11 14.4V9.6C11 9.03995 11 8.75992 10.891 8.54601C10.7951 8.35785 10.6422 8.20487 10.454 8.10899C10.2401 8 9.96005 8 9.4 8H4.6C4.03995 8 3.75992 8 3.54601 8.10899C3.35785 8.20487 3.20487 8.35785 3.10899 8.54601C3 8.75992 3 9.03995 3 9.6V14.4C3 14.9601 3 15.2401 3.10899 15.454C3.20487 15.6422 3.35785 15.7951 3.54601 15.891C3.75992 16 4.03995 16 4.6 16Z" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>`,
|
||||||
|
link: o`
|
||||||
|
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M5 12H19M19 12L12 5M19 12L12 19" stroke="currentColor" stroke-width="1" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>
|
||||||
|
`,
|
||||||
|
warningColorful: o`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M12 5L4 19H20L12 5ZM12 17C11.4 17 11 16.6 11 16C11 15.4 11.4 15 12 15C12.6 15 13 15.4 13 16C13 16.6 12.6 17 12 17ZM11 14V10H13V14H11Z" fill="#FFCC00"/>
|
||||||
|
</svg>`,
|
||||||
|
successColorful: o`<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M12 4C7.6 4 4 7.6 4 12C4 16.4 7.6 20 12 20C16.4 20 20 16.4 20 12C20 7.6 16.4 4 12 4ZM11.1 15.7L6.9 11.6L8.3 10.2L11 12.9L16 8L17.4 9.4L11.1 15.7Z" fill="#27AE60"/>
|
||||||
|
</svg>`,
|
||||||
|
heightFill: o`
|
||||||
|
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M6.5 5.5L9 3M9 15L11.5 12.5M9 15L6.5 12.5M9 15V3M9 3L11.5 5.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>
|
||||||
|
`,
|
||||||
|
heightFixed: o`
|
||||||
|
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M12.5 3H5.5M12.5 15H5.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<line x1="9" y1="3.75" x2="9" y2="14.25" stroke="currentColor" stroke-width="1.5"/>
|
||||||
|
</svg>
|
||||||
|
`,
|
||||||
|
heightHug: o`
|
||||||
|
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M5.25 15L9 11.25L12.75 15M5.25 3L9 6.75L12.75 3" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>
|
||||||
|
`,
|
||||||
|
heightMax: o`
|
||||||
|
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M9 13.5V4.5M9 13.5L6.75 12M9 13.5L11.25 12M9 4.5L6.75 6M9 4.5L11.25 6M15.75 2.25H2.25M15.75 15.75H2.25" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>
|
||||||
|
`,
|
||||||
|
heightMin: o`
|
||||||
|
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M2.25 9H15.75M9 1.5V6.375M9 6.375L12 3.375M9 6.375L6 3.375M9 16.5V11.625M9 11.625L12 14.625M9 11.625L6 14.625" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>
|
||||||
|
`,
|
||||||
|
alignBottom: o`
|
||||||
|
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M13.5 15V7.5M9 15V3M4.5 15V10.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>
|
||||||
|
`,
|
||||||
|
horizontalBottom: o`
|
||||||
|
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M4.5 15V7.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<path d="M9 15V3" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<path d="M13.5 15V10.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>
|
||||||
|
`,
|
||||||
|
horizontalCenter: o`
|
||||||
|
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M4.5 12.75V5.25" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<path d="M9 15V3" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<path d="M13.5 11.25V6.75" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>
|
||||||
|
`,
|
||||||
|
horizontalTop: o`
|
||||||
|
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M4.5 10.5V3" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<path d="M9 15V3" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<path d="M13.5 7.5V3" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>
|
||||||
|
`,
|
||||||
|
verticalCenter: o`
|
||||||
|
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M12.75 4.5L5.25 4.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<path d="M3 9L15 9" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<path d="M6.75 13.5H11.25" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>
|
||||||
|
`,
|
||||||
|
verticalEnd: o`
|
||||||
|
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M15 4.5L7.5 4.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<path d="M3 9L15 9" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<path d="M10.5 13.5H15" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>
|
||||||
|
`,
|
||||||
|
verticalStart: o`
|
||||||
|
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M10.5 4.5L3 4.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<path d="M3 9L15 9" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<path d="M3 13.5H7.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>
|
||||||
|
`,
|
||||||
|
switchOn: o`
|
||||||
|
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M1.5 9C1.5 6.51472 3.51472 4.5 6 4.5H12C14.4853 4.5 16.5 6.51472 16.5 9C16.5 11.4853 14.4853 13.5 12 13.5H6C3.51472 13.5 1.5 11.4853 1.5 9Z" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<path d="M12 11.5C13.3807 11.5 14.5 10.3807 14.5 9C14.5 7.6193 13.3807 6.5 12 6.5C10.6193 6.5 9.5 7.6193 9.5 9C9.5 10.3807 10.6193 11.5 12 11.5Z" fill="currentColor"/>
|
||||||
|
</svg>
|
||||||
|
`,
|
||||||
|
switchOff: o`
|
||||||
|
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M1.5 9C1.5 6.51472 3.51472 4.5 6 4.5H12C14.4853 4.5 16.5 6.51472 16.5 9C16.5 11.4853 14.4853 13.5 12 13.5H6C3.51472 13.5 1.5 11.4853 1.5 9Z" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
<path d="M6 11.5C7.38071 11.5 8.5 10.3807 8.5 9C8.5 7.6193 7.38071 6.5 6 6.5C4.61929 6.5 3.5 7.6193 3.5 9C3.5 10.3807 4.61929 11.5 6 11.5Z" fill="currentColor"/>
|
||||||
|
</svg>
|
||||||
|
`,
|
||||||
|
databaseUpload: o`<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M9 6.76875C10.1125 6.76875 11.2312 6.60312 12.3562 6.27187C13.4812 5.94062 14.1125 5.60625 14.25 5.26875C14.1125 4.90625 13.4844 4.5625 12.3656 4.2375C11.2469 3.9125 10.125 3.75 9 3.75C7.8625 3.75 6.74687 3.90937 5.65312 4.22812C4.55937 4.54687 3.925 4.89375 3.75 5.26875C3.925 5.60625 4.55937 5.94062 5.65312 6.27187C6.74687 6.60312 7.8625 6.76875 9 6.76875ZM13.125 15.75H13.875V12.675L15.225 14.025L15.75 13.5L13.5 11.25L11.25 13.5L11.775 14.025L13.125 12.675V15.75ZM13.5 17.25C12.4625 17.25 11.5781 16.8844 10.8469 16.1531C10.1156 15.4219 9.75 14.5375 9.75 13.5C9.75 12.4625 10.1156 11.5781 10.8469 10.8469C11.5781 10.1156 12.4625 9.75 13.5 9.75C14.5375 9.75 15.4219 10.1156 16.1531 10.8469C16.8844 11.5781 17.25 12.4625 17.25 13.5C17.25 14.5375 16.8844 15.4219 16.1531 16.1531C15.4219 16.8844 14.5375 17.25 13.5 17.25ZM8.30625 14.2312C8.34375 14.5062 8.4 14.7687 8.475 15.0187C8.55 15.2687 8.64375 15.5125 8.75625 15.75C7.84375 15.7375 6.99375 15.65 6.20625 15.4875C5.41875 15.325 4.73125 15.1094 4.14375 14.8406C3.55625 14.5719 3.09375 14.2594 2.75625 13.9031C2.41875 13.5469 2.25 13.1625 2.25 12.75V5.25C2.25 4.425 2.90937 3.71875 4.22812 3.13125C5.54687 2.54375 7.1375 2.25 9 2.25C10.8625 2.25 12.4531 2.54375 13.7719 3.13125C15.0906 3.71875 15.75 4.425 15.75 5.25V8.75625C15.5125 8.64375 15.2687 8.55 15.0187 8.475C14.7687 8.4 14.5125 8.34375 14.25 8.30625V7.14375C13.6 7.50625 12.825 7.78125 11.925 7.96875C11.025 8.15625 10.05 8.25 9 8.25C7.9375 8.25 6.95625 8.15625 6.05625 7.96875C5.15625 7.78125 4.3875 7.50625 3.75 7.14375V9.0375C4.3875 9.625 5.20312 10.0156 6.19687 10.2094C7.19062 10.4031 8.125 10.5 9 10.5H9.20625C9.04375 10.725 8.90312 10.9625 8.78437 11.2125C8.66562 11.4625 8.5625 11.725 8.475 12C7.525 11.95 6.64375 11.8344 5.83125 11.6531C5.01875 11.4719 4.325 11.2187 3.75 10.8937V12.75C3.8375 12.9125 4.025 13.0781 4.3125 13.2469C4.6 13.4156 4.95 13.5656 5.3625 13.6969C5.775 13.8281 6.23437 13.9406 6.74062 14.0344C7.24687 14.1281 7.76875 14.1937 8.30625 14.2312Z" fill="currentColor"/>
|
||||||
|
</svg>`
|
||||||
|
};
|
||||||
|
export {
|
||||||
|
r as i
|
||||||
|
};
|
@ -0,0 +1,48 @@
|
|||||||
|
import { P as c } from "./copilot-xjoIJFQc.js";
|
||||||
|
/**
|
||||||
|
* @license
|
||||||
|
* Copyright 2017 Google LLC
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
const d = (e, a, n) => (n.configurable = !0, n.enumerable = !0, Reflect.decorate && typeof a != "object" && Object.defineProperty(e, a, n), n);
|
||||||
|
/**
|
||||||
|
* @license
|
||||||
|
* Copyright 2017 Google LLC
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
function v(e, a) {
|
||||||
|
return (n, o, b) => {
|
||||||
|
const i = (l) => l.renderRoot?.querySelector(e) ?? null;
|
||||||
|
return d(n, o, { get() {
|
||||||
|
return i(this);
|
||||||
|
} });
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function u(e) {
|
||||||
|
e.querySelectorAll(
|
||||||
|
"vaadin-context-menu, vaadin-menu-bar, vaadin-menu-bar-submenu, vaadin-select, vaadin-combo-box, vaadin-tooltip, vaadin-dialog, vaadin-multi-select-combo-box"
|
||||||
|
).forEach((a) => {
|
||||||
|
a?.$?.comboBox && (a = a.$.comboBox);
|
||||||
|
let n = a.shadowRoot?.querySelector(
|
||||||
|
`${a.localName}-overlay, ${a.localName}-submenu, vaadin-menu-bar-overlay`
|
||||||
|
);
|
||||||
|
n?.localName === "vaadin-menu-bar-submenu" && (n = n.shadowRoot.querySelector("vaadin-menu-bar-overlay")), n ? n._attachOverlay = t.bind(n) : a.$?.overlay && (a.$.overlay._attachOverlay = t.bind(a.$.overlay));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
function r() {
|
||||||
|
return document.querySelector(`${c}main`).shadowRoot;
|
||||||
|
}
|
||||||
|
const m = () => Array.from(r().children).filter((a) => a._hasOverlayStackMixin && !a.hasAttribute("closing")).sort((a, n) => a.__zIndex - n.__zIndex || 0), s = (e) => e === m().pop();
|
||||||
|
function t() {
|
||||||
|
const e = this;
|
||||||
|
e._placeholder = document.createComment("vaadin-overlay-placeholder"), e.parentNode.insertBefore(e._placeholder, e), r().appendChild(e), e.hasOwnProperty("_last") || Object.defineProperty(e, "_last", {
|
||||||
|
// Only returns odd die sides
|
||||||
|
get() {
|
||||||
|
return s(this);
|
||||||
|
}
|
||||||
|
}), e.bringToFront(), requestAnimationFrame(() => u(e));
|
||||||
|
}
|
||||||
|
export {
|
||||||
|
v as e,
|
||||||
|
u as m
|
||||||
|
};
|
@ -0,0 +1,45 @@
|
|||||||
|
import { a7 as p, a8 as u } from "./copilot-xjoIJFQc.js";
|
||||||
|
/**
|
||||||
|
* @license
|
||||||
|
* Copyright 2017 Google LLC
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
const l = { attribute: !0, type: String, converter: p, reflect: !1, hasChanged: u }, d = (t = l, o, e) => {
|
||||||
|
const { kind: a, metadata: s } = e;
|
||||||
|
let n = globalThis.litPropertyMetadata.get(s);
|
||||||
|
if (n === void 0 && globalThis.litPropertyMetadata.set(s, n = /* @__PURE__ */ new Map()), n.set(e.name, t), a === "accessor") {
|
||||||
|
const { name: r } = e;
|
||||||
|
return { set(i) {
|
||||||
|
const c = o.get.call(this);
|
||||||
|
o.set.call(this, i), this.requestUpdate(r, c, t);
|
||||||
|
}, init(i) {
|
||||||
|
return i !== void 0 && this.P(r, void 0, t), i;
|
||||||
|
} };
|
||||||
|
}
|
||||||
|
if (a === "setter") {
|
||||||
|
const { name: r } = e;
|
||||||
|
return function(i) {
|
||||||
|
const c = this[r];
|
||||||
|
o.call(this, i), this.requestUpdate(r, c, t);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
throw Error("Unsupported decorator location: " + a);
|
||||||
|
};
|
||||||
|
function h(t) {
|
||||||
|
return (o, e) => typeof e == "object" ? d(t, o, e) : ((a, s, n) => {
|
||||||
|
const r = s.hasOwnProperty(n);
|
||||||
|
return s.constructor.createProperty(n, r ? { ...a, wrapped: !0 } : a), r ? Object.getOwnPropertyDescriptor(s, n) : void 0;
|
||||||
|
})(t, o, e);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @license
|
||||||
|
* Copyright 2017 Google LLC
|
||||||
|
* SPDX-License-Identifier: BSD-3-Clause
|
||||||
|
*/
|
||||||
|
function g(t) {
|
||||||
|
return h({ ...t, state: !0, attribute: !1 });
|
||||||
|
}
|
||||||
|
export {
|
||||||
|
h as n,
|
||||||
|
g as r
|
||||||
|
};
|
179
src/main/frontend/generated/jar-resources/datepickerConnector.js
Normal file
179
src/main/frontend/generated/jar-resources/datepickerConnector.js
Normal file
@ -0,0 +1,179 @@
|
|||||||
|
import dateFnsFormat from 'date-fns/format';
|
||||||
|
import dateFnsParse from 'date-fns/parse';
|
||||||
|
import dateFnsIsValid from 'date-fns/isValid';
|
||||||
|
import { extractDateParts, parseDate as _parseDate } from '@vaadin/date-picker/src/vaadin-date-picker-helper.js';
|
||||||
|
|
||||||
|
window.Vaadin.Flow.datepickerConnector = {};
|
||||||
|
window.Vaadin.Flow.datepickerConnector.initLazy = (datepicker) => {
|
||||||
|
// Check whether the connector was already initialized for the datepicker
|
||||||
|
if (datepicker.$connector) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
datepicker.$connector = {};
|
||||||
|
|
||||||
|
const createLocaleBasedDateFormat = function (locale) {
|
||||||
|
try {
|
||||||
|
// Check whether the locale is supported or not
|
||||||
|
new Date().toLocaleDateString(locale);
|
||||||
|
} catch (e) {
|
||||||
|
console.warn('The locale is not supported, using default format setting (ISO 8601).');
|
||||||
|
return 'yyyy-MM-dd';
|
||||||
|
}
|
||||||
|
|
||||||
|
// format test date and convert to date-fns pattern
|
||||||
|
const testDate = new Date(Date.UTC(1234, 4, 6));
|
||||||
|
let pattern = testDate.toLocaleDateString(locale, { timeZone: 'UTC' });
|
||||||
|
pattern = pattern
|
||||||
|
// escape date-fns pattern letters by enclosing them in single quotes
|
||||||
|
.replace(/([a-zA-Z]+)/g, "'$1'")
|
||||||
|
// insert date placeholder
|
||||||
|
.replace('06', 'dd')
|
||||||
|
.replace('6', 'd')
|
||||||
|
// insert month placeholder
|
||||||
|
.replace('05', 'MM')
|
||||||
|
.replace('5', 'M')
|
||||||
|
// insert year placeholder
|
||||||
|
.replace('1234', 'yyyy');
|
||||||
|
const isValidPattern = pattern.includes('d') && pattern.includes('M') && pattern.includes('y');
|
||||||
|
if (!isValidPattern) {
|
||||||
|
console.warn('The locale is not supported, using default format setting (ISO 8601).');
|
||||||
|
return 'yyyy-MM-dd';
|
||||||
|
}
|
||||||
|
|
||||||
|
return pattern;
|
||||||
|
};
|
||||||
|
|
||||||
|
function createFormatterAndParser(formats) {
|
||||||
|
if (!formats || formats.length === 0) {
|
||||||
|
throw new Error('Array of custom date formats is null or empty');
|
||||||
|
}
|
||||||
|
|
||||||
|
function getShortYearFormat(format) {
|
||||||
|
if (format.includes('yyyy') && !format.includes('yyyyy')) {
|
||||||
|
return format.replace('yyyy', 'yy');
|
||||||
|
}
|
||||||
|
if (format.includes('YYYY') && !format.includes('YYYYY')) {
|
||||||
|
return format.replace('YYYY', 'YY');
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isFormatWithYear(format) {
|
||||||
|
return format.includes('y') || format.includes('Y');
|
||||||
|
}
|
||||||
|
|
||||||
|
function isShortYearFormat(format) {
|
||||||
|
// Format is long if it includes a four-digit year.
|
||||||
|
return !format.includes('yyyy') && !format.includes('YYYY');
|
||||||
|
}
|
||||||
|
|
||||||
|
function getExtendedFormats(formats) {
|
||||||
|
return formats.reduce((acc, format) => {
|
||||||
|
// We first try to match the date with the shorter version,
|
||||||
|
// as short years are supported with the long date format.
|
||||||
|
if (isFormatWithYear(format) && !isShortYearFormat(format)) {
|
||||||
|
acc.push(getShortYearFormat(format));
|
||||||
|
}
|
||||||
|
acc.push(format);
|
||||||
|
return acc;
|
||||||
|
}, []);
|
||||||
|
}
|
||||||
|
|
||||||
|
function correctFullYear(date) {
|
||||||
|
// The last parsed date check handles the case where a four-digit year is parsed, then formatted
|
||||||
|
// as a two-digit year, and then parsed again. In this case we want to keep the century of the
|
||||||
|
// originally parsed year, instead of using the century of the reference date.
|
||||||
|
|
||||||
|
// Do not apply any correction if the previous parse attempt was failed.
|
||||||
|
if (datepicker.$connector._lastParseStatus === 'error') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update century if the last parsed date is the same except the century.
|
||||||
|
if (datepicker.$connector._lastParseStatus === 'successful') {
|
||||||
|
if (
|
||||||
|
datepicker.$connector._lastParsedDate.day === date.getDate() &&
|
||||||
|
datepicker.$connector._lastParsedDate.month === date.getMonth() &&
|
||||||
|
datepicker.$connector._lastParsedDate.year % 100 === date.getFullYear() % 100
|
||||||
|
) {
|
||||||
|
date.setFullYear(datepicker.$connector._lastParsedDate.year);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update century if this is the first parse after overlay open.
|
||||||
|
const currentValue = _parseDate(datepicker.value);
|
||||||
|
if (
|
||||||
|
dateFnsIsValid(currentValue) &&
|
||||||
|
currentValue.getDate() === date.getDate() &&
|
||||||
|
currentValue.getMonth() === date.getMonth() &&
|
||||||
|
currentValue.getFullYear() % 100 === date.getFullYear() % 100
|
||||||
|
) {
|
||||||
|
date.setFullYear(currentValue.getFullYear());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function formatDate(dateParts) {
|
||||||
|
const format = formats[0];
|
||||||
|
const date = _parseDate(`${dateParts.year}-${dateParts.month + 1}-${dateParts.day}`);
|
||||||
|
|
||||||
|
return dateFnsFormat(date, format);
|
||||||
|
}
|
||||||
|
|
||||||
|
function doParseDate(dateString, format, referenceDate) {
|
||||||
|
// When format does not contain a year, then current year should be used.
|
||||||
|
const refDate = isFormatWithYear(format) ? referenceDate : new Date();
|
||||||
|
const date = dateFnsParse(dateString, format, refDate);
|
||||||
|
if (dateFnsIsValid(date)) {
|
||||||
|
if (isFormatWithYear(format) && isShortYearFormat(format)) {
|
||||||
|
correctFullYear(date);
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
day: date.getDate(),
|
||||||
|
month: date.getMonth(),
|
||||||
|
year: date.getFullYear()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseDate(dateString) {
|
||||||
|
const referenceDate = _getReferenceDate();
|
||||||
|
for (let format of getExtendedFormats(formats)) {
|
||||||
|
const parsedDate = doParseDate(dateString, format, referenceDate);
|
||||||
|
if (parsedDate) {
|
||||||
|
datepicker.$connector._lastParseStatus = 'successful';
|
||||||
|
datepicker.$connector._lastParsedDate = parsedDate;
|
||||||
|
return parsedDate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
datepicker.$connector._lastParseStatus = 'error';
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
formatDate: formatDate,
|
||||||
|
parseDate: parseDate
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function _getReferenceDate() {
|
||||||
|
const { referenceDate } = datepicker.i18n;
|
||||||
|
return referenceDate ? new Date(referenceDate.year, referenceDate.month, referenceDate.day) : new Date();
|
||||||
|
}
|
||||||
|
|
||||||
|
datepicker.$connector.updateI18n = (locale, i18n) => {
|
||||||
|
// Either use custom formats specified in I18N, or create format from locale
|
||||||
|
const hasCustomFormats = i18n && i18n.dateFormats && i18n.dateFormats.length > 0;
|
||||||
|
if (i18n && i18n.referenceDate) {
|
||||||
|
i18n.referenceDate = extractDateParts(new Date(i18n.referenceDate));
|
||||||
|
}
|
||||||
|
const usedFormats = hasCustomFormats ? i18n.dateFormats : [createLocaleBasedDateFormat(locale)];
|
||||||
|
const formatterAndParser = createFormatterAndParser(usedFormats);
|
||||||
|
|
||||||
|
// Merge current web component I18N settings with new I18N settings and the formatting and parsing functions
|
||||||
|
datepicker.i18n = Object.assign({}, datepicker.i18n, i18n, formatterAndParser);
|
||||||
|
};
|
||||||
|
|
||||||
|
datepicker.addEventListener('opened-changed', () => (datepicker.$connector._lastParseStatus = undefined));
|
||||||
|
}
|
@ -0,0 +1,14 @@
|
|||||||
|
function disableOnClickListener({currentTarget: element}) {
|
||||||
|
if (element.disableOnClick) {
|
||||||
|
requestAnimationFrame(() => element.disabled = true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
window.Vaadin.Flow.disableOnClick = {
|
||||||
|
initDisableOnClick: (element) => {
|
||||||
|
if (!element.__hasDisableOnClickListener) {
|
||||||
|
element.addEventListener('click', disableOnClickListener);
|
||||||
|
element.__hasDisableOnClickListener = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
130
src/main/frontend/generated/jar-resources/dndConnector.js
Normal file
130
src/main/frontend/generated/jar-resources/dndConnector.js
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
window.Vaadin = window.Vaadin || {};
|
||||||
|
window.Vaadin.Flow = window.Vaadin.Flow || {};
|
||||||
|
window.Vaadin.Flow.dndConnector = {
|
||||||
|
__ondragenterListener: function (event) {
|
||||||
|
// TODO filter by data type
|
||||||
|
// TODO prevent dropping on itself (by default)
|
||||||
|
const effect = event.currentTarget['__dropEffect'];
|
||||||
|
if (!event.currentTarget.hasAttribute('disabled')) {
|
||||||
|
if (effect) {
|
||||||
|
event.dataTransfer.dropEffect = effect;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (effect !== 'none') {
|
||||||
|
/* #7108: if drag moves on top of drop target's children, first another ondragenter event
|
||||||
|
* is fired and then a ondragleave event. This happens again once the drag
|
||||||
|
* moves on top of another children, or back on top of the drop target element.
|
||||||
|
* Thus need to "cancel" the following ondragleave, to not remove class name.
|
||||||
|
* Drop event will happen even when dropped to a child element. */
|
||||||
|
if (event.currentTarget.classList.contains('v-drag-over-target')) {
|
||||||
|
event.currentTarget['__skip-leave'] = true;
|
||||||
|
} else {
|
||||||
|
event.currentTarget.classList.add('v-drag-over-target');
|
||||||
|
}
|
||||||
|
// enables browser specific pseudo classes (at least FF)
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation(); // don't let parents know
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
__ondragoverListener: function (event) {
|
||||||
|
// TODO filter by data type
|
||||||
|
// TODO filter by effectAllowed != dropEffect due to Safari & IE11 ?
|
||||||
|
if (!event.currentTarget.hasAttribute('disabled')) {
|
||||||
|
const effect = event.currentTarget['__dropEffect'];
|
||||||
|
if (effect) {
|
||||||
|
event.dataTransfer.dropEffect = effect;
|
||||||
|
}
|
||||||
|
// allows the drop && don't let parents know
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
__ondragleaveListener: function (event) {
|
||||||
|
if (event.currentTarget['__skip-leave']) {
|
||||||
|
event.currentTarget['__skip-leave'] = false;
|
||||||
|
} else {
|
||||||
|
event.currentTarget.classList.remove('v-drag-over-target');
|
||||||
|
}
|
||||||
|
// #7109 need to stop or any parent drop target might not get highlighted,
|
||||||
|
// as ondragenter for it is fired before the child gets dragleave.
|
||||||
|
event.stopPropagation();
|
||||||
|
},
|
||||||
|
|
||||||
|
__ondropListener: function (event) {
|
||||||
|
const effect = event.currentTarget['__dropEffect'];
|
||||||
|
if (effect) {
|
||||||
|
event.dataTransfer.dropEffect = effect;
|
||||||
|
}
|
||||||
|
event.currentTarget.classList.remove('v-drag-over-target');
|
||||||
|
// prevent browser handling && don't let parents know
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
},
|
||||||
|
|
||||||
|
updateDropTarget: function (element) {
|
||||||
|
if (element['__active']) {
|
||||||
|
element.addEventListener('dragenter', this.__ondragenterListener, false);
|
||||||
|
element.addEventListener('dragover', this.__ondragoverListener, false);
|
||||||
|
element.addEventListener('dragleave', this.__ondragleaveListener, true);
|
||||||
|
element.addEventListener('drop', this.__ondropListener, false);
|
||||||
|
} else {
|
||||||
|
element.removeEventListener('dragenter', this.__ondragenterListener, false);
|
||||||
|
element.removeEventListener('dragover', this.__ondragoverListener, false);
|
||||||
|
element.removeEventListener('dragleave', this.__ondragleaveListener, false);
|
||||||
|
element.removeEventListener('drop', this.__ondropListener, false);
|
||||||
|
element.classList.remove('v-drag-over-target');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/** DRAG SOURCE METHODS: */
|
||||||
|
|
||||||
|
__dragstartListener: function (event) {
|
||||||
|
event.stopPropagation();
|
||||||
|
event.dataTransfer.setData('text/plain', '');
|
||||||
|
if (event.currentTarget.hasAttribute('disabled')) {
|
||||||
|
event.preventDefault();
|
||||||
|
} else {
|
||||||
|
if (event.currentTarget['__effectAllowed']) {
|
||||||
|
event.dataTransfer.effectAllowed = event.currentTarget['__effectAllowed'];
|
||||||
|
}
|
||||||
|
event.currentTarget.classList.add('v-dragged');
|
||||||
|
}
|
||||||
|
if(event.currentTarget.__dragImage) {
|
||||||
|
if(event.currentTarget.__dragImage.style.display === "none") {
|
||||||
|
event.currentTarget.__dragImage.style.display = "block";
|
||||||
|
event.currentTarget.classList.add('shown');
|
||||||
|
}
|
||||||
|
event.dataTransfer.setDragImage(
|
||||||
|
event.currentTarget.__dragImage,
|
||||||
|
event.currentTarget.__dragImageOffsetX,
|
||||||
|
event.currentTarget.__dragImageOffsetY);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
__dragendListener: function (event) {
|
||||||
|
event.currentTarget.classList.remove('v-dragged');
|
||||||
|
if(event.currentTarget.classList.contains('shown')) {
|
||||||
|
event.currentTarget.classList.remove('shown');
|
||||||
|
event.currentTarget.__dragImage.style.display = "none";
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
updateDragSource: function (element) {
|
||||||
|
if (element['draggable']) {
|
||||||
|
element.addEventListener('dragstart', this.__dragstartListener, false);
|
||||||
|
element.addEventListener('dragend', this.__dragendListener, false);
|
||||||
|
} else {
|
||||||
|
element.removeEventListener('dragstart', this.__dragstartListener, false);
|
||||||
|
element.removeEventListener('dragend', this.__dragendListener, false);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
setDragImage: function (dragImage, offsetX, offsetY, dragSource) {
|
||||||
|
dragSource.__dragImage = dragImage;
|
||||||
|
dragSource.__dragImageOffsetX = offsetX;
|
||||||
|
dragSource.__dragImageOffsetY = offsetY;
|
||||||
|
}
|
||||||
|
};
|
@ -0,0 +1,68 @@
|
|||||||
|
import { noChange } from 'lit';
|
||||||
|
import { directive, PartType } from 'lit/directive.js';
|
||||||
|
import { AsyncDirective } from 'lit/async-directive.js';
|
||||||
|
|
||||||
|
class FlowComponentDirective extends AsyncDirective {
|
||||||
|
constructor(partInfo) {
|
||||||
|
super(partInfo);
|
||||||
|
if (partInfo.type !== PartType.CHILD) {
|
||||||
|
throw new Error(`${this.constructor.directiveName}() can only be used in child bindings`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
update(part, [appid, nodeid]) {
|
||||||
|
this.updateContent(part, appid, nodeid);
|
||||||
|
return noChange;
|
||||||
|
}
|
||||||
|
|
||||||
|
updateContent(part, appid, nodeid) {
|
||||||
|
const { parentNode, startNode } = part;
|
||||||
|
this.__parentNode = parentNode;
|
||||||
|
|
||||||
|
const hasNewNodeId = nodeid !== undefined && nodeid !== null;
|
||||||
|
const newNode = hasNewNodeId ? this.getNewNode(appid, nodeid) : null;
|
||||||
|
const oldNode = this.getOldNode(part);
|
||||||
|
|
||||||
|
clearTimeout(this.__parentNode.__nodeRetryTimeout);
|
||||||
|
|
||||||
|
if (hasNewNodeId && !newNode) {
|
||||||
|
// If the node is not found, try again later.
|
||||||
|
this.__parentNode.__nodeRetryTimeout = setTimeout(() => this.updateContent(part, appid, nodeid));
|
||||||
|
} else if (oldNode === newNode) {
|
||||||
|
return;
|
||||||
|
} else if (oldNode && newNode) {
|
||||||
|
parentNode.replaceChild(newNode, oldNode);
|
||||||
|
} else if (oldNode) {
|
||||||
|
parentNode.removeChild(oldNode);
|
||||||
|
} else if (newNode) {
|
||||||
|
startNode.after(newNode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getNewNode(appid, nodeid) {
|
||||||
|
return window.Vaadin.Flow.clients[appid].getByNodeId(nodeid);
|
||||||
|
}
|
||||||
|
|
||||||
|
getOldNode(part) {
|
||||||
|
const { startNode, endNode } = part;
|
||||||
|
if (startNode.nextSibling === endNode) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
return startNode.nextSibling;
|
||||||
|
}
|
||||||
|
|
||||||
|
disconnected() {
|
||||||
|
clearTimeout(this.__parentNode.__nodeRetryTimeout);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renders the given flow component node.
|
||||||
|
*
|
||||||
|
* WARNING: This directive is not intended for public use.
|
||||||
|
*
|
||||||
|
* @param {string} appid
|
||||||
|
* @param {number} nodeid
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
export const flowComponentDirective = directive(FlowComponentDirective);
|
@ -0,0 +1,208 @@
|
|||||||
|
import '@polymer/polymer/lib/elements/dom-if.js';
|
||||||
|
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||||
|
import { Debouncer } from '@polymer/polymer/lib/utils/debounce.js';
|
||||||
|
import { idlePeriod } from '@polymer/polymer/lib/utils/async.js';
|
||||||
|
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||||
|
import { flowComponentDirective } from './flow-component-directive.js';
|
||||||
|
import { render, html as litHtml } from 'lit';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the requested node in a form suitable for Lit template interpolation.
|
||||||
|
* @param {string} appid
|
||||||
|
* @param {number} nodeid
|
||||||
|
* @returns {any} a Lit directive
|
||||||
|
*/
|
||||||
|
function getNode(appid, nodeid) {
|
||||||
|
return flowComponentDirective(appid, nodeid);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the nodes defined by the given node ids as the child nodes of the
|
||||||
|
* given root element.
|
||||||
|
* @param {string} appid
|
||||||
|
* @param {number[]} nodeIds
|
||||||
|
* @param {Element} root
|
||||||
|
*/
|
||||||
|
function setChildNodes(appid, nodeIds, root) {
|
||||||
|
render(litHtml`${nodeIds.map(id => flowComponentDirective(appid, id))}`, root);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SimpleElementBindingStrategy::addChildren uses insertBefore to add child
|
||||||
|
* elements to the container. When the children are manually placed under
|
||||||
|
* another element, the call to insertBefore can occasionally fail due to
|
||||||
|
* an invalid reference node.
|
||||||
|
*
|
||||||
|
* This is a temporary workaround which patches the container's native API
|
||||||
|
* to not fail when called with invalid arguments.
|
||||||
|
*/
|
||||||
|
function patchVirtualContainer(container) {
|
||||||
|
const originalInsertBefore = container.insertBefore;
|
||||||
|
|
||||||
|
container.insertBefore = function (newNode, referenceNode) {
|
||||||
|
if (referenceNode && referenceNode.parentNode === this) {
|
||||||
|
return originalInsertBefore.call(this, newNode, referenceNode);
|
||||||
|
} else {
|
||||||
|
return originalInsertBefore.call(this, newNode, null);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
window.Vaadin ||= {};
|
||||||
|
window.Vaadin.FlowComponentHost ||= { patchVirtualContainer, getNode, setChildNodes };
|
||||||
|
|
||||||
|
class FlowComponentRenderer extends PolymerElement {
|
||||||
|
static get template() {
|
||||||
|
return html`
|
||||||
|
<style>
|
||||||
|
:host {
|
||||||
|
animation: 1ms flow-component-renderer-appear;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes flow-component-renderer-appear {
|
||||||
|
to {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<slot></slot>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
static get is() {
|
||||||
|
return 'flow-component-renderer';
|
||||||
|
}
|
||||||
|
static get properties() {
|
||||||
|
return {
|
||||||
|
nodeid: Number,
|
||||||
|
appid: String,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
static get observers() {
|
||||||
|
return ['_attachRenderedComponentIfAble(appid, nodeid)'];
|
||||||
|
}
|
||||||
|
|
||||||
|
ready() {
|
||||||
|
super.ready();
|
||||||
|
this.addEventListener('click', function (event) {
|
||||||
|
if (
|
||||||
|
this.firstChild &&
|
||||||
|
typeof this.firstChild.click === 'function' &&
|
||||||
|
event.target === this
|
||||||
|
) {
|
||||||
|
event.stopPropagation();
|
||||||
|
this.firstChild.click();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.addEventListener('animationend', this._onAnimationEnd);
|
||||||
|
}
|
||||||
|
|
||||||
|
_asyncAttachRenderedComponentIfAble() {
|
||||||
|
this._debouncer = Debouncer.debounce(this._debouncer, idlePeriod, () =>
|
||||||
|
this._attachRenderedComponentIfAble()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
_attachRenderedComponentIfAble() {
|
||||||
|
if (this.appid == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (this.nodeid == null) {
|
||||||
|
if (this.firstChild) {
|
||||||
|
this.removeChild(this.firstChild);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const renderedComponent = this._getRenderedComponent();
|
||||||
|
if (this.firstChild) {
|
||||||
|
if (!renderedComponent) {
|
||||||
|
this._asyncAttachRenderedComponentIfAble();
|
||||||
|
} else if (this.firstChild !== renderedComponent) {
|
||||||
|
this.replaceChild(renderedComponent, this.firstChild);
|
||||||
|
this._defineFocusTarget();
|
||||||
|
this.onComponentRendered();
|
||||||
|
} else {
|
||||||
|
this._defineFocusTarget();
|
||||||
|
this.onComponentRendered();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (renderedComponent) {
|
||||||
|
this.appendChild(renderedComponent);
|
||||||
|
this._defineFocusTarget();
|
||||||
|
this.onComponentRendered();
|
||||||
|
} else {
|
||||||
|
this._asyncAttachRenderedComponentIfAble();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_getRenderedComponent() {
|
||||||
|
try {
|
||||||
|
return window.Vaadin.Flow.clients[this.appid].getByNodeId(this.nodeid);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(
|
||||||
|
'Could not get node %s from app %s',
|
||||||
|
this.nodeid,
|
||||||
|
this.appid
|
||||||
|
);
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
onComponentRendered() {
|
||||||
|
// subclasses can override this method to execute custom logic on resize
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Setting the `focus-target` attribute to the first focusable descendant
|
||||||
|
starting from the firstChild necessary for the focus to be delegated
|
||||||
|
within the flow-component-renderer when used inside a vaadin-grid cell */
|
||||||
|
_defineFocusTarget() {
|
||||||
|
var focusable = this._getFirstFocusableDescendant(this.firstChild);
|
||||||
|
if (focusable !== null) {
|
||||||
|
focusable.setAttribute('focus-target', 'true');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_getFirstFocusableDescendant(node) {
|
||||||
|
if (this._isFocusable(node)) {
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
if (node.hasAttribute && (node.hasAttribute('disabled') || node.hasAttribute('hidden'))) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
if (!node.children) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
for (var i = 0; i < node.children.length; i++) {
|
||||||
|
var focusable = this._getFirstFocusableDescendant(node.children[i]);
|
||||||
|
if (focusable !== null) {
|
||||||
|
return focusable;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
_isFocusable(node) {
|
||||||
|
if (
|
||||||
|
node.hasAttribute &&
|
||||||
|
typeof node.hasAttribute === 'function' &&
|
||||||
|
(node.hasAttribute('disabled') || node.hasAttribute('hidden'))
|
||||||
|
) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return node.tabIndex === 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
_onAnimationEnd(e) {
|
||||||
|
// ShadyCSS applies scoping suffixes to animation names
|
||||||
|
// To ensure that child is attached once element is unhidden
|
||||||
|
// for when it was filtered out from, eg, ComboBox
|
||||||
|
// https://github.com/vaadin/vaadin-flow-components/issues/437
|
||||||
|
if (e.animationName.indexOf('flow-component-renderer-appear') === 0) {
|
||||||
|
this._attachRenderedComponentIfAble();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
window.customElements.define(FlowComponentRenderer.is, FlowComponentRenderer);
|
1204
src/main/frontend/generated/jar-resources/gridConnector.ts
Normal file
1204
src/main/frontend/generated/jar-resources/gridConnector.ts
Normal file
File diff suppressed because it is too large
Load Diff
1
src/main/frontend/generated/jar-resources/index.d.ts
vendored
Normal file
1
src/main/frontend/generated/jar-resources/index.d.ts
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
export * from './Flow';
|
2
src/main/frontend/generated/jar-resources/index.js
Normal file
2
src/main/frontend/generated/jar-resources/index.js
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
export * from './Flow';
|
||||||
|
//# sourceMappingURL=index.js.map
|
1
src/main/frontend/generated/jar-resources/index.js.map
Normal file
1
src/main/frontend/generated/jar-resources/index.js.map
Normal file
@ -0,0 +1 @@
|
|||||||
|
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/main/frontend/index.ts"],"names":[],"mappings":"AAAA,cAAc,QAAQ,CAAC","sourcesContent":["export * from './Flow';\n"]}
|
112
src/main/frontend/generated/jar-resources/lit-renderer.ts
Normal file
112
src/main/frontend/generated/jar-resources/lit-renderer.ts
Normal file
@ -0,0 +1,112 @@
|
|||||||
|
/* eslint-disable no-restricted-syntax */
|
||||||
|
/* eslint-disable max-params */
|
||||||
|
import { html, render } from 'lit';
|
||||||
|
import { live } from 'lit/directives/live.js';
|
||||||
|
|
||||||
|
type RenderRoot = HTMLElement & { __litRenderer?: Renderer; _$litPart$?: any };
|
||||||
|
|
||||||
|
type ItemModel = { item: any; index: number };
|
||||||
|
|
||||||
|
type Renderer = ((root: RenderRoot, rendererOwner: HTMLElement, model: ItemModel) => void) & { __rendererId?: string };
|
||||||
|
|
||||||
|
type Component = HTMLElement & { [key: string]: Renderer | undefined };
|
||||||
|
|
||||||
|
const _window = window as any;
|
||||||
|
_window.Vaadin = _window.Vaadin || {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Assigns the component a renderer function which uses Lit to render
|
||||||
|
* the given template expression inside the render root element.
|
||||||
|
*
|
||||||
|
* @param component The host component to which the renderer runction is to be set
|
||||||
|
* @param rendererName The name of the renderer function
|
||||||
|
* @param templateExpression The content of the template literal passed to Lit for rendering.
|
||||||
|
* @param returnChannel A channel to the server.
|
||||||
|
* Calling it will end up invoking a handler in the server-side LitRenderer.
|
||||||
|
* @param clientCallables A list of function names that can be called from within the template literal.
|
||||||
|
* @param propertyNamespace LitRenderer-specific namespace for properties.
|
||||||
|
* Needed to avoid property name collisions between renderers.
|
||||||
|
*/
|
||||||
|
_window.Vaadin.setLitRenderer = (
|
||||||
|
component: Component,
|
||||||
|
rendererName: string,
|
||||||
|
templateExpression: string,
|
||||||
|
returnChannel: (name: string, itemKey: string, args: any[]) => void,
|
||||||
|
clientCallables: string[],
|
||||||
|
propertyNamespace: string,
|
||||||
|
appId: string
|
||||||
|
) => {
|
||||||
|
const callablesCreator = (itemKey: string) => {
|
||||||
|
return clientCallables.map((clientCallable) => (...args: any[]) => {
|
||||||
|
if (itemKey !== undefined) {
|
||||||
|
returnChannel(clientCallable, itemKey, args[0] instanceof Event ? [] : [...args]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
const fnArgs = [
|
||||||
|
'html',
|
||||||
|
'root',
|
||||||
|
'live',
|
||||||
|
'appId',
|
||||||
|
'itemKey',
|
||||||
|
'model',
|
||||||
|
'item',
|
||||||
|
'index',
|
||||||
|
...clientCallables,
|
||||||
|
`return html\`${templateExpression}\``
|
||||||
|
];
|
||||||
|
const htmlGenerator = new Function(...fnArgs);
|
||||||
|
const renderFunction = (root: RenderRoot, model: ItemModel, itemKey: string) => {
|
||||||
|
const { item, index } = model;
|
||||||
|
render(htmlGenerator(html, root, live, appId, itemKey, model, item, index, ...callablesCreator(itemKey)), root);
|
||||||
|
};
|
||||||
|
|
||||||
|
const renderer: Renderer = (root, _, model) => {
|
||||||
|
const { item } = model;
|
||||||
|
// Clean up the root element of any existing content
|
||||||
|
// (and Lit's _$litPart$ property) from other renderers
|
||||||
|
// TODO: Remove once https://github.com/vaadin/web-components/issues/2235 is done
|
||||||
|
if (root.__litRenderer !== renderer) {
|
||||||
|
root.innerHTML = '';
|
||||||
|
delete root._$litPart$;
|
||||||
|
root.__litRenderer = renderer;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Map a new item that only includes the properties defined by
|
||||||
|
// this specific LitRenderer instance. The renderer instance specific
|
||||||
|
// "propertyNamespace" prefix is stripped from the property name at this point:
|
||||||
|
//
|
||||||
|
// item: { key: "2", lr_3769df5394a74ef3_lastName: "Tyler"}
|
||||||
|
// ->
|
||||||
|
// mappedItem: { lastName: "Tyler" }
|
||||||
|
const mappedItem: { [key: string]: any } = {};
|
||||||
|
for (const key in item) {
|
||||||
|
if (key.startsWith(propertyNamespace)) {
|
||||||
|
mappedItem[key.replace(propertyNamespace, '')] = item[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
renderFunction(root, { ...model, item: mappedItem }, item.key);
|
||||||
|
};
|
||||||
|
|
||||||
|
renderer.__rendererId = propertyNamespace;
|
||||||
|
component[rendererName] = renderer;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the renderer function with the given name from the component
|
||||||
|
* if the propertyNamespace matches the renderer's id.
|
||||||
|
*
|
||||||
|
* @param component The host component whose renderer function is to be removed
|
||||||
|
* @param rendererName The name of the renderer function
|
||||||
|
* @param rendererId The rendererId of the function to be removed
|
||||||
|
*/
|
||||||
|
_window.Vaadin.unsetLitRenderer = (component: Component, rendererName: string, rendererId: string) => {
|
||||||
|
// The check for __rendererId property is necessary since the renderer function
|
||||||
|
// may get overridden by another renderer, for example, by one coming from
|
||||||
|
// vaadin-template-renderer. We don't want LitRenderer registration cleanup to
|
||||||
|
// unintentionally remove the new renderer.
|
||||||
|
if (component[rendererName]?.__rendererId === rendererId) {
|
||||||
|
component[rendererName] = undefined;
|
||||||
|
}
|
||||||
|
};
|
122
src/main/frontend/generated/jar-resources/menubarConnector.js
Normal file
122
src/main/frontend/generated/jar-resources/menubarConnector.js
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2000-2024 Vaadin Ltd.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||||
|
* use this file except in compliance with the License. You may obtain a copy of
|
||||||
|
* the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations under
|
||||||
|
* the License.
|
||||||
|
*/
|
||||||
|
import './contextMenuConnector.js';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the connector for a menu bar element.
|
||||||
|
*
|
||||||
|
* @param {HTMLElement} menubar
|
||||||
|
* @param {string} appId
|
||||||
|
*/
|
||||||
|
function initLazy(menubar, appId) {
|
||||||
|
if (menubar.$connector) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const observer = new MutationObserver((records) => {
|
||||||
|
const hasChangedAttributes = records.some((entry) => {
|
||||||
|
const oldValue = entry.oldValue;
|
||||||
|
const newValue = entry.target.getAttribute(entry.attributeName);
|
||||||
|
return oldValue !== newValue;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (hasChangedAttributes) {
|
||||||
|
menubar.$connector.generateItems();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
menubar.$connector = {
|
||||||
|
/**
|
||||||
|
* Generates and assigns the items to the menu bar.
|
||||||
|
*
|
||||||
|
* When the method is called without providing a node id,
|
||||||
|
* the previously generated items tree will be used.
|
||||||
|
* That can be useful if you only want to sync the disabled and hidden properties of root items.
|
||||||
|
*
|
||||||
|
* @param {number | undefined} nodeId
|
||||||
|
*/
|
||||||
|
generateItems(nodeId) {
|
||||||
|
if (!menubar.shadowRoot) {
|
||||||
|
// workaround for https://github.com/vaadin/flow/issues/5722
|
||||||
|
setTimeout(() => menubar.$connector.generateItems(nodeId));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!menubar._container) {
|
||||||
|
// Menu-bar defers first buttons render to avoid re-layout
|
||||||
|
// See https://github.com/vaadin/web-components/issues/7271
|
||||||
|
queueMicrotask(() => menubar.$connector.generateItems(nodeId));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nodeId) {
|
||||||
|
menubar.__generatedItems = window.Vaadin.Flow.contextMenuConnector.generateItemsTree(appId, nodeId);
|
||||||
|
}
|
||||||
|
|
||||||
|
let items = menubar.__generatedItems || [];
|
||||||
|
|
||||||
|
items.forEach((item) => {
|
||||||
|
// Propagate disabled state from items to parent buttons
|
||||||
|
item.disabled = item.component.disabled;
|
||||||
|
|
||||||
|
// Saving item to component because `_item` can be reassigned to a new value
|
||||||
|
// when the component goes to the overflow menu
|
||||||
|
item.component._rootItem = item;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Observe for hidden and disabled attributes in case they are changed by Flow.
|
||||||
|
// When a change occurs, the observer will re-generate items on top of the existing tree
|
||||||
|
// to sync the new attribute values with the corresponding properties in the items array.
|
||||||
|
items.forEach((item) => {
|
||||||
|
observer.observe(item.component, {
|
||||||
|
attributeFilter: ['hidden', 'disabled'],
|
||||||
|
attributeOldValue: true
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Remove hidden items entirely from the array. Just hiding them
|
||||||
|
// could cause the overflow button to be rendered without items.
|
||||||
|
//
|
||||||
|
// The items-prop needs to be set even when all items are visible
|
||||||
|
// to update the disabled state and re-render buttons.
|
||||||
|
items = items.filter((item) => !item.component.hidden);
|
||||||
|
|
||||||
|
menubar.items = items;
|
||||||
|
|
||||||
|
// Propagate click events from the menu buttons to the item components
|
||||||
|
menubar._buttons.forEach((button) => {
|
||||||
|
if (button.item && button.item.component) {
|
||||||
|
button.addEventListener('click', (e) => {
|
||||||
|
if (e.composedPath().indexOf(button.item.component) === -1) {
|
||||||
|
button.item.component.click();
|
||||||
|
e.stopPropagation();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function setClassName(component) {
|
||||||
|
const item = component._rootItem || component._item;
|
||||||
|
|
||||||
|
if (item) {
|
||||||
|
item.className = component.className;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
window.Vaadin.Flow.menubarConnector = { initLazy, setClassName };
|
@ -0,0 +1,33 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2000-2024 Vaadin Ltd.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||||
|
* use this file except in compliance with the License. You may obtain a copy of
|
||||||
|
* the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations under
|
||||||
|
* the License.
|
||||||
|
*/
|
||||||
|
window.Vaadin.Flow.messageListConnector = {
|
||||||
|
setItems(list, items, locale) {
|
||||||
|
const formatter = new Intl.DateTimeFormat(locale, {
|
||||||
|
year: 'numeric',
|
||||||
|
month: 'short',
|
||||||
|
day: 'numeric',
|
||||||
|
hour: 'numeric',
|
||||||
|
minute: 'numeric'
|
||||||
|
});
|
||||||
|
list.items = items.map((item) =>
|
||||||
|
item.time
|
||||||
|
? Object.assign(item, {
|
||||||
|
time: formatter.format(new Date(item.time))
|
||||||
|
})
|
||||||
|
: item
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
19
src/main/frontend/generated/jar-resources/selectConnector.js
Normal file
19
src/main/frontend/generated/jar-resources/selectConnector.js
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
window.Vaadin.Flow.selectConnector = {}
|
||||||
|
window.Vaadin.Flow.selectConnector.initLazy = (select) => {
|
||||||
|
// do not init this connector twice for the given select
|
||||||
|
if (select.$connector) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
select.$connector = {};
|
||||||
|
|
||||||
|
select.renderer = (root) => {
|
||||||
|
const listBox = select.querySelector('vaadin-select-list-box');
|
||||||
|
if (listBox) {
|
||||||
|
if (root.firstChild) {
|
||||||
|
root.removeChild(root.firstChild);
|
||||||
|
}
|
||||||
|
root.appendChild(listBox);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
175
src/main/frontend/generated/jar-resources/theme-util.js
Normal file
175
src/main/frontend/generated/jar-resources/theme-util.js
Normal file
@ -0,0 +1,175 @@
|
|||||||
|
import stripCssComments from 'strip-css-comments';
|
||||||
|
|
||||||
|
// Safari 15 - 16.3, polyfilled
|
||||||
|
const polyfilledSafari = CSSStyleSheet.toString().includes('document.createElement');
|
||||||
|
|
||||||
|
const createLinkReferences = (css, target) => {
|
||||||
|
// Unresolved urls are written as '@import url(text);' or '@import "text";' to the css
|
||||||
|
// media query can be present on @media tag or on @import directive after url
|
||||||
|
// Note that with Vite production build there is no space between @import and "text"
|
||||||
|
// [0] is the full match
|
||||||
|
// [1] matches the media query
|
||||||
|
// [2] matches the url
|
||||||
|
// [3] matches the quote char surrounding in '@import "..."'
|
||||||
|
// [4] matches the url in '@import "..."'
|
||||||
|
// [5] matches media query on @import statement
|
||||||
|
const importMatcher =
|
||||||
|
/(?:@media\s(.+?))?(?:\s{)?\@import\s*(?:url\(\s*['"]?(.+?)['"]?\s*\)|(["'])((?:\\.|[^\\])*?)\3)([^;]*);(?:})?/g;
|
||||||
|
|
||||||
|
// Only cleanup if comment exist
|
||||||
|
if (/\/\*(.|[\r\n])*?\*\//gm.exec(css) != null) {
|
||||||
|
// clean up comments
|
||||||
|
css = stripCssComments(css);
|
||||||
|
}
|
||||||
|
|
||||||
|
var match;
|
||||||
|
var styleCss = css;
|
||||||
|
|
||||||
|
// For each external url import add a link reference
|
||||||
|
while ((match = importMatcher.exec(css)) !== null) {
|
||||||
|
styleCss = styleCss.replace(match[0], '');
|
||||||
|
const link = document.createElement('link');
|
||||||
|
link.rel = 'stylesheet';
|
||||||
|
link.href = match[2] || match[4];
|
||||||
|
const media = match[1] || match[5];
|
||||||
|
if (media) {
|
||||||
|
link.media = media;
|
||||||
|
}
|
||||||
|
// For target document append to head else append to target
|
||||||
|
if (target === document) {
|
||||||
|
document.head.appendChild(link);
|
||||||
|
} else {
|
||||||
|
target.appendChild(link);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return styleCss;
|
||||||
|
};
|
||||||
|
|
||||||
|
const addAdoptedStyleSafariPolyfill = (sheet, target, first) => {
|
||||||
|
if (first) {
|
||||||
|
target.adoptedStyleSheets = [sheet, ...target.adoptedStyleSheets];
|
||||||
|
} else {
|
||||||
|
target.adoptedStyleSheets = [...target.adoptedStyleSheets, sheet];
|
||||||
|
}
|
||||||
|
return () => {
|
||||||
|
target.adoptedStyleSheets = target.adoptedStyleSheets.filter((ss) => ss !== sheet);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const addAdoptedStyle = (cssText, target, first) => {
|
||||||
|
const sheet = new CSSStyleSheet();
|
||||||
|
sheet.replaceSync(cssText);
|
||||||
|
if (polyfilledSafari) {
|
||||||
|
return addAdoptedStyleSafariPolyfill(sheet, target, first);
|
||||||
|
}
|
||||||
|
if (first) {
|
||||||
|
target.adoptedStyleSheets.splice(0, 0, sheet);
|
||||||
|
} else {
|
||||||
|
target.adoptedStyleSheets.push(sheet);
|
||||||
|
}
|
||||||
|
return () => {
|
||||||
|
target.adoptedStyleSheets.splice(target.adoptedStyleSheets.indexOf(sheet), 1);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const addStyleTag = (cssText, referenceComment) => {
|
||||||
|
const styleTag = document.createElement('style');
|
||||||
|
styleTag.type = 'text/css';
|
||||||
|
styleTag.textContent = cssText;
|
||||||
|
|
||||||
|
let beforeThis = undefined;
|
||||||
|
if (referenceComment) {
|
||||||
|
const comments = Array.from(document.head.childNodes).filter(elem => elem.nodeType === Node.COMMENT_NODE);
|
||||||
|
const container = comments.find(comment => comment.data.trim() === referenceComment);
|
||||||
|
if (container) {
|
||||||
|
beforeThis = container;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
document.head.insertBefore(styleTag, beforeThis);
|
||||||
|
return () => {
|
||||||
|
styleTag.remove();
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
// target: Document | ShadowRoot
|
||||||
|
export const injectGlobalCss = (css, referenceComment, target, first) => {
|
||||||
|
if (target === document) {
|
||||||
|
const hash = getHash(css);
|
||||||
|
if (window.Vaadin.theme.injectedGlobalCss.indexOf(hash) !== -1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
window.Vaadin.theme.injectedGlobalCss.push(hash);
|
||||||
|
}
|
||||||
|
const cssText = createLinkReferences(css, target);
|
||||||
|
|
||||||
|
// We avoid mixing style tags and adoptedStyleSheets to make override order clear
|
||||||
|
if (target === document) {
|
||||||
|
return addStyleTag(cssText, referenceComment);
|
||||||
|
}
|
||||||
|
|
||||||
|
return addAdoptedStyle(cssText, target, first);
|
||||||
|
};
|
||||||
|
|
||||||
|
window.Vaadin = window.Vaadin || {};
|
||||||
|
window.Vaadin.theme = window.Vaadin.theme || {};
|
||||||
|
window.Vaadin.theme.injectedGlobalCss = [];
|
||||||
|
|
||||||
|
const webcomponentGlobalCss = {
|
||||||
|
css: [],
|
||||||
|
importers: []
|
||||||
|
};
|
||||||
|
|
||||||
|
export const injectGlobalWebcomponentCss = (css) => {
|
||||||
|
webcomponentGlobalCss.css.push(css);
|
||||||
|
webcomponentGlobalCss.importers.forEach(registrar => {
|
||||||
|
registrar(css);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const webcomponentGlobalCssInjector = (registrar) => {
|
||||||
|
const registeredCss = [];
|
||||||
|
const wrapper = (css) => {
|
||||||
|
const hash = getHash(css);
|
||||||
|
if (!registeredCss.includes(hash)) {
|
||||||
|
registeredCss.push(hash);
|
||||||
|
registrar(css);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
webcomponentGlobalCss.importers.push(wrapper);
|
||||||
|
webcomponentGlobalCss.css.forEach(wrapper);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate a 32 bit FNV-1a hash
|
||||||
|
* Found here: https://gist.github.com/vaiorabbit/5657561
|
||||||
|
* Ref.: http://isthe.com/chongo/tech/comp/fnv/
|
||||||
|
*
|
||||||
|
* @param {string} str the input value
|
||||||
|
* @returns {string} 32 bit (as 8 byte hex string)
|
||||||
|
*/
|
||||||
|
function hashFnv32a(str) {
|
||||||
|
/*jshint bitwise:false */
|
||||||
|
let i,
|
||||||
|
l,
|
||||||
|
hval = 0x811c9dc5;
|
||||||
|
|
||||||
|
for (i = 0, l = str.length; i < l; i++) {
|
||||||
|
hval ^= str.charCodeAt(i);
|
||||||
|
hval += (hval << 1) + (hval << 4) + (hval << 7) + (hval << 8) + (hval << 24);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convert to 8 digit hex string
|
||||||
|
return ('0000000' + (hval >>> 0).toString(16)).substr(-8);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate a 64 bit hash for the given input.
|
||||||
|
* Double hash is used to significantly lower the collision probability.
|
||||||
|
*
|
||||||
|
* @param {string} input value to get hash for
|
||||||
|
* @returns {string} 64 bit (as 16 byte hex string)
|
||||||
|
*/
|
||||||
|
function getHash(input) {
|
||||||
|
let h1 = hashFnv32a(input); // returns 32 bit (as 8 byte hex string)
|
||||||
|
return h1 + hashFnv32a(h1 + input);
|
||||||
|
}
|
23
src/main/frontend/generated/jar-resources/tooltip.ts
Normal file
23
src/main/frontend/generated/jar-resources/tooltip.ts
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
import { Tooltip } from '@vaadin/tooltip/src/vaadin-tooltip.js';
|
||||||
|
|
||||||
|
const _window = window as any;
|
||||||
|
_window.Vaadin ||= {};
|
||||||
|
_window.Vaadin.Flow ||= {};
|
||||||
|
_window.Vaadin.Flow.tooltip ||= {};
|
||||||
|
|
||||||
|
Object.assign(_window.Vaadin.Flow.tooltip, {
|
||||||
|
setDefaultHideDelay: (hideDelay: number) => Tooltip.setDefaultHideDelay(hideDelay),
|
||||||
|
setDefaultFocusDelay: (focusDelay: number) => Tooltip.setDefaultFocusDelay(focusDelay),
|
||||||
|
setDefaultHoverDelay: (hoverDelay: number) => Tooltip.setDefaultHoverDelay(hoverDelay)
|
||||||
|
});
|
||||||
|
|
||||||
|
const { defaultHideDelay, defaultFocusDelay, defaultHoverDelay } = _window.Vaadin.Flow.tooltip;
|
||||||
|
if (defaultHideDelay) {
|
||||||
|
Tooltip.setDefaultHideDelay(defaultHideDelay);
|
||||||
|
}
|
||||||
|
if (defaultFocusDelay) {
|
||||||
|
Tooltip.setDefaultFocusDelay(defaultFocusDelay);
|
||||||
|
}
|
||||||
|
if (defaultHoverDelay) {
|
||||||
|
Tooltip.setDefaultHoverDelay(defaultHoverDelay);
|
||||||
|
}
|
@ -0,0 +1,69 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2000-2024 Vaadin Ltd.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
|
||||||
|
* use this file except in compliance with the License. You may obtain a copy of
|
||||||
|
* the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations under
|
||||||
|
* the License.
|
||||||
|
*/
|
||||||
|
let memoizedTemplate;
|
||||||
|
|
||||||
|
customElements.whenDefined('vaadin-text-field').then(() => {
|
||||||
|
class BigDecimalFieldElement extends customElements.get('vaadin-text-field') {
|
||||||
|
static get template() {
|
||||||
|
if (!memoizedTemplate) {
|
||||||
|
memoizedTemplate = super.template.cloneNode(true);
|
||||||
|
memoizedTemplate.innerHTML += `<style>
|
||||||
|
:host {
|
||||||
|
width: 8em;
|
||||||
|
}
|
||||||
|
|
||||||
|
:host([dir="rtl"]) [part="input-field"] {
|
||||||
|
direction: ltr;
|
||||||
|
}
|
||||||
|
|
||||||
|
:host([dir="rtl"]) [part="input-field"] ::slotted(input) {
|
||||||
|
--_lumo-text-field-overflow-mask-image: linear-gradient(to left, transparent, #000 1.25em) !important;
|
||||||
|
}
|
||||||
|
</style>`;
|
||||||
|
}
|
||||||
|
return memoizedTemplate;
|
||||||
|
}
|
||||||
|
|
||||||
|
static get is() {
|
||||||
|
return 'vaadin-big-decimal-field';
|
||||||
|
}
|
||||||
|
|
||||||
|
static get properties() {
|
||||||
|
return {
|
||||||
|
_decimalSeparator: {
|
||||||
|
type: String,
|
||||||
|
value: '.',
|
||||||
|
observer: '__decimalSeparatorChanged'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
ready() {
|
||||||
|
super.ready();
|
||||||
|
this.inputElement.setAttribute('inputmode', 'decimal');
|
||||||
|
}
|
||||||
|
|
||||||
|
__decimalSeparatorChanged(separator, oldSeparator) {
|
||||||
|
this.allowedCharPattern = '[-+\\d' + separator + ']';
|
||||||
|
|
||||||
|
if (this.value && oldSeparator) {
|
||||||
|
this.value = this.value.split(oldSeparator).join(separator);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
customElements.define(BigDecimalFieldElement.is, BigDecimalFieldElement);
|
||||||
|
});
|
16
src/main/frontend/generated/jar-resources/vaadin-dev-tools/License.d.ts
vendored
Normal file
16
src/main/frontend/generated/jar-resources/vaadin-dev-tools/License.d.ts
vendored
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import { ServerMessage } from "./vaadin-dev-tools";
|
||||||
|
export interface Product {
|
||||||
|
name: string;
|
||||||
|
version: string;
|
||||||
|
}
|
||||||
|
export interface ProductAndMessage {
|
||||||
|
message: string;
|
||||||
|
messageHtml?: string;
|
||||||
|
product: Product;
|
||||||
|
}
|
||||||
|
export declare const findAll: (element: Element | ShadowRoot | Document, tags: string[]) => Element[];
|
||||||
|
export declare const licenseCheckOk: (data: Product) => void;
|
||||||
|
export declare const licenseCheckFailed: (data: ProductAndMessage) => void;
|
||||||
|
export declare const licenseCheckNoKey: (data: ProductAndMessage) => void;
|
||||||
|
export declare const handleLicenseMessage: (message: ServerMessage) => boolean;
|
||||||
|
export declare const licenseInit: () => void;
|
15
src/main/frontend/generated/jar-resources/vaadin-dev-tools/connection.d.ts
vendored
Normal file
15
src/main/frontend/generated/jar-resources/vaadin-dev-tools/connection.d.ts
vendored
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
export declare enum ConnectionStatus {
|
||||||
|
ACTIVE = "active",
|
||||||
|
INACTIVE = "inactive",
|
||||||
|
UNAVAILABLE = "unavailable",
|
||||||
|
ERROR = "error"
|
||||||
|
}
|
||||||
|
export declare abstract class Connection {
|
||||||
|
static HEARTBEAT_INTERVAL: number;
|
||||||
|
status: ConnectionStatus;
|
||||||
|
onHandshake(): void;
|
||||||
|
onConnectionError(_: string): void;
|
||||||
|
onStatusChange(_: ConnectionStatus): void;
|
||||||
|
setActive(yes: boolean): void;
|
||||||
|
setStatus(status: ConnectionStatus): void;
|
||||||
|
}
|
8
src/main/frontend/generated/jar-resources/vaadin-dev-tools/live-reload-connection.d.ts
vendored
Normal file
8
src/main/frontend/generated/jar-resources/vaadin-dev-tools/live-reload-connection.d.ts
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
import { Connection } from './connection.js';
|
||||||
|
export declare class LiveReloadConnection extends Connection {
|
||||||
|
webSocket?: WebSocket;
|
||||||
|
constructor(url: string);
|
||||||
|
onReload(_strategy: string): void;
|
||||||
|
handleMessage(msg: any): void;
|
||||||
|
handleError(msg: any): void;
|
||||||
|
}
|
99
src/main/frontend/generated/jar-resources/vaadin-dev-tools/vaadin-dev-tools.d.ts
vendored
Normal file
99
src/main/frontend/generated/jar-resources/vaadin-dev-tools/vaadin-dev-tools.d.ts
vendored
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
import { LitElement } from 'lit';
|
||||||
|
import { Product } from './License';
|
||||||
|
import { ConnectionStatus } from './connection';
|
||||||
|
/**
|
||||||
|
* Plugin API for the dev tools window.
|
||||||
|
*/
|
||||||
|
export interface DevToolsInterface {
|
||||||
|
send(command: string, data: any): void;
|
||||||
|
}
|
||||||
|
export interface MessageHandler {
|
||||||
|
handleMessage(message: ServerMessage): boolean;
|
||||||
|
}
|
||||||
|
export interface ServerMessage {
|
||||||
|
/**
|
||||||
|
* The command
|
||||||
|
*/
|
||||||
|
command: string;
|
||||||
|
/**
|
||||||
|
* the data for the command
|
||||||
|
*/
|
||||||
|
data: any;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* To create and register a plugin, use e.g.
|
||||||
|
* @example
|
||||||
|
* export class MyTab extends LitElement implements MessageHandler {
|
||||||
|
* render() {
|
||||||
|
* return html`<div>Here I am</div>`;
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* customElements.define('my-tab', MyTab);
|
||||||
|
*
|
||||||
|
* const plugin: DevToolsPlugin = {
|
||||||
|
* init: function (devToolsInterface: DevToolsInterface): void {
|
||||||
|
* devToolsInterface.addTab('Tab title', 'my-tab')
|
||||||
|
* }
|
||||||
|
* };
|
||||||
|
*
|
||||||
|
* (window as any).Vaadin.devToolsPlugins.push(plugin);
|
||||||
|
*/
|
||||||
|
export interface DevToolsPlugin {
|
||||||
|
/**
|
||||||
|
* Called once to initialize the plugin.
|
||||||
|
*
|
||||||
|
* @param devToolsInterface provides methods to interact with the dev tools
|
||||||
|
*/
|
||||||
|
init(devToolsInterface: DevToolsInterface): void;
|
||||||
|
}
|
||||||
|
export declare enum MessageType {
|
||||||
|
LOG = "log",
|
||||||
|
INFORMATION = "information",
|
||||||
|
WARNING = "warning",
|
||||||
|
ERROR = "error"
|
||||||
|
}
|
||||||
|
type DevToolsConf = {
|
||||||
|
enable: boolean;
|
||||||
|
url: string;
|
||||||
|
backend?: string;
|
||||||
|
liveReloadPort: number;
|
||||||
|
token?: string;
|
||||||
|
};
|
||||||
|
export declare class VaadinDevTools extends LitElement {
|
||||||
|
unhandledMessages: ServerMessage[];
|
||||||
|
conf: DevToolsConf;
|
||||||
|
static get styles(): import("lit").CSSResult[];
|
||||||
|
static DISMISSED_NOTIFICATIONS_IN_LOCAL_STORAGE: string;
|
||||||
|
static ACTIVE_KEY_IN_SESSION_STORAGE: string;
|
||||||
|
static TRIGGERED_KEY_IN_SESSION_STORAGE: string;
|
||||||
|
static TRIGGERED_COUNT_KEY_IN_SESSION_STORAGE: string;
|
||||||
|
static AUTO_DEMOTE_NOTIFICATION_DELAY: number;
|
||||||
|
static HOTSWAP_AGENT: string;
|
||||||
|
static JREBEL: string;
|
||||||
|
static SPRING_BOOT_DEVTOOLS: string;
|
||||||
|
static BACKEND_DISPLAY_NAME: Record<string, string>;
|
||||||
|
static get isActive(): boolean;
|
||||||
|
frontendStatus: ConnectionStatus;
|
||||||
|
javaStatus: ConnectionStatus;
|
||||||
|
private root;
|
||||||
|
componentPickActive: boolean;
|
||||||
|
private javaConnection?;
|
||||||
|
private frontendConnection?;
|
||||||
|
private nextMessageId;
|
||||||
|
private transitionDuration;
|
||||||
|
elementTelemetry(): void;
|
||||||
|
openWebSocketConnection(): void;
|
||||||
|
tabHandleMessage(tabElement: HTMLElement, message: ServerMessage): boolean;
|
||||||
|
handleFrontendMessage(message: ServerMessage): void;
|
||||||
|
handleHmrMessage(message: ServerMessage): boolean;
|
||||||
|
getDedicatedWebSocketUrl(): string | undefined;
|
||||||
|
getSpringBootWebSocketUrl(location: any): string;
|
||||||
|
connectedCallback(): void;
|
||||||
|
initPlugin(plugin: DevToolsPlugin): Promise<void>;
|
||||||
|
format(o: any): string;
|
||||||
|
checkLicense(productInfo: Product): void;
|
||||||
|
setActive(yes: boolean): void;
|
||||||
|
render(): import("lit-html").TemplateResult<1>;
|
||||||
|
setJavaLiveReloadActive(active: boolean): void;
|
||||||
|
}
|
||||||
|
export {};
|
File diff suppressed because one or more lines are too long
13
src/main/frontend/generated/jar-resources/vaadin-dev-tools/websocket-connection.d.ts
vendored
Normal file
13
src/main/frontend/generated/jar-resources/vaadin-dev-tools/websocket-connection.d.ts
vendored
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import { Connection } from './connection';
|
||||||
|
export declare class WebSocketConnection extends Connection {
|
||||||
|
static HEARTBEAT_INTERVAL: number;
|
||||||
|
socket?: any;
|
||||||
|
canSend: boolean;
|
||||||
|
constructor(url: string);
|
||||||
|
onReload(_strategy: string): void;
|
||||||
|
onUpdate(_path: string, _content: string): void;
|
||||||
|
onMessage(_message: any): void;
|
||||||
|
handleMessage(msg: any): void;
|
||||||
|
handleError(msg: any): void;
|
||||||
|
send(command: string, data: any): void;
|
||||||
|
}
|
@ -0,0 +1,97 @@
|
|||||||
|
import '@vaadin/grid/vaadin-grid-column.js';
|
||||||
|
import { GridColumn } from '@vaadin/grid/src/vaadin-grid-column.js';
|
||||||
|
import { GridSelectionColumnBaseMixin } from '@vaadin/grid/src/vaadin-grid-selection-column-base-mixin.js';
|
||||||
|
|
||||||
|
export class GridFlowSelectionColumn extends GridSelectionColumnBaseMixin(GridColumn) {
|
||||||
|
|
||||||
|
static get is() {
|
||||||
|
return 'vaadin-grid-flow-selection-column';
|
||||||
|
}
|
||||||
|
|
||||||
|
static get properties() {
|
||||||
|
return {
|
||||||
|
/**
|
||||||
|
* Override property to enable auto-width
|
||||||
|
*/
|
||||||
|
autoWidth: {
|
||||||
|
type: Boolean,
|
||||||
|
value: true
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override property to set custom width
|
||||||
|
*/
|
||||||
|
width: {
|
||||||
|
type: String,
|
||||||
|
value: '56px'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override method from `GridSelectionColumnBaseMixin` to add ID to select all
|
||||||
|
* checkbox
|
||||||
|
*
|
||||||
|
* @override
|
||||||
|
*/
|
||||||
|
_defaultHeaderRenderer(root, _column) {
|
||||||
|
super._defaultHeaderRenderer(root, _column);
|
||||||
|
const checkbox = root.firstElementChild;
|
||||||
|
if (checkbox) {
|
||||||
|
checkbox.id = 'selectAllCheckbox';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override a method from `GridSelectionColumnBaseMixin` to handle the user
|
||||||
|
* selecting all items.
|
||||||
|
*
|
||||||
|
* @protected
|
||||||
|
* @override
|
||||||
|
*/
|
||||||
|
_selectAll() {
|
||||||
|
this.selectAll = true;
|
||||||
|
this.$server.selectAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override a method from `GridSelectionColumnBaseMixin` to handle the user
|
||||||
|
* deselecting all items.
|
||||||
|
*
|
||||||
|
* @protected
|
||||||
|
* @override
|
||||||
|
*/
|
||||||
|
_deselectAll() {
|
||||||
|
this.selectAll = false;
|
||||||
|
this.$server.deselectAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override a method from `GridSelectionColumnBaseMixin` to handle the user
|
||||||
|
* selecting an item.
|
||||||
|
*
|
||||||
|
* @param {Object} item the item to select
|
||||||
|
* @protected
|
||||||
|
* @override
|
||||||
|
*/
|
||||||
|
_selectItem(item) {
|
||||||
|
this._grid.$connector.doSelection([item], true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override a method from `GridSelectionColumnBaseMixin` to handle the user
|
||||||
|
* deselecting an item.
|
||||||
|
*
|
||||||
|
* @param {Object} item the item to deselect
|
||||||
|
* @protected
|
||||||
|
* @override
|
||||||
|
*/
|
||||||
|
_deselectItem(item) {
|
||||||
|
this._grid.$connector.doDeselection([item], true);
|
||||||
|
// Optimistically update select all state
|
||||||
|
this.selectAll = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
customElements.define(GridFlowSelectionColumn.is, GridFlowSelectionColumn);
|
@ -0,0 +1,26 @@
|
|||||||
|
import { Popover } from '@vaadin/popover/src/vaadin-popover.js';
|
||||||
|
|
||||||
|
const _window = window as any;
|
||||||
|
_window.Vaadin ||= {};
|
||||||
|
_window.Vaadin.Flow ||= {};
|
||||||
|
_window.Vaadin.Flow.popover ||= {};
|
||||||
|
|
||||||
|
Object.assign(_window.Vaadin.Flow.popover, {
|
||||||
|
setDefaultHideDelay: (hideDelay: number) => Popover.setDefaultHideDelay(hideDelay),
|
||||||
|
setDefaultFocusDelay: (focusDelay: number) => Popover.setDefaultFocusDelay(focusDelay),
|
||||||
|
setDefaultHoverDelay: (hoverDelay: number) => Popover.setDefaultHoverDelay(hoverDelay)
|
||||||
|
});
|
||||||
|
|
||||||
|
const { defaultHideDelay, defaultFocusDelay, defaultHoverDelay } = _window.Vaadin.Flow.popover;
|
||||||
|
|
||||||
|
if (defaultHideDelay) {
|
||||||
|
Popover.setDefaultHideDelay(defaultHideDelay);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (defaultFocusDelay) {
|
||||||
|
Popover.setDefaultFocusDelay(defaultFocusDelay);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (defaultHoverDelay) {
|
||||||
|
Popover.setDefaultHoverDelay(defaultHoverDelay);
|
||||||
|
}
|
@ -0,0 +1,183 @@
|
|||||||
|
// map from unicode eastern arabic number characters to arabic numbers
|
||||||
|
const EASTERN_ARABIC_DIGIT_MAP = {
|
||||||
|
'\\u0660': '0',
|
||||||
|
'\\u0661': '1',
|
||||||
|
'\\u0662': '2',
|
||||||
|
'\\u0663': '3',
|
||||||
|
'\\u0664': '4',
|
||||||
|
'\\u0665': '5',
|
||||||
|
'\\u0666': '6',
|
||||||
|
'\\u0667': '7',
|
||||||
|
'\\u0668': '8',
|
||||||
|
'\\u0669': '9'
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Escapes the given string so it can be safely used in a regexp.
|
||||||
|
*
|
||||||
|
* @param {string} string
|
||||||
|
* @return {string}
|
||||||
|
*/
|
||||||
|
function escapeRegExp(string) {
|
||||||
|
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses eastern arabic number characters to arabic numbers (0-9)
|
||||||
|
*
|
||||||
|
* @param {string} digits
|
||||||
|
* @return {string}
|
||||||
|
*/
|
||||||
|
function parseEasternArabicDigits(digits) {
|
||||||
|
return digits.replace(/[\u0660-\u0669]/g, function (char) {
|
||||||
|
const unicode = '\\u0' + char.charCodeAt(0).toString(16);
|
||||||
|
return EASTERN_ARABIC_DIGIT_MAP[unicode];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} locale
|
||||||
|
* @param {Date} testTime
|
||||||
|
* @return {string | null}
|
||||||
|
*/
|
||||||
|
function getAmOrPmString(locale, testTime) {
|
||||||
|
const testTimeString = testTime.toLocaleTimeString(locale);
|
||||||
|
|
||||||
|
// AM/PM string is anything from one letter in eastern arabic to standard two letters,
|
||||||
|
// to having space in between, dots ...
|
||||||
|
// cannot disqualify whitespace since some locales use a. m. / p. m.
|
||||||
|
// TODO when more scripts support is added (than Arabic), need to exclude those numbers too
|
||||||
|
const amOrPmRegExp = /[^\d\u0660-\u0669]/;
|
||||||
|
|
||||||
|
const matches =
|
||||||
|
// In most locales, the time ends with AM/PM:
|
||||||
|
testTimeString.match(new RegExp(`${amOrPmRegExp.source}+$`, 'g')) ||
|
||||||
|
// In some locales, the time starts with AM/PM e.g in Chinese:
|
||||||
|
testTimeString.match(new RegExp(`^${amOrPmRegExp.source}+`, 'g'));
|
||||||
|
|
||||||
|
return matches && matches[0].trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} locale
|
||||||
|
* @return {string | null}
|
||||||
|
*/
|
||||||
|
export function getSeparator(locale) {
|
||||||
|
let timeString = TEST_PM_TIME.toLocaleTimeString(locale);
|
||||||
|
|
||||||
|
// Since the next regex picks first non-number-whitespace,
|
||||||
|
// need to discard possible PM from beginning (eg. chinese locale)
|
||||||
|
const pmString = getPmString(locale);
|
||||||
|
if (pmString && timeString.startsWith(pmString)) {
|
||||||
|
timeString = timeString.replace(pmString, '');
|
||||||
|
}
|
||||||
|
|
||||||
|
const matches = timeString.match(/[^\u0660-\u0669\s\d]/);
|
||||||
|
return matches && matches[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Searches for either an AM or PM token in the given time string
|
||||||
|
* depending on what is provided in `amOrPmString`.
|
||||||
|
*
|
||||||
|
* The search is case and space insensitive.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* `searchAmOrPmToken('1 P M', 'PM')` => `'P M'`
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* `searchAmOrPmToken('1 a.m.', 'A. M.')` => `a.m.`
|
||||||
|
*
|
||||||
|
* @param {string} timeString
|
||||||
|
* @param {string} amOrPmString
|
||||||
|
* @return {string | null}
|
||||||
|
*/
|
||||||
|
export function searchAmOrPmToken(timeString, amOrPmString) {
|
||||||
|
if (!amOrPmString) return null;
|
||||||
|
|
||||||
|
// Create a regexp string for searching for AM/PM without space-sensitivity.
|
||||||
|
const tokenRegExpString = amOrPmString.split(/\s*/).map(escapeRegExp).join('\\s*');
|
||||||
|
|
||||||
|
// Create a regexp without case-sensitivity.
|
||||||
|
const tokenRegExp = new RegExp(tokenRegExpString, 'i');
|
||||||
|
|
||||||
|
// Match the regexp against the time string.
|
||||||
|
const tokenMatches = timeString.match(tokenRegExp);
|
||||||
|
if (tokenMatches) {
|
||||||
|
return tokenMatches[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const TEST_PM_TIME = new Date('August 19, 1975 23:15:30');
|
||||||
|
|
||||||
|
export const TEST_AM_TIME = new Date('August 19, 1975 05:15:30');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} locale
|
||||||
|
* @return {string}
|
||||||
|
*/
|
||||||
|
export function getPmString(locale) {
|
||||||
|
return getAmOrPmString(locale, TEST_PM_TIME);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} locale
|
||||||
|
* @return {string}
|
||||||
|
*/
|
||||||
|
export function getAmString(locale) {
|
||||||
|
return getAmOrPmString(locale, TEST_AM_TIME);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} digits
|
||||||
|
* @return {number}
|
||||||
|
*/
|
||||||
|
export function parseDigitsIntoInteger(digits) {
|
||||||
|
return parseInt(parseEasternArabicDigits(digits));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} milliseconds
|
||||||
|
* @return {number}
|
||||||
|
*/
|
||||||
|
export function parseMillisecondsIntoInteger(milliseconds) {
|
||||||
|
milliseconds = parseEasternArabicDigits(milliseconds);
|
||||||
|
// digits are either .1 .01 or .001 so need to "shift"
|
||||||
|
if (milliseconds.length === 1) {
|
||||||
|
milliseconds += '00';
|
||||||
|
} else if (milliseconds.length === 2) {
|
||||||
|
milliseconds += '0';
|
||||||
|
}
|
||||||
|
return parseInt(milliseconds);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} timeString
|
||||||
|
* @param {number} milliseconds
|
||||||
|
* @param {string} amString
|
||||||
|
* @param {string} pmString
|
||||||
|
* @return {string}
|
||||||
|
*/
|
||||||
|
export function formatMilliseconds(timeString, milliseconds, amString, pmString) {
|
||||||
|
// might need to inject milliseconds between seconds and AM/PM
|
||||||
|
let cleanedTimeString = timeString;
|
||||||
|
if (timeString.endsWith(amString)) {
|
||||||
|
cleanedTimeString = timeString.replace(' ' + amString, '');
|
||||||
|
} else if (timeString.endsWith(pmString)) {
|
||||||
|
cleanedTimeString = timeString.replace(' ' + pmString, '');
|
||||||
|
}
|
||||||
|
if (milliseconds) {
|
||||||
|
let millisecondsString = milliseconds < 10 ? '0' : '';
|
||||||
|
millisecondsString += milliseconds < 100 ? '0' : '';
|
||||||
|
millisecondsString += milliseconds;
|
||||||
|
cleanedTimeString += '.' + millisecondsString;
|
||||||
|
} else {
|
||||||
|
cleanedTimeString += '.000';
|
||||||
|
}
|
||||||
|
if (timeString.endsWith(amString)) {
|
||||||
|
cleanedTimeString = cleanedTimeString + ' ' + amString;
|
||||||
|
} else if (timeString.endsWith(pmString)) {
|
||||||
|
cleanedTimeString = cleanedTimeString + ' ' + pmString;
|
||||||
|
}
|
||||||
|
return cleanedTimeString;
|
||||||
|
}
|
@ -0,0 +1,185 @@
|
|||||||
|
import {
|
||||||
|
TEST_PM_TIME,
|
||||||
|
formatMilliseconds,
|
||||||
|
parseMillisecondsIntoInteger,
|
||||||
|
parseDigitsIntoInteger,
|
||||||
|
getAmString,
|
||||||
|
getPmString,
|
||||||
|
getSeparator,
|
||||||
|
searchAmOrPmToken
|
||||||
|
} from './helpers.js';
|
||||||
|
import { parseISOTime } from '@vaadin/time-picker/src/vaadin-time-picker-helper.js';
|
||||||
|
|
||||||
|
// Execute callback when predicate returns true.
|
||||||
|
// Try again later if predicate returns false.
|
||||||
|
function when(predicate, callback, timeout = 0) {
|
||||||
|
if (predicate()) {
|
||||||
|
callback();
|
||||||
|
} else {
|
||||||
|
setTimeout(() => when(predicate, callback, 200), timeout);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseISO(text) {
|
||||||
|
// The default i18n parser of the web component is ISO 8601 compliant.
|
||||||
|
const timeObject = parseISOTime(text);
|
||||||
|
|
||||||
|
// The web component returns an object with string values
|
||||||
|
// while the connector expects number values.
|
||||||
|
return {
|
||||||
|
hours: parseInt(timeObject.hours || 0),
|
||||||
|
minutes: parseInt(timeObject.minutes || 0),
|
||||||
|
seconds: parseInt(timeObject.seconds || 0),
|
||||||
|
milliseconds: parseInt(timeObject.milliseconds || 0)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
window.Vaadin.Flow.timepickerConnector = {};
|
||||||
|
window.Vaadin.Flow.timepickerConnector.initLazy = (timepicker) => {
|
||||||
|
// Check whether the connector was already initialized for the timepicker
|
||||||
|
if (timepicker.$connector) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
timepicker.$connector = {};
|
||||||
|
|
||||||
|
timepicker.$connector.setLocale = (locale) => {
|
||||||
|
// capture previous value if any
|
||||||
|
let previousValueObject;
|
||||||
|
if (timepicker.value && timepicker.value !== '') {
|
||||||
|
previousValueObject = parseISO(timepicker.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Check whether the locale is supported by the browser or not
|
||||||
|
TEST_PM_TIME.toLocaleTimeString(locale);
|
||||||
|
} catch (e) {
|
||||||
|
locale = 'en-US';
|
||||||
|
// FIXME should do a callback for server to throw an exception ?
|
||||||
|
throw new Error(
|
||||||
|
'vaadin-time-picker: The locale ' +
|
||||||
|
locale +
|
||||||
|
' is not supported, falling back to default locale setting(en-US).'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1. 24 or 12 hour clock, if latter then what are the am/pm strings ?
|
||||||
|
const pmString = getPmString(locale);
|
||||||
|
const amString = getAmString(locale);
|
||||||
|
|
||||||
|
// 2. What is the separator ?
|
||||||
|
const separator = getSeparator(locale);
|
||||||
|
|
||||||
|
const includeSeconds = function () {
|
||||||
|
return timepicker.step && timepicker.step < 60;
|
||||||
|
};
|
||||||
|
|
||||||
|
const includeMilliSeconds = function () {
|
||||||
|
return timepicker.step && timepicker.step < 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
let cachedTimeString;
|
||||||
|
let cachedTimeObject;
|
||||||
|
|
||||||
|
timepicker.i18n = {
|
||||||
|
formatTime(timeObject) {
|
||||||
|
if (!timeObject) return;
|
||||||
|
|
||||||
|
const timeToBeFormatted = new Date();
|
||||||
|
timeToBeFormatted.setHours(timeObject.hours);
|
||||||
|
timeToBeFormatted.setMinutes(timeObject.minutes);
|
||||||
|
timeToBeFormatted.setSeconds(timeObject.seconds !== undefined ? timeObject.seconds : 0);
|
||||||
|
|
||||||
|
// the web component expects the correct granularity used for the time string,
|
||||||
|
// thus need to format the time object in correct granularity by passing the format options
|
||||||
|
let localeTimeString = timeToBeFormatted.toLocaleTimeString(locale, {
|
||||||
|
hour: 'numeric',
|
||||||
|
minute: 'numeric',
|
||||||
|
second: includeSeconds() ? 'numeric' : undefined
|
||||||
|
});
|
||||||
|
|
||||||
|
// milliseconds not part of the time format API
|
||||||
|
if (includeMilliSeconds()) {
|
||||||
|
localeTimeString = formatMilliseconds(localeTimeString, timeObject.milliseconds, amString, pmString);
|
||||||
|
}
|
||||||
|
|
||||||
|
return localeTimeString;
|
||||||
|
},
|
||||||
|
|
||||||
|
parseTime(timeString) {
|
||||||
|
if (timeString && timeString === cachedTimeString && cachedTimeObject) {
|
||||||
|
return cachedTimeObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!timeString) {
|
||||||
|
// when nothing is returned, the component shows the invalid state for the input
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const amToken = searchAmOrPmToken(timeString, amString);
|
||||||
|
const pmToken = searchAmOrPmToken(timeString, pmString);
|
||||||
|
|
||||||
|
const numbersOnlyTimeString = timeString
|
||||||
|
.replace(amToken || '', '')
|
||||||
|
.replace(pmToken || '', '')
|
||||||
|
.trim();
|
||||||
|
|
||||||
|
// A regexp that allows to find the numbers with optional separator and continuing searching after it.
|
||||||
|
const numbersRegExp = new RegExp('([\\d\\u0660-\\u0669]){1,2}(?:' + separator + ')?', 'g');
|
||||||
|
|
||||||
|
let hours = numbersRegExp.exec(numbersOnlyTimeString);
|
||||||
|
if (hours) {
|
||||||
|
hours = parseDigitsIntoInteger(hours[0].replace(separator, ''));
|
||||||
|
// handle 12 am -> 0
|
||||||
|
// do not do anything if am & pm are not used or if those are the same,
|
||||||
|
// as with locale bg-BG there is always ч. at the end of the time
|
||||||
|
if (amToken !== pmToken) {
|
||||||
|
if (hours === 12 && amToken) {
|
||||||
|
hours = 0;
|
||||||
|
}
|
||||||
|
if (hours !== 12 && pmToken) {
|
||||||
|
hours += 12;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const minutes = numbersRegExp.exec(numbersOnlyTimeString);
|
||||||
|
const seconds = minutes && numbersRegExp.exec(numbersOnlyTimeString);
|
||||||
|
// detecting milliseconds from input, expects am/pm removed from end, eg. .0 or .00 or .000
|
||||||
|
const millisecondRegExp = /[[\.][\d\u0660-\u0669]{1,3}$/;
|
||||||
|
// reset to end or things can explode
|
||||||
|
let milliseconds = seconds && includeMilliSeconds() && millisecondRegExp.exec(numbersOnlyTimeString);
|
||||||
|
// handle case where last numbers are seconds and . is the separator (invalid regexp match)
|
||||||
|
if (milliseconds && milliseconds['index'] <= seconds['index']) {
|
||||||
|
milliseconds = undefined;
|
||||||
|
}
|
||||||
|
// hours is a number at this point, others are either arrays or null
|
||||||
|
// the string in [0] from the arrays includes the separator too
|
||||||
|
cachedTimeObject = hours !== undefined && {
|
||||||
|
hours: hours,
|
||||||
|
minutes: minutes ? parseDigitsIntoInteger(minutes[0].replace(separator, '')) : 0,
|
||||||
|
seconds: seconds ? parseDigitsIntoInteger(seconds[0].replace(separator, '')) : 0,
|
||||||
|
milliseconds:
|
||||||
|
minutes && seconds && milliseconds
|
||||||
|
? parseMillisecondsIntoInteger(milliseconds[0].replace('.', ''))
|
||||||
|
: 0
|
||||||
|
};
|
||||||
|
cachedTimeString = timeString;
|
||||||
|
return cachedTimeObject;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (previousValueObject) {
|
||||||
|
when(
|
||||||
|
() => timepicker.$,
|
||||||
|
() => {
|
||||||
|
const newValue = timepicker.i18n.formatTime(previousValueObject);
|
||||||
|
// FIXME works but uses private API, needs fixes in web component
|
||||||
|
if (timepicker.inputElement.value !== newValue) {
|
||||||
|
timepicker.inputElement.value = newValue;
|
||||||
|
timepicker.$.comboBox.value = newValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
@ -0,0 +1,150 @@
|
|||||||
|
import { Debouncer } from '@polymer/polymer/lib/utils/debounce.js';
|
||||||
|
import { timeOut } from '@polymer/polymer/lib/utils/async.js';
|
||||||
|
|
||||||
|
window.Vaadin.Flow.virtualListConnector = {
|
||||||
|
initLazy: function (list) {
|
||||||
|
// Check whether the connector was already initialized for the virtual list
|
||||||
|
if (list.$connector) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const extraItemsBuffer = 20;
|
||||||
|
|
||||||
|
let lastRequestedRange = [0, 0];
|
||||||
|
|
||||||
|
list.$connector = {};
|
||||||
|
list.$connector.placeholderItem = { __placeholder: true };
|
||||||
|
|
||||||
|
const updateRequestedItem = function () {
|
||||||
|
/*
|
||||||
|
* TODO virtual list seems to do a small index adjustment after scrolling
|
||||||
|
* has stopped. This causes a redundant request to be sent to make a
|
||||||
|
* corresponding minimal change to the buffer. We should avoid these
|
||||||
|
* requests by making the logic skip doing a request if the available
|
||||||
|
* buffer is within some tolerance compared to the requested buffer.
|
||||||
|
*/
|
||||||
|
const visibleIndexes = [...list.children]
|
||||||
|
.filter((el) => '__virtualListIndex' in el)
|
||||||
|
.map((el) => el.__virtualListIndex);
|
||||||
|
const firstNeededItem = Math.min(...visibleIndexes);
|
||||||
|
const lastNeededItem = Math.max(...visibleIndexes);
|
||||||
|
|
||||||
|
let first = Math.max(0, firstNeededItem - extraItemsBuffer);
|
||||||
|
let last = Math.min(lastNeededItem + extraItemsBuffer, list.items.length);
|
||||||
|
|
||||||
|
if (lastRequestedRange[0] != first || lastRequestedRange[1] != last) {
|
||||||
|
lastRequestedRange = [first, last];
|
||||||
|
const count = 1 + last - first;
|
||||||
|
list.$server.setRequestedRange(first, count);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const scheduleUpdateRequest = function () {
|
||||||
|
list.__requestDebounce = Debouncer.debounce(list.__requestDebounce, timeOut.after(50), updateRequestedItem);
|
||||||
|
};
|
||||||
|
|
||||||
|
requestAnimationFrame(() => updateRequestedItem);
|
||||||
|
|
||||||
|
// Add an observer function that will invoke on virtualList.renderer property
|
||||||
|
// change and then patches it with a wrapper renderer
|
||||||
|
list.patchVirtualListRenderer = function () {
|
||||||
|
if (!list.renderer || list.renderer.__virtualListConnectorPatched) {
|
||||||
|
// The list either doesn't have a renderer yet or it's already been patched
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const originalRenderer = list.renderer;
|
||||||
|
|
||||||
|
const renderer = (root, list, model) => {
|
||||||
|
root.__virtualListIndex = model.index;
|
||||||
|
|
||||||
|
if (model.item === undefined) {
|
||||||
|
if (list.$connector.placeholderElement) {
|
||||||
|
// ComponentRenderer
|
||||||
|
if (!root.__hasComponentRendererPlaceholder) {
|
||||||
|
// The root was previously rendered by the ComponentRenderer. Clear and add a placeholder.
|
||||||
|
root.innerHTML = '';
|
||||||
|
delete root._$litPart$;
|
||||||
|
root.appendChild(list.$connector.placeholderElement.cloneNode(true));
|
||||||
|
root.__hasComponentRendererPlaceholder = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// LitRenderer
|
||||||
|
originalRenderer.call(list, root, list, {
|
||||||
|
...model,
|
||||||
|
item: list.$connector.placeholderItem
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (root.__hasComponentRendererPlaceholder) {
|
||||||
|
// The root was previously populated with a placeholder. Clear it.
|
||||||
|
root.innerHTML = '';
|
||||||
|
root.__hasComponentRendererPlaceholder = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
originalRenderer.call(list, root, list, model);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Check if we need to do anything once things have settled down.
|
||||||
|
* This method is called multiple times in sequence for the same user
|
||||||
|
* action, but we only want to do the check once.
|
||||||
|
*/
|
||||||
|
scheduleUpdateRequest();
|
||||||
|
};
|
||||||
|
renderer.__virtualListConnectorPatched = true;
|
||||||
|
renderer.__rendererId = originalRenderer.__rendererId;
|
||||||
|
|
||||||
|
list.renderer = renderer;
|
||||||
|
};
|
||||||
|
|
||||||
|
list._createPropertyObserver('renderer', 'patchVirtualListRenderer', true);
|
||||||
|
list.patchVirtualListRenderer();
|
||||||
|
|
||||||
|
list.items = [];
|
||||||
|
|
||||||
|
list.$connector.set = function (index, items) {
|
||||||
|
list.items.splice(index, items.length, ...items);
|
||||||
|
list.items = [...list.items];
|
||||||
|
};
|
||||||
|
|
||||||
|
list.$connector.clear = function (index, length) {
|
||||||
|
// How many items, starting from "index", should be set as undefined
|
||||||
|
const clearCount = Math.min(length, list.items.length - index);
|
||||||
|
list.$connector.set(index, [...Array(clearCount)]);
|
||||||
|
};
|
||||||
|
|
||||||
|
list.$connector.updateData = function (items) {
|
||||||
|
const updatedItemsMap = items.reduce((map, item) => {
|
||||||
|
map[item.key] = item;
|
||||||
|
return map;
|
||||||
|
}, {});
|
||||||
|
|
||||||
|
list.items = list.items.map((item) => {
|
||||||
|
// Items can be undefined if they are outside the viewport
|
||||||
|
if (!item) {
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
// Replace existing item with updated item,
|
||||||
|
// return existing item as fallback if it was not updated
|
||||||
|
return updatedItemsMap[item.key] || item;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
list.$connector.updateSize = function (newSize) {
|
||||||
|
const delta = newSize - list.items.length;
|
||||||
|
if (delta > 0) {
|
||||||
|
list.items = [...list.items, ...Array(delta)];
|
||||||
|
} else if (delta < 0) {
|
||||||
|
list.items = list.items.slice(0, newSize);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
list.$connector.setPlaceholderItem = function (placeholderItem = {}, appId) {
|
||||||
|
placeholderItem.__placeholder = true;
|
||||||
|
list.$connector.placeholderItem = placeholderItem;
|
||||||
|
const nodeId = Object.entries(placeholderItem).find(([key]) => key.endsWith('_nodeid'));
|
||||||
|
list.$connector.placeholderElement = nodeId ? Vaadin.Flow.clients[appId].getByNodeId(nodeId[1]) : null;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
11
src/main/frontend/generated/vaadin-featureflags.js
Normal file
11
src/main/frontend/generated/vaadin-featureflags.js
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
// @ts-nocheck
|
||||||
|
window.Vaadin = window.Vaadin || {};
|
||||||
|
window.Vaadin.featureFlags = window.Vaadin.featureFlags || {};
|
||||||
|
window.Vaadin.featureFlags.exampleFeatureFlag = false;
|
||||||
|
window.Vaadin.featureFlags.collaborationEngineBackend = false;
|
||||||
|
window.Vaadin.featureFlags.formFillerAddon = false;
|
||||||
|
window.Vaadin.featureFlags.hillaI18n = false;
|
||||||
|
window.Vaadin.featureFlags.fullstackSignals = false;
|
||||||
|
window.Vaadin.featureFlags.copilotExperimentalFeatures = false;
|
||||||
|
window.Vaadin.featureFlags.dashboardComponent = false;
|
||||||
|
export {};
|
6
src/main/frontend/generated/vaadin.ts
Normal file
6
src/main/frontend/generated/vaadin.ts
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
import './vaadin-featureflags.js';
|
||||||
|
|
||||||
|
import './index';
|
||||||
|
|
||||||
|
import './vaadin-react.js';
|
||||||
|
import 'Frontend/generated/jar-resources/vaadin-dev-tools/vaadin-dev-tools.js';
|
23
src/main/frontend/index.html
Normal file
23
src/main/frontend/index.html
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<!--
|
||||||
|
This file is auto-generated by Vaadin.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
|
<style>
|
||||||
|
body, #outlet {
|
||||||
|
height: 100vh;
|
||||||
|
width: 100%;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<!-- index.ts is included here automatically (either by the dev server or during the build) -->
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<!-- This outlet div is where the views are rendered -->
|
||||||
|
<div id="outlet"></div>
|
||||||
|
</body>
|
||||||
|
</html>
|
1
src/main/java/aReminder
Normal file
1
src/main/java/aReminder
Normal file
@ -0,0 +1 @@
|
|||||||
|
TODO: Change package
|
@ -0,0 +1,12 @@
|
|||||||
|
package ru.vyatsu.qr_access_admin;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
|
||||||
|
@SpringBootApplication
|
||||||
|
public class QrAccessAdminApplication {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(QrAccessAdminApplication.class, args);
|
||||||
|
}
|
||||||
|
}
|
131
src/main/java/ru/vyatsu/qr_access_admin/common/MainLayout.java
Normal file
131
src/main/java/ru/vyatsu/qr_access_admin/common/MainLayout.java
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
package ru.vyatsu.qr_access_admin.common;
|
||||||
|
|
||||||
|
import ru.vyatsu.qr_access_admin.common.view.MainView;
|
||||||
|
import ru.vyatsu.qr_access_admin.door.view.DoorView;
|
||||||
|
import ru.vyatsu.qr_access_admin.qr.view.QrView;
|
||||||
|
import ru.vyatsu.qr_access_admin.unit.view.UnitView;
|
||||||
|
import com.vaadin.flow.component.Component;
|
||||||
|
import com.vaadin.flow.component.ComponentUtil;
|
||||||
|
import com.vaadin.flow.component.applayout.AppLayout;
|
||||||
|
import com.vaadin.flow.component.applayout.DrawerToggle;
|
||||||
|
import com.vaadin.flow.component.html.H1;
|
||||||
|
import com.vaadin.flow.component.html.H2;
|
||||||
|
import com.vaadin.flow.component.icon.VaadinIcon;
|
||||||
|
import com.vaadin.flow.component.orderedlayout.FlexComponent;
|
||||||
|
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
|
||||||
|
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
|
||||||
|
import com.vaadin.flow.component.tabs.Tab;
|
||||||
|
import com.vaadin.flow.component.tabs.Tabs;
|
||||||
|
import com.vaadin.flow.component.tabs.TabsVariant;
|
||||||
|
import com.vaadin.flow.router.PageTitle;
|
||||||
|
import com.vaadin.flow.router.RouterLink;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
|
|
||||||
|
public class MainLayout extends AppLayout {
|
||||||
|
private final Tabs menu;
|
||||||
|
private H2 viewTitle;
|
||||||
|
|
||||||
|
|
||||||
|
public MainLayout() {
|
||||||
|
setPrimarySection(Section.DRAWER);
|
||||||
|
addToNavbar(true, createHeaderContent());
|
||||||
|
menu = createMenu();
|
||||||
|
|
||||||
|
addToDrawer(createDrawerContent(menu));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void afterNavigation() {
|
||||||
|
super.afterNavigation();
|
||||||
|
|
||||||
|
// Select the tab corresponding to currently shown view
|
||||||
|
getTabForComponent(getContent()).ifPresent(menu::setSelectedTab);
|
||||||
|
|
||||||
|
// Set the view title in the header
|
||||||
|
viewTitle.setText(getCurrentPageTitle());
|
||||||
|
}
|
||||||
|
|
||||||
|
private Optional<Tab> getTabForComponent(Component component) {
|
||||||
|
return menu.getChildren()
|
||||||
|
.filter(tab -> ComponentUtil.getData(tab, Class.class)
|
||||||
|
.equals(component.getClass()))
|
||||||
|
.findFirst().map(Tab.class::cast);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getCurrentPageTitle() {
|
||||||
|
return getContent().getClass().getAnnotation(PageTitle.class).value();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Component createHeaderContent() {
|
||||||
|
HorizontalLayout layout = new HorizontalLayout();
|
||||||
|
|
||||||
|
layout.setId("header");
|
||||||
|
layout.getThemeList().set("dark", true);
|
||||||
|
layout.setWidthFull();
|
||||||
|
layout.setAlignItems(FlexComponent.Alignment.CENTER);
|
||||||
|
|
||||||
|
HorizontalLayout innerLayout = new HorizontalLayout();
|
||||||
|
innerLayout.setJustifyContentMode(FlexComponent.JustifyContentMode.BETWEEN);
|
||||||
|
innerLayout.setAlignItems(FlexComponent.Alignment.CENTER);
|
||||||
|
innerLayout.setWidth("100%");
|
||||||
|
layout.add(new DrawerToggle());
|
||||||
|
|
||||||
|
viewTitle = new H2();
|
||||||
|
innerLayout.add(viewTitle);
|
||||||
|
|
||||||
|
RouterLink homeLink = new RouterLink(MainView.class);
|
||||||
|
homeLink.add(VaadinIcon.USER.create());
|
||||||
|
innerLayout.add(homeLink);
|
||||||
|
layout.add(innerLayout);
|
||||||
|
|
||||||
|
return layout;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Component createDrawerContent(Tabs menu) {
|
||||||
|
VerticalLayout layout = new VerticalLayout();
|
||||||
|
|
||||||
|
// Configure styling for the drawer
|
||||||
|
layout.setSizeFull();
|
||||||
|
layout.setPadding(false);
|
||||||
|
layout.setSpacing(false);
|
||||||
|
layout.getThemeList().set("spacing-s", true);
|
||||||
|
layout.setAlignItems(FlexComponent.Alignment.STRETCH);
|
||||||
|
|
||||||
|
// Have a drawer header with an application logo
|
||||||
|
HorizontalLayout logoLayout = new HorizontalLayout();
|
||||||
|
logoLayout.setId("logo");
|
||||||
|
logoLayout.setAlignItems(FlexComponent.Alignment.CENTER);
|
||||||
|
logoLayout.add(VaadinIcon.QRCODE.create());
|
||||||
|
logoLayout.add(new H1("QR-admin"));
|
||||||
|
|
||||||
|
// Display the logo and the menu in the drawer
|
||||||
|
layout.add(logoLayout, menu);
|
||||||
|
return layout;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Tabs createMenu() {
|
||||||
|
final Tabs tabs = new Tabs();
|
||||||
|
tabs.setOrientation(Tabs.Orientation.VERTICAL);
|
||||||
|
tabs.addThemeVariants(TabsVariant.LUMO_MINIMAL);
|
||||||
|
tabs.setId("tabs");
|
||||||
|
tabs.add(createMenuItems());
|
||||||
|
return tabs;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Tab[] createMenuItems() {
|
||||||
|
return new Tab[]{
|
||||||
|
createTab("Домашняя страница", MainView.class),
|
||||||
|
createTab("Устройства", UnitView.class),
|
||||||
|
createTab("Двери", DoorView.class),
|
||||||
|
createTab("QR-коды", QrView.class)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Tab createTab(String text, Class<? extends Component> navigationTarget) {
|
||||||
|
final Tab tab = new Tab();
|
||||||
|
tab.add(new RouterLink(text, navigationTarget));
|
||||||
|
ComponentUtil.setData(tab, Class.class, navigationTarget);
|
||||||
|
return tab;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
package ru.vyatsu.qr_access_admin.common.config;
|
||||||
|
|
||||||
|
import com.vaadin.flow.component.page.AppShellConfigurator;
|
||||||
|
import com.vaadin.flow.theme.Theme;
|
||||||
|
import com.vaadin.flow.theme.lumo.Lumo;
|
||||||
|
|
||||||
|
@Theme(themeClass = Lumo.class)
|
||||||
|
public class CustomShellConfigurator implements AppShellConfigurator {
|
||||||
|
}
|
@ -0,0 +1,20 @@
|
|||||||
|
package ru.vyatsu.qr_access_admin.common.validation;
|
||||||
|
|
||||||
|
import jakarta.validation.Constraint;
|
||||||
|
import jakarta.validation.Payload;
|
||||||
|
|
||||||
|
import java.lang.annotation.*;
|
||||||
|
|
||||||
|
@Target(ElementType.FIELD)
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Constraint(validatedBy = IsAfterValidator.class)
|
||||||
|
@Documented
|
||||||
|
public @interface IsAfter {
|
||||||
|
String message() default "{date.time.is.after.validation}";
|
||||||
|
|
||||||
|
String dateTime() default "NOW";
|
||||||
|
|
||||||
|
Class<?>[] groups() default {};
|
||||||
|
|
||||||
|
Class<? extends Payload>[] payload() default {};
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
package ru.vyatsu.qr_access_admin.common.validation;
|
||||||
|
|
||||||
|
import jakarta.validation.ConstraintValidator;
|
||||||
|
import jakarta.validation.ConstraintValidatorContext;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
public class IsAfterValidator implements ConstraintValidator<IsAfter, LocalDateTime> {
|
||||||
|
|
||||||
|
private LocalDateTime dateTime;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void initialize(IsAfter constraintAnnotation) {
|
||||||
|
String sDate = constraintAnnotation.dateTime();
|
||||||
|
if (sDate.equals("NOW")) {
|
||||||
|
dateTime = LocalDateTime.now();
|
||||||
|
} else {
|
||||||
|
dateTime = LocalDateTime.parse(sDate);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isValid(LocalDateTime value, ConstraintValidatorContext context) {
|
||||||
|
if (value == null) return true;
|
||||||
|
return value.isAfter(dateTime);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
package ru.vyatsu.qr_access_admin.common.view;
|
||||||
|
|
||||||
|
import ru.vyatsu.qr_access_admin.common.MainLayout;
|
||||||
|
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
|
||||||
|
import com.vaadin.flow.router.PageTitle;
|
||||||
|
import com.vaadin.flow.router.Route;
|
||||||
|
|
||||||
|
@Route(value = "", layout = MainLayout.class)
|
||||||
|
@PageTitle("Start")
|
||||||
|
public class MainView extends VerticalLayout {
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,89 @@
|
|||||||
|
package ru.vyatsu.qr_access_admin.door.component;
|
||||||
|
|
||||||
|
import ru.vyatsu.qr_access_admin.door.entity.DoorEntity;
|
||||||
|
import ru.vyatsu.qr_access_admin.unit.model.UnitComboBoxModel;
|
||||||
|
import ru.vyatsu.qr_access_admin.unit.entity.UnitRepository;
|
||||||
|
import ru.vyatsu.qr_access_admin.unit.mapper.UnitEntityUnitComboBoxModelMapper;
|
||||||
|
import com.vaadin.flow.component.Composite;
|
||||||
|
import com.vaadin.flow.component.Key;
|
||||||
|
import com.vaadin.flow.component.button.Button;
|
||||||
|
import com.vaadin.flow.component.button.ButtonVariant;
|
||||||
|
import com.vaadin.flow.component.combobox.ComboBox;
|
||||||
|
import com.vaadin.flow.component.icon.VaadinIcon;
|
||||||
|
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
|
||||||
|
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
|
||||||
|
import com.vaadin.flow.data.binder.BeanValidationBinder;
|
||||||
|
import com.vaadin.flow.data.binder.Binder;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class DoorEditor extends Composite<VerticalLayout> {
|
||||||
|
|
||||||
|
private final UnitEntityUnitComboBoxModelMapper unitMapper = new UnitEntityUnitComboBoxModelMapper();
|
||||||
|
|
||||||
|
public interface SaveListener {
|
||||||
|
void onSave(DoorEntity door);
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface DeleteListener {
|
||||||
|
void onDelete(DoorEntity door);
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface CancelListener {
|
||||||
|
void onCancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
private volatile DoorEntity currentDoor;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
private SaveListener saveListener;
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
private DeleteListener deleteListener;
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
private CancelListener cancelListener;
|
||||||
|
|
||||||
|
private final Binder<DoorEntity> binder = new BeanValidationBinder<>(DoorEntity.class);
|
||||||
|
|
||||||
|
public void setCurrentDoor(DoorEntity door) {
|
||||||
|
this.currentDoor = door;
|
||||||
|
binder.setBean(door);
|
||||||
|
}
|
||||||
|
|
||||||
|
public DoorEditor(UnitRepository unitRepository) {
|
||||||
|
ComboBox<UnitComboBoxModel> unitField = new ComboBox<>("Устройство");
|
||||||
|
unitField.setRequired(true);
|
||||||
|
unitField.setPageSize(100);
|
||||||
|
Map<String, UnitComboBoxModel> units = unitRepository.findAll()
|
||||||
|
.stream()
|
||||||
|
.map(unitMapper::toModel)
|
||||||
|
.collect(Collectors.toMap(UnitComboBoxModel::clientId, unit -> unit));
|
||||||
|
unitField.setItems(units.values());
|
||||||
|
unitField.setItemLabelGenerator(UnitComboBoxModel::clientName);
|
||||||
|
|
||||||
|
var save = new Button("Сохранить", VaadinIcon.CHECK.create());
|
||||||
|
var cancel = new Button("Отмена");
|
||||||
|
var delete = new Button("Удалить", VaadinIcon.TRASH.create());
|
||||||
|
|
||||||
|
binder.forField(unitField)
|
||||||
|
.withConverter(UnitComboBoxModel::clientId, units::get, "Invalid value")
|
||||||
|
.bind("unitId");
|
||||||
|
|
||||||
|
save.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
|
||||||
|
save.addClickListener(e -> saveListener.onSave(currentDoor));
|
||||||
|
save.addClickShortcut(Key.ENTER);
|
||||||
|
|
||||||
|
delete.addThemeVariants(ButtonVariant.LUMO_ERROR);
|
||||||
|
delete.addClickListener(e -> deleteListener.onDelete(currentDoor));
|
||||||
|
|
||||||
|
cancel.addClickListener(e -> cancelListener.onCancel());
|
||||||
|
|
||||||
|
getContent().add(unitField, new HorizontalLayout(save, cancel, delete));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
package ru.vyatsu.qr_access_admin.door.entity;
|
||||||
|
|
||||||
|
import jakarta.persistence.*;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "doors")
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class DoorEntity {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.UUID)
|
||||||
|
private String id;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
private String unitId;
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
package ru.vyatsu.qr_access_admin.door.entity;
|
||||||
|
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
|
||||||
|
public interface DoorRepository extends JpaRepository<DoorEntity, String> {
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,79 @@
|
|||||||
|
package ru.vyatsu.qr_access_admin.door.view;
|
||||||
|
|
||||||
|
import ru.vyatsu.qr_access_admin.common.MainLayout;
|
||||||
|
import ru.vyatsu.qr_access_admin.door.component.DoorEditor;
|
||||||
|
import ru.vyatsu.qr_access_admin.door.entity.DoorEntity;
|
||||||
|
import ru.vyatsu.qr_access_admin.door.entity.DoorRepository;
|
||||||
|
import ru.vyatsu.qr_access_admin.unit.entity.UnitRepository;
|
||||||
|
import com.vaadin.flow.component.button.Button;
|
||||||
|
import com.vaadin.flow.component.grid.Grid;
|
||||||
|
import com.vaadin.flow.component.icon.VaadinIcon;
|
||||||
|
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
|
||||||
|
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
|
||||||
|
import com.vaadin.flow.router.PageTitle;
|
||||||
|
import com.vaadin.flow.router.Route;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Route(value = "doors", layout = MainLayout.class)
|
||||||
|
@PageTitle("Двери")
|
||||||
|
public class DoorView extends VerticalLayout {
|
||||||
|
private final Grid<DoorEntity> grid;
|
||||||
|
private final DoorRepository repository;
|
||||||
|
private final DoorEditor editor;
|
||||||
|
|
||||||
|
public DoorView(DoorRepository repository, UnitRepository unitRepository) {
|
||||||
|
this.repository = repository;
|
||||||
|
|
||||||
|
var addButton = new Button("Добавить дверь", VaadinIcon.PLUS.create());
|
||||||
|
|
||||||
|
grid = new Grid<>(DoorEntity.class);
|
||||||
|
editor = new DoorEditor(unitRepository);
|
||||||
|
|
||||||
|
var actionsLayout = new HorizontalLayout(addButton);
|
||||||
|
add(actionsLayout, grid, editor);
|
||||||
|
|
||||||
|
this.configureEditor();
|
||||||
|
|
||||||
|
addButton.addClickListener(e -> editDoor(new DoorEntity()));
|
||||||
|
|
||||||
|
grid.setHeight("200px");
|
||||||
|
|
||||||
|
grid.asSingleSelect().addValueChangeListener(e -> editDoor(e.getValue()));
|
||||||
|
|
||||||
|
refreshDoorsGrid();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void refreshDoorsGrid() {
|
||||||
|
List<DoorEntity> entities = repository.findAll();
|
||||||
|
|
||||||
|
grid.setItems(entities);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void editDoor(DoorEntity door) {
|
||||||
|
if (door == null) {
|
||||||
|
editor.setVisible(false);
|
||||||
|
} else {
|
||||||
|
editor.setVisible(true);
|
||||||
|
editor.setCurrentDoor(door);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void configureEditor() {
|
||||||
|
editor.setVisible(false);
|
||||||
|
|
||||||
|
editor.setSaveListener(door -> {
|
||||||
|
repository.save(door);
|
||||||
|
refreshDoorsGrid();
|
||||||
|
editDoor(null);
|
||||||
|
});
|
||||||
|
|
||||||
|
editor.setDeleteListener(door -> {
|
||||||
|
repository.deleteById(door.getId());
|
||||||
|
refreshDoorsGrid();
|
||||||
|
editDoor(null);
|
||||||
|
});
|
||||||
|
|
||||||
|
editor.setCancelListener(() -> editDoor(null));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,89 @@
|
|||||||
|
package ru.vyatsu.qr_access_admin.qr.component;
|
||||||
|
|
||||||
|
import com.vaadin.flow.component.Composite;
|
||||||
|
import com.vaadin.flow.component.Key;
|
||||||
|
import com.vaadin.flow.component.button.Button;
|
||||||
|
import com.vaadin.flow.component.button.ButtonVariant;
|
||||||
|
import com.vaadin.flow.component.combobox.ComboBox;
|
||||||
|
import com.vaadin.flow.component.datetimepicker.DateTimePicker;
|
||||||
|
import com.vaadin.flow.component.icon.VaadinIcon;
|
||||||
|
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
|
||||||
|
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
|
||||||
|
import com.vaadin.flow.data.binder.BeanValidationBinder;
|
||||||
|
import com.vaadin.flow.data.binder.Binder;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
import ru.vyatsu.qr_access_admin.door.entity.DoorEntity;
|
||||||
|
import ru.vyatsu.qr_access_admin.door.entity.DoorRepository;
|
||||||
|
import ru.vyatsu.qr_access_admin.qr.entity.QrEntity;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class QrEditor extends Composite<VerticalLayout> {
|
||||||
|
|
||||||
|
public interface SaveListener {
|
||||||
|
void onSave(QrEntity qr);
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface DeleteListener {
|
||||||
|
void onDelete(QrEntity qr);
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface CancelListener {
|
||||||
|
void onCancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
private volatile QrEntity currentQr;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
private SaveListener saveListener;
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
private DeleteListener deleteListener;
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
private CancelListener cancelListener;
|
||||||
|
|
||||||
|
private final Binder<QrEntity> binder = new BeanValidationBinder<>(QrEntity.class);
|
||||||
|
|
||||||
|
public void setCurrentQr(QrEntity qr) {
|
||||||
|
this.currentQr = qr;
|
||||||
|
binder.setBean(qr);
|
||||||
|
}
|
||||||
|
|
||||||
|
public QrEditor(DoorRepository doorRepository) {
|
||||||
|
ComboBox<DoorEntity> doorIdField = new ComboBox<>("Идентификатор двери");
|
||||||
|
doorIdField.setRequired(true);
|
||||||
|
doorIdField.setItemLabelGenerator(DoorEntity::getId);
|
||||||
|
Map<String, DoorEntity> doors = doorRepository.findAll()
|
||||||
|
.stream()
|
||||||
|
.collect(Collectors.toMap(DoorEntity::getId, e -> e));
|
||||||
|
|
||||||
|
doorIdField.setItems(doors.values());
|
||||||
|
var startDateTime = new DateTimePicker("Начало действия");
|
||||||
|
var endDateTime = new DateTimePicker("Актуален до");
|
||||||
|
|
||||||
|
var save = new Button("Сохранить", VaadinIcon.CHECK.create());
|
||||||
|
var cancel = new Button("Отмена");
|
||||||
|
var delete = new Button("Удалить", VaadinIcon.TRASH.create());
|
||||||
|
|
||||||
|
binder.forField(doorIdField)
|
||||||
|
.withConverter(DoorEntity::getId, doors::get, "Invalid value")
|
||||||
|
.bind("doorId");
|
||||||
|
binder.forField(startDateTime).bind("startDateTime");
|
||||||
|
binder.forField(endDateTime).bind("endDateTime");
|
||||||
|
|
||||||
|
save.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
|
||||||
|
save.addClickListener(e -> saveListener.onSave(currentQr));
|
||||||
|
save.addClickShortcut(Key.ENTER);
|
||||||
|
|
||||||
|
delete.addThemeVariants(ButtonVariant.LUMO_ERROR);
|
||||||
|
delete.addClickListener(e -> deleteListener.onDelete(currentQr));
|
||||||
|
|
||||||
|
cancel.addClickListener(e -> cancelListener.onCancel());
|
||||||
|
|
||||||
|
getContent().add(doorIdField, startDateTime, endDateTime, new HorizontalLayout(save, cancel, delete));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,28 @@
|
|||||||
|
package ru.vyatsu.qr_access_admin.qr.entity;
|
||||||
|
|
||||||
|
import jakarta.persistence.*;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "qrs")
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class QrEntity {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@Column
|
||||||
|
@GeneratedValue(strategy = GenerationType.UUID)
|
||||||
|
private String keyCode;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
private String doorId;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
private LocalDateTime startDateTime;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
private LocalDateTime endDateTime;
|
||||||
|
}
|
@ -0,0 +1,6 @@
|
|||||||
|
package ru.vyatsu.qr_access_admin.qr.entity;
|
||||||
|
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
|
||||||
|
public interface QrRepository extends JpaRepository<QrEntity, String> {
|
||||||
|
}
|
76
src/main/java/ru/vyatsu/qr_access_admin/qr/view/QrView.java
Normal file
76
src/main/java/ru/vyatsu/qr_access_admin/qr/view/QrView.java
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
package ru.vyatsu.qr_access_admin.qr.view;
|
||||||
|
|
||||||
|
import com.vaadin.flow.component.button.Button;
|
||||||
|
import com.vaadin.flow.component.grid.Grid;
|
||||||
|
import com.vaadin.flow.component.icon.VaadinIcon;
|
||||||
|
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
|
||||||
|
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
|
||||||
|
import com.vaadin.flow.router.PageTitle;
|
||||||
|
import com.vaadin.flow.router.Route;
|
||||||
|
import ru.vyatsu.qr_access_admin.common.MainLayout;
|
||||||
|
import ru.vyatsu.qr_access_admin.door.entity.DoorRepository;
|
||||||
|
import ru.vyatsu.qr_access_admin.qr.component.QrEditor;
|
||||||
|
import ru.vyatsu.qr_access_admin.qr.entity.QrEntity;
|
||||||
|
import ru.vyatsu.qr_access_admin.qr.entity.QrRepository;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Route(value = "qrs", layout = MainLayout.class)
|
||||||
|
@PageTitle("Коды")
|
||||||
|
public class QrView extends VerticalLayout {
|
||||||
|
private final QrRepository repository;
|
||||||
|
private final Grid<QrEntity> grid;
|
||||||
|
private final QrEditor editor;
|
||||||
|
|
||||||
|
public QrView(QrRepository repository, DoorRepository doorRepository) {
|
||||||
|
this.repository = repository;
|
||||||
|
|
||||||
|
var addButton = new Button("Добавить код", VaadinIcon.PLUS.create());
|
||||||
|
grid = new Grid<>(QrEntity.class);
|
||||||
|
editor = new QrEditor(doorRepository);
|
||||||
|
|
||||||
|
var actionsLayout = new HorizontalLayout(addButton);
|
||||||
|
add(actionsLayout, grid, editor);
|
||||||
|
|
||||||
|
this.configureEditor();
|
||||||
|
|
||||||
|
addButton.addClickListener(e -> editQr(new QrEntity()));
|
||||||
|
|
||||||
|
grid.setHeight("200px");
|
||||||
|
grid.asSingleSelect().addValueChangeListener(e -> editQr(e.getValue()));
|
||||||
|
|
||||||
|
refreshQrGrid();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void refreshQrGrid() {
|
||||||
|
List<QrEntity> entities = repository.findAll();
|
||||||
|
grid.setItems(entities);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void editQr(QrEntity qr) {
|
||||||
|
if (qr == null) {
|
||||||
|
editor.setVisible(false);
|
||||||
|
} else {
|
||||||
|
editor.setVisible(true);
|
||||||
|
editor.setCurrentQr(qr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void configureEditor() {
|
||||||
|
editor.setVisible(false);
|
||||||
|
|
||||||
|
editor.setSaveListener(qr -> {
|
||||||
|
repository.save(qr);
|
||||||
|
refreshQrGrid();
|
||||||
|
editQr(null);
|
||||||
|
});
|
||||||
|
|
||||||
|
editor.setDeleteListener(qr -> {
|
||||||
|
repository.deleteById(qr.getKeyCode());
|
||||||
|
refreshQrGrid();
|
||||||
|
editQr(null);
|
||||||
|
});
|
||||||
|
|
||||||
|
editor.setCancelListener(() -> editQr(null));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,80 @@
|
|||||||
|
package ru.vyatsu.qr_access_admin.unit.component;
|
||||||
|
|
||||||
|
import ru.vyatsu.qr_access_admin.unit.model.UnitModel;
|
||||||
|
import com.vaadin.flow.component.Composite;
|
||||||
|
import com.vaadin.flow.component.Key;
|
||||||
|
import com.vaadin.flow.component.button.Button;
|
||||||
|
import com.vaadin.flow.component.button.ButtonVariant;
|
||||||
|
import com.vaadin.flow.component.datetimepicker.DateTimePicker;
|
||||||
|
import com.vaadin.flow.component.icon.VaadinIcon;
|
||||||
|
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
|
||||||
|
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
|
||||||
|
import com.vaadin.flow.component.textfield.TextField;
|
||||||
|
import com.vaadin.flow.data.binder.BeanValidationBinder;
|
||||||
|
import com.vaadin.flow.data.binder.Binder;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
public class UnitEditor extends Composite<VerticalLayout> {
|
||||||
|
public interface SaveListener {
|
||||||
|
void onSave(UnitModel unit);
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface DeleteListener {
|
||||||
|
void onDelete(UnitModel unit);
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface CancelListener {
|
||||||
|
void onCancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
private volatile UnitModel currentUnit;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
private SaveListener saveListener;
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
private DeleteListener deleteListener;
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
private CancelListener cancelListener;
|
||||||
|
|
||||||
|
private final Binder<UnitModel> binder = new BeanValidationBinder<>(UnitModel.class);
|
||||||
|
|
||||||
|
public void setCurrentUnit(UnitModel unit) {
|
||||||
|
this.currentUnit = unit;
|
||||||
|
binder.setBean(unit);
|
||||||
|
}
|
||||||
|
|
||||||
|
public UnitEditor() {
|
||||||
|
var clientId = new TextField("Идентификатор устройства");
|
||||||
|
clientId.setRequired(true);
|
||||||
|
var clientSecret = new TextField("Секрет устройства");
|
||||||
|
clientSecret.setRequired(true);
|
||||||
|
var clientSecretExpiresAt = new DateTimePicker("Актуален до");
|
||||||
|
clientSecretExpiresAt.setRequiredIndicatorVisible(true);
|
||||||
|
var clientName = new TextField("Человекочитаемое название устройства");
|
||||||
|
clientName.setRequired(true);
|
||||||
|
|
||||||
|
var save = new Button("Сохранить", VaadinIcon.CHECK.create());
|
||||||
|
var cancel = new Button("Отмена");
|
||||||
|
var delete = new Button("Удалить", VaadinIcon.TRASH.create());
|
||||||
|
|
||||||
|
binder.forField(clientId).bind("clientId");
|
||||||
|
binder.forField(clientSecret).bind("clientSecret");
|
||||||
|
binder.forField(clientSecretExpiresAt).bind("clientSecretExpiresAt");
|
||||||
|
binder.forField(clientName).bind("clientName");
|
||||||
|
|
||||||
|
save.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
|
||||||
|
save.addClickListener(e -> saveListener.onSave(currentUnit));
|
||||||
|
save.addClickShortcut(Key.ENTER);
|
||||||
|
|
||||||
|
delete.addThemeVariants(ButtonVariant.LUMO_ERROR);
|
||||||
|
delete.addClickListener(e -> deleteListener.onDelete(currentUnit));
|
||||||
|
|
||||||
|
cancel.addClickListener(e -> cancelListener.onCancel());
|
||||||
|
|
||||||
|
getContent().add(clientId, clientSecret, clientSecretExpiresAt, clientName, new HorizontalLayout(save, cancel, delete));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,50 @@
|
|||||||
|
package ru.vyatsu.qr_access_admin.unit.entity;
|
||||||
|
|
||||||
|
import jakarta.persistence.*;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.Setter;
|
||||||
|
import org.hibernate.annotations.CreationTimestamp;
|
||||||
|
import org.hibernate.annotations.JdbcTypeCode;
|
||||||
|
import org.hibernate.annotations.SourceType;
|
||||||
|
import org.hibernate.type.SqlTypes;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "oauth2_registered_client")
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@NoArgsConstructor
|
||||||
|
public class UnitEntity {
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.UUID)
|
||||||
|
private String id;
|
||||||
|
@Column
|
||||||
|
private String clientId;
|
||||||
|
@Column
|
||||||
|
@CreationTimestamp(source = SourceType.DB)
|
||||||
|
private LocalDateTime clientIdIssuedAt;
|
||||||
|
@Column
|
||||||
|
private String clientSecret;
|
||||||
|
@Column
|
||||||
|
private LocalDateTime clientSecretExpiresAt;
|
||||||
|
@Column
|
||||||
|
private String clientName;
|
||||||
|
@Column
|
||||||
|
private String clientAuthenticationMethods;
|
||||||
|
@Column
|
||||||
|
private String authorizationGrantTypes;
|
||||||
|
@Column
|
||||||
|
private String redirectUris;
|
||||||
|
@Column
|
||||||
|
private String postLogoutRedirectUris;
|
||||||
|
@Column
|
||||||
|
private String scopes;
|
||||||
|
@Column
|
||||||
|
@JdbcTypeCode(SqlTypes.JSON)
|
||||||
|
private String clientSettings;
|
||||||
|
@Column
|
||||||
|
@JdbcTypeCode(SqlTypes.JSON)
|
||||||
|
private String tokenSettings;
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
package ru.vyatsu.qr_access_admin.unit.entity;
|
||||||
|
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
import org.springframework.stereotype.Repository;
|
||||||
|
|
||||||
|
@Repository
|
||||||
|
public interface UnitRepository extends JpaRepository<UnitEntity, String> {
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
package ru.vyatsu.qr_access_admin.unit.mapper;
|
||||||
|
|
||||||
|
import ru.vyatsu.qr_access_admin.unit.model.UnitComboBoxModel;
|
||||||
|
import ru.vyatsu.qr_access_admin.unit.entity.UnitEntity;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class UnitEntityUnitComboBoxModelMapper {
|
||||||
|
|
||||||
|
public UnitComboBoxModel toModel(UnitEntity entity) {
|
||||||
|
if (entity == null) {
|
||||||
|
throw new IllegalArgumentException("UnitEntity cannot be null");
|
||||||
|
}
|
||||||
|
return new UnitComboBoxModel(entity.getClientId(), entity.getClientName());
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<UnitComboBoxModel> toModels(Collection<UnitEntity> entities) {
|
||||||
|
return entities.stream()
|
||||||
|
.map(this::toModel)
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,53 @@
|
|||||||
|
package ru.vyatsu.qr_access_admin.unit.mapper;
|
||||||
|
|
||||||
|
import ru.vyatsu.qr_access_admin.unit.entity.UnitEntity;
|
||||||
|
import ru.vyatsu.qr_access_admin.unit.model.UnitModel;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class UnitEntityUnitModelMapper {
|
||||||
|
|
||||||
|
public static final String DEFAULT_CLIENT_SETTINGS = "{\"@class\":\"java.util.Collections$UnmodifiableMap\",\"settings.client.require-proof-key\":false,\"settings.client.require-authorization-consent\":false}";
|
||||||
|
private static final String DEFAULT_TOKEN_SETTINGS = """
|
||||||
|
{"@class":"java.util.Collections$UnmodifiableMap","settings.token.reuse-refresh-tokens":true,"settings.token.x509-certificate-bound-access-tokens":false,"settings.token.id-token-signature-algorithm":["org.springframework.security.oauth2.jose.jws.SignatureAlgorithm","RS256"],"settings.token.access-token-time-to-live":["java.time.Duration",31540000.000000000],"settings.token.access-token-format":{"@class":"org.springframework.security.oauth2.server.authorization.settings.OAuth2TokenFormat","value":"self-contained"},"settings.token.refresh-token-time-to-live":["java.time.Duration",3600.000000000],"settings.token.authorization-code-time-to-live":["java.time.Duration",300.000000000],"settings.token.device-code-time-to-live":["java.time.Duration",300.000000000]}
|
||||||
|
""";
|
||||||
|
|
||||||
|
public UnitEntity mapModelToEntity(UnitModel model) {
|
||||||
|
UnitEntity entity = new UnitEntity();
|
||||||
|
entity.setId(model.getId());
|
||||||
|
entity.setClientId(model.getClientId());
|
||||||
|
// TODO: Приделать PasswordEncoder когда заедет security
|
||||||
|
entity.setClientSecret(model.getClientSecret());
|
||||||
|
entity.setClientSecretExpiresAt(model.getClientSecretExpiresAt());
|
||||||
|
entity.setClientName(model.getClientName());
|
||||||
|
entity.setScopes("");
|
||||||
|
// TODO: Использовать enum, когда заедет oauth2
|
||||||
|
entity.setAuthorizationGrantTypes("client_credentials");
|
||||||
|
// TODO: Использовать enum, когда заедет oauth2
|
||||||
|
entity.setClientAuthenticationMethods("client_secret_post");
|
||||||
|
entity.setClientSettings(DEFAULT_CLIENT_SETTINGS);
|
||||||
|
entity.setTokenSettings(DEFAULT_TOKEN_SETTINGS);
|
||||||
|
entity.setRedirectUris("");
|
||||||
|
entity.setPostLogoutRedirectUris("");
|
||||||
|
return entity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UnitModel mapEntityToModel(UnitEntity entity) {
|
||||||
|
UnitModel unitModel = new UnitModel();
|
||||||
|
unitModel.setId(entity.getId());
|
||||||
|
unitModel.setClientId(entity.getClientId());
|
||||||
|
unitModel.setClientSecret(entity.getClientSecret());
|
||||||
|
unitModel.setClientName(entity.getClientName());
|
||||||
|
unitModel.setClientSecretExpiresAt(entity.getClientSecretExpiresAt());
|
||||||
|
return unitModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<UnitModel> mapEntityToModel(Collection<UnitEntity> entities) {
|
||||||
|
return entities.stream()
|
||||||
|
.map(this::mapEntityToModel)
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,4 @@
|
|||||||
|
package ru.vyatsu.qr_access_admin.unit.model;
|
||||||
|
|
||||||
|
public record UnitComboBoxModel(String clientId, String clientName) {
|
||||||
|
}
|
@ -0,0 +1,29 @@
|
|||||||
|
package ru.vyatsu.qr_access_admin.unit.model;
|
||||||
|
|
||||||
|
import ru.vyatsu.qr_access_admin.common.validation.IsAfter;
|
||||||
|
import jakarta.validation.constraints.NotBlank;
|
||||||
|
import jakarta.validation.constraints.Size;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
@NoArgsConstructor
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class UnitModel {
|
||||||
|
|
||||||
|
private String id;
|
||||||
|
@NotBlank
|
||||||
|
@Size(max = 100)
|
||||||
|
private String clientId;
|
||||||
|
@Size(max = 255)
|
||||||
|
@NotBlank
|
||||||
|
private String clientSecret;
|
||||||
|
@IsAfter
|
||||||
|
private LocalDateTime clientSecretExpiresAt;
|
||||||
|
@NotBlank
|
||||||
|
@Size(max = 255)
|
||||||
|
private String clientName;
|
||||||
|
}
|
@ -0,0 +1,82 @@
|
|||||||
|
package ru.vyatsu.qr_access_admin.unit.view;
|
||||||
|
|
||||||
|
import com.vaadin.flow.component.button.Button;
|
||||||
|
import com.vaadin.flow.component.grid.Grid;
|
||||||
|
import com.vaadin.flow.component.icon.VaadinIcon;
|
||||||
|
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
|
||||||
|
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
|
||||||
|
import com.vaadin.flow.router.PageTitle;
|
||||||
|
import com.vaadin.flow.router.Route;
|
||||||
|
import ru.vyatsu.qr_access_admin.common.MainLayout;
|
||||||
|
import ru.vyatsu.qr_access_admin.unit.component.UnitEditor;
|
||||||
|
import ru.vyatsu.qr_access_admin.unit.entity.UnitEntity;
|
||||||
|
import ru.vyatsu.qr_access_admin.unit.entity.UnitRepository;
|
||||||
|
import ru.vyatsu.qr_access_admin.unit.mapper.UnitEntityUnitModelMapper;
|
||||||
|
import ru.vyatsu.qr_access_admin.unit.model.UnitModel;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Route(value = "units", layout = MainLayout.class)
|
||||||
|
@PageTitle("Устройства")
|
||||||
|
public class UnitView extends VerticalLayout {
|
||||||
|
|
||||||
|
private final UnitRepository unitRepository;
|
||||||
|
private final Grid<UnitModel> grid;
|
||||||
|
private final UnitEditor editor;
|
||||||
|
private final UnitEntityUnitModelMapper entityModelMapper;
|
||||||
|
|
||||||
|
public UnitView(UnitRepository unitRepository, UnitEntityUnitModelMapper entityModelMapper) {
|
||||||
|
this.unitRepository = unitRepository;
|
||||||
|
this.entityModelMapper = entityModelMapper;
|
||||||
|
|
||||||
|
var addButton = new Button("Добавить устройство", VaadinIcon.PLUS.create());
|
||||||
|
grid = new Grid<>(UnitModel.class);
|
||||||
|
editor = new UnitEditor();
|
||||||
|
|
||||||
|
var actionsLayout = new HorizontalLayout(addButton);
|
||||||
|
add(actionsLayout, grid, editor);
|
||||||
|
|
||||||
|
this.configureEditor();
|
||||||
|
|
||||||
|
addButton.addClickListener(e -> editUnit(new UnitModel()));
|
||||||
|
|
||||||
|
grid.setHeight("200px");
|
||||||
|
grid.asSingleSelect().addValueChangeListener(e -> editUnit(e.getValue()));
|
||||||
|
|
||||||
|
refreshUnitsGrid();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void refreshUnitsGrid() {
|
||||||
|
List<UnitEntity> entities = unitRepository.findAll();
|
||||||
|
|
||||||
|
grid.setItems(entityModelMapper.mapEntityToModel(entities));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void editUnit(UnitModel unit) {
|
||||||
|
if (unit == null) {
|
||||||
|
editor.setVisible(false);
|
||||||
|
} else {
|
||||||
|
editor.setVisible(true);
|
||||||
|
editor.setCurrentUnit(unit);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void configureEditor() {
|
||||||
|
editor.setVisible(false);
|
||||||
|
|
||||||
|
editor.setSaveListener(unit -> {
|
||||||
|
UnitEntity entity = entityModelMapper.mapModelToEntity(unit);
|
||||||
|
unitRepository.save(entity);
|
||||||
|
refreshUnitsGrid();
|
||||||
|
editUnit(null);
|
||||||
|
});
|
||||||
|
|
||||||
|
editor.setDeleteListener(unit -> {
|
||||||
|
unitRepository.deleteById(unit.getId());
|
||||||
|
refreshUnitsGrid();
|
||||||
|
editUnit(null);
|
||||||
|
});
|
||||||
|
|
||||||
|
editor.setCancelListener(() -> editUnit(null));
|
||||||
|
}
|
||||||
|
}
|
14
src/main/resources/application.yaml
Normal file
14
src/main/resources/application.yaml
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
server:
|
||||||
|
port: 8082
|
||||||
|
spring:
|
||||||
|
application:
|
||||||
|
name: qr-access-admin
|
||||||
|
datasource:
|
||||||
|
url: jdbc:postgresql://localhost:5432/qr_access
|
||||||
|
username: qr_access_user
|
||||||
|
password: 123
|
||||||
|
security:
|
||||||
|
oauth2:
|
||||||
|
resourceserver:
|
||||||
|
jwt:
|
||||||
|
jwk-set-uri: http://localhost:8081/oauth2/jwks
|
BIN
src/main/resources/static/favicon.ico
Normal file
BIN
src/main/resources/static/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.7 KiB |
BIN
src/main/resources/static/images/avatar.png
Normal file
BIN
src/main/resources/static/images/avatar.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 9.2 KiB |
BIN
src/main/resources/static/images/logo.png
Normal file
BIN
src/main/resources/static/images/logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.7 KiB |
@ -0,0 +1,11 @@
|
|||||||
|
package ru.vyatsu.qr_access_admin;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
|
||||||
|
@SpringBootTest
|
||||||
|
class QrAccessAdminApplicationTests {
|
||||||
|
@Test
|
||||||
|
void contextLoads() {
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user