Struktura programu z widokami i repozytorium
This commit is contained in:
commit
d42be59ec6
34
.gitignore
vendored
Normal file
34
.gitignore
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
node_modules
|
||||
HELP.md
|
||||
target/
|
||||
!.mvn/wrapper/maven-wrapper.jar
|
||||
!**/src/main/**/target/
|
||||
!**/src/test/**/target/
|
||||
|
||||
### STS ###
|
||||
.apt_generated
|
||||
.classpath
|
||||
.factorypath
|
||||
.project
|
||||
.settings
|
||||
.springBeans
|
||||
.sts4-cache
|
||||
|
||||
### IntelliJ IDEA ###
|
||||
.idea
|
||||
*.iws
|
||||
*.iml
|
||||
*.ipr
|
||||
|
||||
### NetBeans ###
|
||||
/nbproject/private/
|
||||
/nbbuild/
|
||||
/dist/
|
||||
/nbdist/
|
||||
/.nb-gradle/
|
||||
build/
|
||||
!**/src/main/**/build/
|
||||
!**/src/test/**/build/
|
||||
|
||||
### VS Code ###
|
||||
.vscode/
|
BIN
.mvn/wrapper/maven-wrapper.jar
vendored
Normal file
BIN
.mvn/wrapper/maven-wrapper.jar
vendored
Normal file
Binary file not shown.
2
.mvn/wrapper/maven-wrapper.properties
vendored
Normal file
2
.mvn/wrapper/maven-wrapper.properties
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.6/apache-maven-3.8.6-bin.zip
|
||||
wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar
|
32
frontend/generated/index.ts
Normal file
32
frontend/generated/index.ts
Normal file
@ -0,0 +1,32 @@
|
||||
/******************************************************************************
|
||||
* This file is auto-generated by Vaadin.
|
||||
* If you want to customize the entry point, you can copy this file or create
|
||||
* your own `index.ts` in your frontend directory.
|
||||
* By default, the `index.ts` file should be in `./frontend/` folder.
|
||||
*
|
||||
* NOTE:
|
||||
* - You need to restart the dev-server after adding the new `index.ts` file.
|
||||
* After that, all modifications to `index.ts` are recompiled automatically.
|
||||
* - `index.js` is also supported if you don't want to use TypeScript.
|
||||
******************************************************************************/
|
||||
|
||||
// import Vaadin client-router to handle client-side and server-side navigation
|
||||
import { Router } from '@vaadin/router';
|
||||
|
||||
// import Flow module to enable navigation to Vaadin server-side views
|
||||
import { Flow } from 'Frontend/generated/jar-resources/Flow.js';
|
||||
|
||||
const { serverSideRoutes } = new Flow({
|
||||
imports: () => import('../../target/frontend/generated-flow-imports.js')
|
||||
});
|
||||
|
||||
const routes = [
|
||||
// for client-side, place routes below (more info https://vaadin.com/docs/v15/flow/typescript/creating-routes.html)
|
||||
|
||||
// for server-side, the next magic line sends all unmatched routes:
|
||||
...serverSideRoutes // IMPORTANT: this must be the last entry in the array
|
||||
];
|
||||
|
||||
// Vaadin router needs an outlet in the index.html page to display views
|
||||
const router = new Router(document.querySelector('#outlet'));
|
||||
router.setRoutes(routes);
|
74
frontend/generated/jar-resources/Flow.d.ts
vendored
Normal file
74
frontend/generated/jar-resources/Flow.d.ts
vendored
Normal file
@ -0,0 +1,74 @@
|
||||
export interface FlowConfig {
|
||||
imports?: () => void;
|
||||
}
|
||||
interface AppConfig {
|
||||
productionMode: boolean;
|
||||
appId: string;
|
||||
uidl: any;
|
||||
clientRouting: boolean;
|
||||
}
|
||||
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;
|
||||
}
|
||||
interface FlowRoute {
|
||||
action: (params: NavigationParameters) => Promise<HTMLRouterContainer>;
|
||||
path: string;
|
||||
}
|
||||
export interface NavigationParameters {
|
||||
pathname: string;
|
||||
search: string;
|
||||
}
|
||||
export interface PreventCommands {
|
||||
prevent: () => 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;
|
||||
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 injectAppIdScript;
|
||||
private flowInitClient;
|
||||
private flowInitUi;
|
||||
private addConnectionIndicator;
|
||||
private offlineStubAction;
|
||||
private isFlowClientLoaded;
|
||||
}
|
||||
export {};
|
324
frontend/generated/jar-resources/Flow.js
Normal file
324
frontend/generated/jar-resources/Flow.js
Normal file
@ -0,0 +1,324 @@
|
||||
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;
|
||||
/**
|
||||
* 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 = /^\//;
|
||||
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();
|
||||
}
|
||||
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) => {
|
||||
resolve(cmd && cancel ? cmd.prevent() : {});
|
||||
this.loadingFinished();
|
||||
};
|
||||
// Call server side to check whether we can leave the view
|
||||
flowRoot.$server.leaveNavigation(this.getFlowRoutePath(ctx), 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) => {
|
||||
if (cmd && cancel) {
|
||||
resolve(cmd.prevent());
|
||||
}
|
||||
else if (cmd && cmd.redirect && redirectContext) {
|
||||
resolve(cmd.redirect(redirectContext.pathname));
|
||||
}
|
||||
else {
|
||||
this.container.style.display = '';
|
||||
resolve(this.container);
|
||||
}
|
||||
this.loadingFinished();
|
||||
};
|
||||
// Call server side to navigate to the given route
|
||||
flowRoot.$server.connectClient(this.container.localName, this.container.id, this.getFlowRoutePath(ctx), this.getFlowRouteQuery(ctx), this.appShellTitle, history.state);
|
||||
});
|
||||
}
|
||||
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(serverSideRouting = false) {
|
||||
// Do not start flow twice
|
||||
if (!this.isFlowClientLoaded()) {
|
||||
// show flow progress indicator
|
||||
this.loadingStarted();
|
||||
// Initialize server side UI
|
||||
this.response = await this.flowInitUi(serverSideRouting);
|
||||
// Enable or disable server side routing
|
||||
this.response.appConfig.clientRouting = !serverSideRouting;
|
||||
const { pushScript, appConfig } = this.response;
|
||||
if (typeof pushScript === 'string') {
|
||||
await this.loadScript(pushScript);
|
||||
}
|
||||
const { appId } = appConfig;
|
||||
// Load bootstrap script with server side parameters
|
||||
const bootstrapMod = await import('./FlowBootstrap');
|
||||
await 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);
|
||||
if (!serverSideRouting) {
|
||||
// we use a custom tag for the flow app container
|
||||
const tag = `flow-container-${appId.toLowerCase()}`;
|
||||
this.container = document.createElement(tag);
|
||||
flowRoot.$[appId] = this.container;
|
||||
this.container.id = appId;
|
||||
}
|
||||
// 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;
|
||||
document.body.appendChild(script);
|
||||
});
|
||||
}
|
||||
injectAppIdScript(appId) {
|
||||
const appIdWithoutHashCode = appId.substring(0, appId.lastIndexOf('-'));
|
||||
const scriptAppId = document.createElement('script');
|
||||
scriptAppId.type = 'module';
|
||||
scriptAppId.setAttribute('data-app-id', appIdWithoutHashCode);
|
||||
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 = Object.keys($wnd.Vaadin.Flow.clients)
|
||||
.filter((key) => key !== 'TypeScript')
|
||||
.reduce((prev, id) => prev || $wnd.Vaadin.Flow.clients[id].isActive(), false);
|
||||
if (!initializing) {
|
||||
clearInterval(intervalId);
|
||||
resolve();
|
||||
}
|
||||
}, 5);
|
||||
});
|
||||
}
|
||||
// Returns the `appConfig` object
|
||||
async flowInitUi(serverSideRouting) {
|
||||
// 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 serverRoutingParam = serverSideRouting ? '&serverSideRouting' : '';
|
||||
const requestPath = `?v-r=init&location=${encodeURIComponent(this.getFlowRoutePath(location))}&query=${encodeURIComponent(this.getFlowRouteQuery(location))}${serverRoutingParam}`;
|
||||
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
frontend/generated/jar-resources/Flow.js.map
Normal file
1
frontend/generated/jar-resources/Flow.js.map
Normal file
File diff suppressed because one or more lines are too long
1
frontend/generated/jar-resources/FlowBootstrap.d.ts
vendored
Normal file
1
frontend/generated/jar-resources/FlowBootstrap.d.ts
vendored
Normal file
@ -0,0 +1 @@
|
||||
export const init: (appInitResponse: any) => void;
|
262
frontend/generated/jar-resources/FlowBootstrap.js
Normal file
262
frontend/generated/jar-resources/FlowBootstrap.js
Normal file
@ -0,0 +1,262 @@
|
||||
/* 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)) {
|
||||
throw new Error('Application ' + appId + ' already initialized');
|
||||
}
|
||||
}
|
||||
|
||||
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
frontend/generated/jar-resources/FlowClient.d.ts
vendored
Normal file
1
frontend/generated/jar-resources/FlowClient.d.ts
vendored
Normal file
@ -0,0 +1 @@
|
||||
export const init: () => void;
|
1100
frontend/generated/jar-resources/FlowClient.js
Normal file
1100
frontend/generated/jar-resources/FlowClient.js
Normal file
File diff suppressed because one or more lines are too long
14
frontend/generated/jar-resources/License.d.ts
vendored
Normal file
14
frontend/generated/jar-resources/License.d.ts
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
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 licenseInit: () => void;
|
110
frontend/generated/jar-resources/License.js
Normal file
110
frontend/generated/jar-resources/License.js
Normal file
@ -0,0 +1,110 @@
|
||||
const noLicenseFallbackTimeout = 1000;
|
||||
export const findAll = (element, tags) => {
|
||||
const lightDom = Array.from(element.querySelectorAll(tags.join(', ')));
|
||||
const shadowDom = Array.from(element.querySelectorAll('*'))
|
||||
.filter((e) => e.shadowRoot)
|
||||
.flatMap((e) => findAll(e.shadowRoot, tags));
|
||||
return [...lightDom, ...shadowDom];
|
||||
};
|
||||
let licenseCheckListener = false;
|
||||
const showNoLicenseFallback = (element, productAndMessage) => {
|
||||
if (!licenseCheckListener) {
|
||||
// When a license check has succeeded, refresh so that all elements are properly shown again
|
||||
window.addEventListener('message', (e) => {
|
||||
if (e.data === 'validate-license') {
|
||||
window.location.reload();
|
||||
}
|
||||
}, false);
|
||||
licenseCheckListener = true;
|
||||
}
|
||||
const overlay = element._overlayElement;
|
||||
if (overlay) {
|
||||
if (overlay.shadowRoot) {
|
||||
const defaultSlot = overlay.shadowRoot.querySelector('slot:not([name])');
|
||||
if (defaultSlot && defaultSlot.assignedElements().length > 0) {
|
||||
showNoLicenseFallback(defaultSlot.assignedElements()[0], productAndMessage);
|
||||
return;
|
||||
}
|
||||
}
|
||||
showNoLicenseFallback(overlay, productAndMessage);
|
||||
return;
|
||||
}
|
||||
const htmlMessage = productAndMessage.messageHtml
|
||||
? productAndMessage.messageHtml
|
||||
: `${productAndMessage.message} <p>Component: ${productAndMessage.product.name} ${productAndMessage.product.version}</p>`.replace(/https:([^ ]*)/g, "<a href='https:$1'>https:$1</a>");
|
||||
if (element.isConnected) {
|
||||
element.outerHTML = `<no-license style="display:flex;align-items:center;text-align:center;justify-content:center;"><div>${htmlMessage}</div></no-license>`;
|
||||
}
|
||||
};
|
||||
const productTagNames = {};
|
||||
const productChecking = {};
|
||||
const productMissingLicense = {};
|
||||
const productCheckOk = {};
|
||||
const key = (product) => {
|
||||
return `${product.name}_${product.version}`;
|
||||
};
|
||||
const checkLicenseIfNeeded = (cvdlElement) => {
|
||||
var _a;
|
||||
const { cvdlName, version } = cvdlElement.constructor;
|
||||
const product = { name: cvdlName, version };
|
||||
const tagName = cvdlElement.tagName.toLowerCase();
|
||||
productTagNames[cvdlName] = (_a = productTagNames[cvdlName]) !== null && _a !== void 0 ? _a : [];
|
||||
productTagNames[cvdlName].push(tagName);
|
||||
const failedLicenseCheck = productMissingLicense[key(product)];
|
||||
if (failedLicenseCheck) {
|
||||
// Has been checked and the check failed
|
||||
setTimeout(() => showNoLicenseFallback(cvdlElement, failedLicenseCheck), noLicenseFallbackTimeout);
|
||||
}
|
||||
if (productMissingLicense[key(product)] || productCheckOk[key(product)]) {
|
||||
// Already checked
|
||||
}
|
||||
else if (!productChecking[key(product)]) {
|
||||
// Has not been checked
|
||||
productChecking[key(product)] = true;
|
||||
window.Vaadin.devTools.checkLicense(product);
|
||||
}
|
||||
};
|
||||
export const licenseCheckOk = (data) => {
|
||||
productCheckOk[key(data)] = true;
|
||||
// eslint-disable-next-line no-console
|
||||
console.debug('License check ok for', data);
|
||||
};
|
||||
export const licenseCheckFailed = (data) => {
|
||||
const productName = data.product.name;
|
||||
productMissingLicense[key(data.product)] = data;
|
||||
// eslint-disable-next-line no-console
|
||||
console.error('License check failed for', productName);
|
||||
const tags = productTagNames[productName];
|
||||
if ((tags === null || tags === void 0 ? void 0 : tags.length) > 0) {
|
||||
findAll(document, tags).forEach((element) => {
|
||||
setTimeout(() => showNoLicenseFallback(element, productMissingLicense[key(data.product)]), noLicenseFallbackTimeout);
|
||||
});
|
||||
}
|
||||
};
|
||||
export const licenseCheckNoKey = (data) => {
|
||||
const keyUrl = data.message;
|
||||
const productName = data.product.name;
|
||||
data.messageHtml = `No license found. <a target=_blank onclick="javascript:window.open(this.href);return false;" href="${keyUrl}">Go here to start a trial or retrieve your license.</a>`;
|
||||
productMissingLicense[key(data.product)] = data;
|
||||
// eslint-disable-next-line no-console
|
||||
console.error('No license found when checking', productName);
|
||||
const tags = productTagNames[productName];
|
||||
if ((tags === null || tags === void 0 ? void 0 : tags.length) > 0) {
|
||||
findAll(document, tags).forEach((element) => {
|
||||
setTimeout(() => showNoLicenseFallback(element, productMissingLicense[key(data.product)]), noLicenseFallbackTimeout);
|
||||
});
|
||||
}
|
||||
};
|
||||
export const licenseInit = () => {
|
||||
// Process already registered elements
|
||||
window.Vaadin.devTools.createdCvdlElements.forEach((element) => {
|
||||
checkLicenseIfNeeded(element);
|
||||
});
|
||||
// Handle new elements directly
|
||||
window.Vaadin.devTools.createdCvdlElements = {
|
||||
push: (element) => {
|
||||
checkLicenseIfNeeded(element);
|
||||
}
|
||||
};
|
||||
};
|
||||
//# sourceMappingURL=License.js.map
|
1
frontend/generated/jar-resources/License.js.map
Normal file
1
frontend/generated/jar-resources/License.js.map
Normal file
File diff suppressed because one or more lines are too long
284
frontend/generated/jar-resources/comboBoxConnector.js
Normal file
284
frontend/generated/jar-resources/comboBoxConnector.js
Normal file
@ -0,0 +1,284 @@
|
||||
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';
|
||||
|
||||
(function () {
|
||||
const tryCatchWrapper = function (callback) {
|
||||
return window.Vaadin.Flow.tryCatchWrapper(callback, 'Vaadin Combo Box');
|
||||
};
|
||||
|
||||
window.Vaadin.Flow.comboBoxConnector = {
|
||||
initLazy: (comboBox) =>
|
||||
tryCatchWrapper(function (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 = tryCatchWrapper((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 = tryCatchWrapper(function (item, filter) {
|
||||
filter = filter ? filter.toString().toLowerCase() : '';
|
||||
return comboBox._getItemLabel(item, comboBox.itemLabelPath).toString().toLowerCase().indexOf(filter) > -1;
|
||||
});
|
||||
|
||||
comboBox.$connector.set = tryCatchWrapper(function (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 = tryCatchWrapper(function (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 = tryCatchWrapper(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 = tryCatchWrapper(function () {
|
||||
clearPageCallbacks();
|
||||
cache = {};
|
||||
comboBox.clearCache();
|
||||
});
|
||||
|
||||
comboBox.$connector.confirm = tryCatchWrapper(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 = tryCatchWrapper(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 = tryCatchWrapper(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',
|
||||
tryCatchWrapper((e) => e.preventDefault())
|
||||
);
|
||||
})(comboBox)
|
||||
};
|
||||
})();
|
||||
|
||||
window.Vaadin.ComboBoxPlaceholder = ComboBoxPlaceholder;
|
40
frontend/generated/jar-resources/confirmDialogConnector.js
Normal file
40
frontend/generated/jar-resources/confirmDialogConnector.js
Normal file
@ -0,0 +1,40 @@
|
||||
(function () {
|
||||
function copyClassName(dialog) {
|
||||
const overlay = dialog._overlayElement;
|
||||
if (overlay) {
|
||||
overlay.className = dialog.className;
|
||||
}
|
||||
}
|
||||
|
||||
const observer = new MutationObserver((records) => {
|
||||
records.forEach((mutation) => {
|
||||
if (mutation.type === 'attributes' && mutation.attributeName === 'class') {
|
||||
copyClassName(mutation.target);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
window.Vaadin.Flow.confirmDialogConnector = {
|
||||
initLazy: function (dialog) {
|
||||
if (dialog.$connector) {
|
||||
return;
|
||||
}
|
||||
|
||||
dialog.$connector = {};
|
||||
|
||||
dialog.addEventListener('opened-changed', (e) => {
|
||||
if (e.detail.value) {
|
||||
copyClassName(dialog);
|
||||
}
|
||||
});
|
||||
|
||||
observer.observe(dialog, {
|
||||
attributes: true,
|
||||
attributeFilter: ['class']
|
||||
});
|
||||
|
||||
// Copy initial class
|
||||
copyClassName(dialog);
|
||||
}
|
||||
};
|
||||
})();
|
117
frontend/generated/jar-resources/contextMenuConnector.js
Normal file
117
frontend/generated/jar-resources/contextMenuConnector.js
Normal file
@ -0,0 +1,117 @@
|
||||
(function () {
|
||||
function tryCatchWrapper(callback) {
|
||||
return window.Vaadin.Flow.tryCatchWrapper(callback, 'Vaadin Context Menu');
|
||||
}
|
||||
|
||||
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: tryCatchWrapper((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,
|
||||
theme: child.__theme
|
||||
};
|
||||
if (child.localName == 'vaadin-context-menu-item' && 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;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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(...args) {
|
||||
return tryCatchWrapper(initLazy)(...args);
|
||||
},
|
||||
|
||||
generateItemsTree(...args) {
|
||||
return tryCatchWrapper(generateItemsTree)(...args);
|
||||
},
|
||||
|
||||
setChecked(...args) {
|
||||
return tryCatchWrapper(setChecked)(...args);
|
||||
},
|
||||
|
||||
setTheme(...args) {
|
||||
return tryCatchWrapper(setTheme)(...args);
|
||||
}
|
||||
};
|
||||
})();
|
@ -0,0 +1,70 @@
|
||||
import * as Gestures from '@vaadin/component-base/src/gestures.js';
|
||||
|
||||
(function () {
|
||||
function tryCatchWrapper(callback) {
|
||||
return window.Vaadin.Flow.tryCatchWrapper(callback, 'Vaadin Context Menu Target');
|
||||
}
|
||||
|
||||
function init(target) {
|
||||
if (target.$contextMenuTargetConnector) {
|
||||
return;
|
||||
}
|
||||
|
||||
target.$contextMenuTargetConnector = {
|
||||
openOnHandler: tryCatchWrapper(function (e) {
|
||||
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: tryCatchWrapper(function (eventType) {
|
||||
this.removeListener();
|
||||
this.openOnEventType = eventType;
|
||||
|
||||
customElements.whenDefined('vaadin-context-menu').then(
|
||||
tryCatchWrapper(() => {
|
||||
if (Gestures.gestures[eventType]) {
|
||||
Gestures.addListener(target, eventType, this.openOnHandler);
|
||||
} else {
|
||||
target.addEventListener(eventType, this.openOnHandler);
|
||||
}
|
||||
})
|
||||
);
|
||||
}),
|
||||
|
||||
removeListener: tryCatchWrapper(function () {
|
||||
if (this.openOnEventType) {
|
||||
if (Gestures.gestures[this.openOnEventType]) {
|
||||
Gestures.removeListener(target, this.openOnEventType, this.openOnHandler);
|
||||
} else {
|
||||
target.removeEventListener(this.openOnEventType, this.openOnHandler);
|
||||
}
|
||||
}
|
||||
}),
|
||||
|
||||
openMenu: tryCatchWrapper(function (contextMenu) {
|
||||
contextMenu.open(this.openEvent);
|
||||
}),
|
||||
|
||||
removeConnector: tryCatchWrapper(function () {
|
||||
this.removeListener();
|
||||
target.$contextMenuTargetConnector = undefined;
|
||||
})
|
||||
};
|
||||
}
|
||||
|
||||
window.Vaadin.Flow.contextMenuTargetConnector = {
|
||||
init(...args) {
|
||||
return tryCatchWrapper(init)(...args);
|
||||
}
|
||||
};
|
||||
})();
|
150
frontend/generated/jar-resources/copy-to-clipboard.js
Normal file
150
frontend/generated/jar-resources/copy-to-clipboard.js
Normal file
@ -0,0 +1,150 @@
|
||||
"use strict";
|
||||
|
||||
var deselectCurrent = function () {
|
||||
var selection = document.getSelection();
|
||||
if (!selection.rangeCount) {
|
||||
return function () {};
|
||||
}
|
||||
var active = document.activeElement;
|
||||
|
||||
var ranges = [];
|
||||
for (var i = 0; i < selection.rangeCount; i++) {
|
||||
ranges.push(selection.getRangeAt(i));
|
||||
}
|
||||
|
||||
switch (active.tagName.toUpperCase()) { // .toUpperCase handles XHTML
|
||||
case 'INPUT':
|
||||
case 'TEXTAREA':
|
||||
active.blur();
|
||||
break;
|
||||
|
||||
default:
|
||||
active = null;
|
||||
break;
|
||||
}
|
||||
|
||||
selection.removeAllRanges();
|
||||
return function () {
|
||||
selection.type === 'Caret' &&
|
||||
selection.removeAllRanges();
|
||||
|
||||
if (!selection.rangeCount) {
|
||||
ranges.forEach(function(range) {
|
||||
selection.addRange(range);
|
||||
});
|
||||
}
|
||||
|
||||
active &&
|
||||
active.focus();
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
var clipboardToIE11Formatting = {
|
||||
"text/plain": "Text",
|
||||
"text/html": "Url",
|
||||
"default": "Text"
|
||||
}
|
||||
|
||||
var defaultMessage = "Copy to clipboard: #{key}, Enter";
|
||||
|
||||
function format(message) {
|
||||
var copyKey = (/mac os x/i.test(navigator.userAgent) ? "⌘" : "Ctrl") + "+C";
|
||||
return message.replace(/#{\s*key\s*}/g, copyKey);
|
||||
}
|
||||
|
||||
export function copy(text, options) {
|
||||
var debug,
|
||||
message,
|
||||
reselectPrevious,
|
||||
range,
|
||||
selection,
|
||||
mark,
|
||||
success = false;
|
||||
if (!options) {
|
||||
options = {};
|
||||
}
|
||||
debug = options.debug || false;
|
||||
try {
|
||||
reselectPrevious = deselectCurrent();
|
||||
|
||||
range = document.createRange();
|
||||
selection = document.getSelection();
|
||||
|
||||
mark = document.createElement("span");
|
||||
mark.textContent = text;
|
||||
// reset user styles for span element
|
||||
mark.style.all = "unset";
|
||||
// prevents scrolling to the end of the page
|
||||
mark.style.position = "fixed";
|
||||
mark.style.top = 0;
|
||||
mark.style.clip = "rect(0, 0, 0, 0)";
|
||||
// used to preserve spaces and line breaks
|
||||
mark.style.whiteSpace = "pre";
|
||||
// do not inherit user-select (it may be `none`)
|
||||
mark.style.webkitUserSelect = "text";
|
||||
mark.style.MozUserSelect = "text";
|
||||
mark.style.msUserSelect = "text";
|
||||
mark.style.userSelect = "text";
|
||||
mark.addEventListener("copy", function(e) {
|
||||
e.stopPropagation();
|
||||
if (options.format) {
|
||||
e.preventDefault();
|
||||
if (typeof e.clipboardData === "undefined") { // IE 11
|
||||
debug && console.warn("unable to use e.clipboardData");
|
||||
debug && console.warn("trying IE specific stuff");
|
||||
window.clipboardData.clearData();
|
||||
var format = clipboardToIE11Formatting[options.format] || clipboardToIE11Formatting["default"]
|
||||
window.clipboardData.setData(format, text);
|
||||
} else { // all other browsers
|
||||
e.clipboardData.clearData();
|
||||
e.clipboardData.setData(options.format, text);
|
||||
}
|
||||
}
|
||||
if (options.onCopy) {
|
||||
e.preventDefault();
|
||||
options.onCopy(e.clipboardData);
|
||||
}
|
||||
});
|
||||
|
||||
document.body.appendChild(mark);
|
||||
|
||||
range.selectNodeContents(mark);
|
||||
selection.addRange(range);
|
||||
|
||||
var successful = document.execCommand("copy");
|
||||
if (!successful) {
|
||||
throw new Error("copy command was unsuccessful");
|
||||
}
|
||||
success = true;
|
||||
} catch (err) {
|
||||
debug && console.error("unable to copy using execCommand: ", err);
|
||||
debug && console.warn("trying IE specific stuff");
|
||||
try {
|
||||
window.clipboardData.setData(options.format || "text", text);
|
||||
options.onCopy && options.onCopy(window.clipboardData);
|
||||
success = true;
|
||||
} catch (err) {
|
||||
debug && console.error("unable to copy using clipboardData: ", err);
|
||||
debug && console.error("falling back to prompt");
|
||||
message = format("message" in options ? options.message : defaultMessage);
|
||||
window.prompt(message, text);
|
||||
}
|
||||
} finally {
|
||||
if (selection) {
|
||||
if (typeof selection.removeRange == "function") {
|
||||
selection.removeRange(range);
|
||||
} else {
|
||||
selection.removeAllRanges();
|
||||
}
|
||||
}
|
||||
|
||||
if (mark) {
|
||||
document.body.removeChild(mark);
|
||||
}
|
||||
reselectPrevious();
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
159
frontend/generated/jar-resources/datepickerConnector.js
Normal file
159
frontend/generated/jar-resources/datepickerConnector.js
Normal file
@ -0,0 +1,159 @@
|
||||
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';
|
||||
|
||||
(function () {
|
||||
const tryCatchWrapper = function (callback) {
|
||||
return window.Vaadin.Flow.tryCatchWrapper(callback, 'Vaadin Date Picker');
|
||||
};
|
||||
|
||||
window.Vaadin.Flow.datepickerConnector = {
|
||||
initLazy: (datepicker) =>
|
||||
tryCatchWrapper(function (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 locale setting(en-US).');
|
||||
return 'M/d/yyyy';
|
||||
}
|
||||
|
||||
// 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 locale setting(en-US).');
|
||||
return 'M/d/yyyy';
|
||||
}
|
||||
|
||||
return pattern;
|
||||
};
|
||||
|
||||
const createFormatterAndParser = tryCatchWrapper(function (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 isShortYearFormat(format) {
|
||||
if (format.includes('y')) {
|
||||
return !format.includes('yyy');
|
||||
}
|
||||
if (format.includes('Y')) {
|
||||
return !format.includes('YYY');
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function formatDate(dateParts) {
|
||||
const format = formats[0];
|
||||
const date = _parseDate(`${dateParts.year}-${dateParts.month + 1}-${dateParts.day}`);
|
||||
|
||||
return dateFnsFormat(date, format);
|
||||
}
|
||||
|
||||
function parseDate(dateString) {
|
||||
const referenceDate = _getReferenceDate();
|
||||
for (let format of formats) {
|
||||
// We first try to match the date with the shorter version.
|
||||
const shortYearFormat = getShortYearFormat(format);
|
||||
if (shortYearFormat) {
|
||||
const shortYearFormatDate = dateFnsParse(dateString, shortYearFormat, referenceDate);
|
||||
if (dateFnsIsValid(shortYearFormatDate)) {
|
||||
let yearValue = shortYearFormatDate.getFullYear();
|
||||
// The last parsed year 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.
|
||||
if (
|
||||
datepicker.$connector._lastParsedYear &&
|
||||
yearValue === datepicker.$connector._lastParsedYear % 100
|
||||
) {
|
||||
yearValue = datepicker.$connector._lastParsedYear;
|
||||
}
|
||||
return {
|
||||
day: shortYearFormatDate.getDate(),
|
||||
month: shortYearFormatDate.getMonth(),
|
||||
year: yearValue
|
||||
};
|
||||
}
|
||||
}
|
||||
const date = dateFnsParse(dateString, format, referenceDate);
|
||||
|
||||
if (dateFnsIsValid(date)) {
|
||||
let yearValue = date.getFullYear();
|
||||
if (
|
||||
datepicker.$connector._lastParsedYear &&
|
||||
yearValue % 100 === datepicker.$connector._lastParsedYear % 100 &&
|
||||
isShortYearFormat(format)
|
||||
) {
|
||||
yearValue = datepicker.$connector._lastParsedYear;
|
||||
} else {
|
||||
datepicker.$connector._lastParsedYear = yearValue;
|
||||
}
|
||||
return {
|
||||
day: date.getDate(),
|
||||
month: date.getMonth(),
|
||||
year: yearValue
|
||||
};
|
||||
}
|
||||
}
|
||||
datepicker.$connector._lastParsedYear = undefined;
|
||||
return false;
|
||||
}
|
||||
|
||||
return {
|
||||
formatDate: formatDate,
|
||||
parseDate: parseDate
|
||||
};
|
||||
});
|
||||
|
||||
function _getReferenceDate() {
|
||||
const { referenceDate } = datepicker.i18n;
|
||||
return referenceDate ? new Date(referenceDate.year, referenceDate.month - 1, referenceDate.day) : new Date();
|
||||
}
|
||||
|
||||
datepicker.$connector.updateI18n = tryCatchWrapper(function (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)
|
||||
};
|
||||
})();
|
38
frontend/generated/jar-resources/dialogConnector.js
Normal file
38
frontend/generated/jar-resources/dialogConnector.js
Normal file
@ -0,0 +1,38 @@
|
||||
(function () {
|
||||
function copyClassName(dialog) {
|
||||
const overlay = dialog.$.overlay;
|
||||
if (overlay) {
|
||||
overlay.className = dialog.className;
|
||||
}
|
||||
}
|
||||
|
||||
const observer = new MutationObserver((records) => {
|
||||
records.forEach((mutation) => {
|
||||
if (mutation.type === 'attributes' && mutation.attributeName === 'class') {
|
||||
copyClassName(mutation.target);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
window.Vaadin.Flow.dialogConnector = {
|
||||
initLazy: function (dialog) {
|
||||
if (dialog.$connector) {
|
||||
return;
|
||||
}
|
||||
dialog.$connector = {};
|
||||
|
||||
dialog.addEventListener('opened-changed', (e) => {
|
||||
if (e.detail.value) {
|
||||
copyClassName(dialog);
|
||||
}
|
||||
});
|
||||
|
||||
observer.observe(dialog, {
|
||||
attributes: true,
|
||||
attributeFilter: ['class']
|
||||
});
|
||||
|
||||
copyClassName(dialog);
|
||||
}
|
||||
};
|
||||
})();
|
1
frontend/generated/jar-resources/dndConnector-es6.js
Normal file
1
frontend/generated/jar-resources/dndConnector-es6.js
Normal file
@ -0,0 +1 @@
|
||||
import './dndConnector.js';
|
110
frontend/generated/jar-resources/dndConnector.js
Normal file
110
frontend/generated/jar-resources/dndConnector.js
Normal file
@ -0,0 +1,110 @@
|
||||
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 && 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, false);
|
||||
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');
|
||||
}
|
||||
},
|
||||
|
||||
__dragendListener: function (event) {
|
||||
event.currentTarget.classList.remove('v-dragged');
|
||||
},
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
};
|
155
frontend/generated/jar-resources/flow-component-renderer.js
Normal file
155
frontend/generated/jar-resources/flow-component-renderer.js
Normal file
@ -0,0 +1,155 @@
|
||||
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';
|
||||
|
||||
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.nodeid || !this.appid) {
|
||||
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);
|
1185
frontend/generated/jar-resources/gridConnector.js
Normal file
1185
frontend/generated/jar-resources/gridConnector.js
Normal file
File diff suppressed because it is too large
Load Diff
1
frontend/generated/jar-resources/index.d.ts
vendored
Normal file
1
frontend/generated/jar-resources/index.d.ts
vendored
Normal file
@ -0,0 +1 @@
|
||||
export * from './Flow';
|
2
frontend/generated/jar-resources/index.js
Normal file
2
frontend/generated/jar-resources/index.js
Normal file
@ -0,0 +1,2 @@
|
||||
export * from './Flow';
|
||||
//# sourceMappingURL=index.js.map
|
1
frontend/generated/jar-resources/index.js.map
Normal file
1
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"]}
|
166
frontend/generated/jar-resources/ironListConnector.js
Normal file
166
frontend/generated/jar-resources/ironListConnector.js
Normal file
@ -0,0 +1,166 @@
|
||||
import { Debouncer } from '@polymer/polymer/lib/utils/debounce.js';
|
||||
import { timeOut } from '@polymer/polymer/lib/utils/async.js';
|
||||
|
||||
window.Vaadin.Flow.ironListConnector = {
|
||||
initLazy: function (list) {
|
||||
// Check whether the connector was already initialized for the Iron list
|
||||
if (list.$connector) {
|
||||
return;
|
||||
}
|
||||
|
||||
const extraItemsBuffer = 20;
|
||||
|
||||
let lastRequestedRange = [0, 0];
|
||||
|
||||
list.$connector = {};
|
||||
list.$connector.placeholderItem = { __placeholder: true };
|
||||
|
||||
const updateRequestedItem = function () {
|
||||
/*
|
||||
* TODO Iron 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.
|
||||
*/
|
||||
let firstNeededItem = list._virtualStart;
|
||||
let lastNeededItem = list._virtualEnd;
|
||||
|
||||
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);
|
||||
}
|
||||
};
|
||||
|
||||
let requestDebounce;
|
||||
const scheduleUpdateRequest = function () {
|
||||
requestDebounce = Debouncer.debounce(requestDebounce, timeOut.after(10), updateRequestedItem);
|
||||
};
|
||||
|
||||
/*
|
||||
* Ensure all items that iron list will be looking at are actually defined.
|
||||
* If this is not done, the component will keep looking ahead through the
|
||||
* array until finding enough present items to render. In our case, that's
|
||||
* a really slow way of achieving nothing since the rest of the array is
|
||||
* empty.
|
||||
*/
|
||||
const originalAssign = list._assignModels;
|
||||
list._assignModels = function () {
|
||||
const tempItems = [];
|
||||
const start = list._virtualStart;
|
||||
const count = Math.min(list.items.length, list._physicalCount);
|
||||
for (let i = 0; i < count; i++) {
|
||||
if (list.items[start + i] === undefined) {
|
||||
tempItems.push(i);
|
||||
list.items[start + i] = list.$connector.placeholderItem;
|
||||
}
|
||||
}
|
||||
|
||||
originalAssign.apply(list, arguments);
|
||||
|
||||
/*
|
||||
* TODO: Keep track of placeholder items in the "active" range and
|
||||
* avoid deleting them so that the next pass will be faster. Instead,
|
||||
* the end of each pass should only delete placeholders that are no
|
||||
* longer needed.
|
||||
*/
|
||||
for (let i = 0; i < tempItems.length; i++) {
|
||||
delete list.items[start + tempItems[i]];
|
||||
}
|
||||
|
||||
/*
|
||||
* 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();
|
||||
};
|
||||
|
||||
list.items = [];
|
||||
|
||||
list.$connector.set = function (index, items) {
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
const itemsIndex = index + i;
|
||||
list.items[itemsIndex] = items[i];
|
||||
}
|
||||
// Do a full render since dirty detection for splices is broken
|
||||
list._render();
|
||||
};
|
||||
|
||||
list.$connector.updateData = function (items) {
|
||||
// Find the items by key inside the list update them
|
||||
const oldItems = list.items;
|
||||
const mapByKey = {};
|
||||
let leftToUpdate = items.length;
|
||||
|
||||
for (let i = 0; i < items.length; i++) {
|
||||
const item = items[i];
|
||||
mapByKey[item.key] = item;
|
||||
}
|
||||
|
||||
for (let i = 0; i < oldItems.length; i++) {
|
||||
const oldItem = oldItems[i];
|
||||
const newItem = mapByKey[oldItem.key];
|
||||
if (newItem) {
|
||||
list.items[i] = newItem;
|
||||
list.notifyPath('items.' + i);
|
||||
leftToUpdate--;
|
||||
if (leftToUpdate == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
list.$connector.clear = function (index, length) {
|
||||
for (let i = 0; i < length; i++) {
|
||||
const itemsIndex = index + i;
|
||||
delete list.items[itemsIndex];
|
||||
|
||||
// Most likely a no-op since the affected index isn't in view
|
||||
list.notifyPath('items.' + itemsIndex);
|
||||
}
|
||||
};
|
||||
|
||||
list.$connector.updateSize = function (newSize) {
|
||||
const delta = newSize - list.items.length;
|
||||
if (delta > 0) {
|
||||
list.items.length = newSize;
|
||||
|
||||
list.notifySplices('items', [
|
||||
{
|
||||
index: newSize - delta,
|
||||
removed: [],
|
||||
addedCount: delta,
|
||||
object: list.items,
|
||||
type: 'splice'
|
||||
}
|
||||
]);
|
||||
} else if (delta < 0) {
|
||||
const removed = list.items.slice(newSize, list.items.length);
|
||||
list.items.splice(newSize);
|
||||
list.notifySplices('items', [
|
||||
{
|
||||
index: newSize,
|
||||
removed: removed,
|
||||
addedCount: 0,
|
||||
object: list.items,
|
||||
type: 'splice'
|
||||
}
|
||||
]);
|
||||
}
|
||||
};
|
||||
|
||||
list.$connector.setPlaceholderItem = function (placeholderItem) {
|
||||
if (!placeholderItem) {
|
||||
placeholderItem = {};
|
||||
}
|
||||
placeholderItem.__placeholder = true;
|
||||
list.$connector.placeholderItem = placeholderItem;
|
||||
};
|
||||
}
|
||||
};
|
12
frontend/generated/jar-resources/ironListStyles.js
Normal file
12
frontend/generated/jar-resources/ironListStyles.js
Normal file
@ -0,0 +1,12 @@
|
||||
import '@polymer/polymer/lib/elements/custom-style.js';
|
||||
const $_documentContainer = document.createElement('template');
|
||||
|
||||
$_documentContainer.innerHTML = `<style>
|
||||
/* Fixes zero width in flex layouts */
|
||||
iron-list {
|
||||
flex: auto;
|
||||
align-self: stretch;
|
||||
}
|
||||
</style>`;
|
||||
|
||||
document.head.appendChild($_documentContainer.content);
|
108
frontend/generated/jar-resources/lit-renderer.ts
Normal file
108
frontend/generated/jar-resources/lit-renderer.ts
Normal file
@ -0,0 +1,108 @@
|
||||
/* eslint-disable no-restricted-syntax */
|
||||
/* eslint-disable max-params */
|
||||
import { html, render } from 'lit';
|
||||
|
||||
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,
|
||||
) => {
|
||||
// Dynamically created function that renders the templateExpression
|
||||
// inside the given root element using Lit
|
||||
const renderFunction = Function(`
|
||||
"use strict";
|
||||
|
||||
const [render, html, returnChannel] = arguments;
|
||||
|
||||
return (root, {item, index}, itemKey) => {
|
||||
${clientCallables
|
||||
.map((clientCallable) => {
|
||||
// Map all the client-callables as inline functions so they can be accessed from the template literal
|
||||
return `
|
||||
const ${clientCallable} = (...args) => {
|
||||
if (itemKey !== undefined) {
|
||||
returnChannel('${clientCallable}', itemKey, args[0] instanceof Event ? [] : [...args]);
|
||||
}
|
||||
}`;
|
||||
})
|
||||
.join('')}
|
||||
|
||||
render(html\`${templateExpression}\`, root)
|
||||
}
|
||||
`)(render, html, returnChannel);
|
||||
|
||||
const renderer: Renderer = (root, _, { index, item }) => {
|
||||
// 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_3_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, { index, 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;
|
||||
}
|
||||
};
|
40
frontend/generated/jar-resources/loginOverlayConnector.js
Normal file
40
frontend/generated/jar-resources/loginOverlayConnector.js
Normal file
@ -0,0 +1,40 @@
|
||||
(function () {
|
||||
function copyClassName(loginOverlay) {
|
||||
const overlayWrapper = loginOverlay.$.vaadinLoginOverlayWrapper;
|
||||
if (overlayWrapper) {
|
||||
overlayWrapper.className = loginOverlay.className;
|
||||
}
|
||||
}
|
||||
|
||||
const observer = new MutationObserver((records) => {
|
||||
records.forEach((mutation) => {
|
||||
if (mutation.type === 'attributes' && mutation.attributeName === 'class') {
|
||||
copyClassName(mutation.target);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
window.Vaadin.Flow.loginOverlayConnector = {
|
||||
initLazy: function (loginOverlay) {
|
||||
if (loginOverlay.$connector) {
|
||||
return;
|
||||
}
|
||||
|
||||
loginOverlay.$connector = {};
|
||||
|
||||
loginOverlay.addEventListener('opened-changed', (e) => {
|
||||
if (e.detail.value) {
|
||||
copyClassName(loginOverlay);
|
||||
}
|
||||
});
|
||||
|
||||
observer.observe(loginOverlay, {
|
||||
attributes: true,
|
||||
attributeFilter: ['class']
|
||||
});
|
||||
|
||||
// Copy initial class
|
||||
copyClassName(loginOverlay);
|
||||
}
|
||||
};
|
||||
})();
|
9
frontend/generated/jar-resources/lumo-includes.ts
Normal file
9
frontend/generated/jar-resources/lumo-includes.ts
Normal file
@ -0,0 +1,9 @@
|
||||
import { color } from '@vaadin/vaadin-lumo-styles/color.js';
|
||||
import { typography } from '@vaadin/vaadin-lumo-styles/typography.js';
|
||||
|
||||
const tpl = document.createElement('template');
|
||||
tpl.innerHTML = `<style>
|
||||
${color.cssText}
|
||||
${typography.cssText}
|
||||
</style>`;
|
||||
document.head.appendChild(tpl.content);
|
9
frontend/generated/jar-resources/material-includes.ts
Normal file
9
frontend/generated/jar-resources/material-includes.ts
Normal file
@ -0,0 +1,9 @@
|
||||
import { colorLight } from '@vaadin/vaadin-material-styles';
|
||||
import { typography } from '@vaadin/vaadin-material-styles';
|
||||
|
||||
const tpl = document.createElement('template');
|
||||
tpl.innerHTML = `<style>
|
||||
${colorLight.cssText}
|
||||
${typography.cssText}
|
||||
</style>`;
|
||||
document.head.appendChild(tpl.content);
|
111
frontend/generated/jar-resources/menubarConnector.js
Normal file
111
frontend/generated/jar-resources/menubarConnector.js
Normal file
@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright 2000-2022 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';
|
||||
|
||||
(function () {
|
||||
const tryCatchWrapper = function (callback) {
|
||||
return window.Vaadin.Flow.tryCatchWrapper(callback, 'Vaadin Menu Bar');
|
||||
};
|
||||
|
||||
/**
|
||||
* 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: tryCatchWrapper((nodeId) => {
|
||||
if (!menubar.shadowRoot) {
|
||||
// workaround for https://github.com/vaadin/flow/issues/5722
|
||||
setTimeout(() => menubar.$connector.generateItems(nodeId));
|
||||
return;
|
||||
}
|
||||
|
||||
if (nodeId) {
|
||||
menubar.__generatedItems = window.Vaadin.Flow.contextMenuConnector.generateItemsTree(appId, nodeId);
|
||||
}
|
||||
|
||||
let items = menubar.__generatedItems || [];
|
||||
|
||||
// Propagate disabled state from items to parent buttons
|
||||
items.forEach((item) => (item.disabled = item.component.disabled));
|
||||
|
||||
// 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);
|
||||
|
||||
// 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
|
||||
});
|
||||
});
|
||||
|
||||
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();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
})
|
||||
};
|
||||
}
|
||||
|
||||
window.Vaadin.Flow.menubarConnector = {
|
||||
initLazy(...args) {
|
||||
return tryCatchWrapper(initLazy)(...args);
|
||||
}
|
||||
};
|
||||
})();
|
41
frontend/generated/jar-resources/messageListConnector.js
Normal file
41
frontend/generated/jar-resources/messageListConnector.js
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2000-2022 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.
|
||||
*/
|
||||
|
||||
(function () {
|
||||
const tryCatchWrapper = function (callback) {
|
||||
return window.Vaadin.Flow.tryCatchWrapper(callback, 'Vaadin Message List');
|
||||
};
|
||||
|
||||
window.Vaadin.Flow.messageListConnector = {
|
||||
setItems: (list, items, locale) =>
|
||||
tryCatchWrapper(function (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
|
||||
);
|
||||
})(list, items, locale)
|
||||
};
|
||||
})();
|
38
frontend/generated/jar-resources/notificationConnector.js
Normal file
38
frontend/generated/jar-resources/notificationConnector.js
Normal file
@ -0,0 +1,38 @@
|
||||
(function () {
|
||||
function copyClassName(notification) {
|
||||
const card = notification._card;
|
||||
if (card) {
|
||||
card.className = notification.className;
|
||||
}
|
||||
}
|
||||
|
||||
const observer = new MutationObserver((records) => {
|
||||
records.forEach((mutation) => {
|
||||
if (mutation.type === 'attributes' && mutation.attributeName === 'class') {
|
||||
copyClassName(mutation.target);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
window.Vaadin.Flow.notificationConnector = {
|
||||
initLazy: function (notification) {
|
||||
if (notification.$connector) {
|
||||
return;
|
||||
}
|
||||
notification.$connector = {};
|
||||
|
||||
notification.addEventListener('opened-changed', (e) => {
|
||||
if (e.detail.value) {
|
||||
copyClassName(notification);
|
||||
}
|
||||
});
|
||||
|
||||
observer.observe(notification, {
|
||||
attributes: true,
|
||||
attributeFilter: ['class']
|
||||
});
|
||||
|
||||
copyClassName(notification);
|
||||
}
|
||||
};
|
||||
})();
|
36
frontend/generated/jar-resources/selectConnector.js
Normal file
36
frontend/generated/jar-resources/selectConnector.js
Normal file
@ -0,0 +1,36 @@
|
||||
(function () {
|
||||
const tryCatchWrapper = function (callback) {
|
||||
return window.Vaadin.Flow.tryCatchWrapper(callback, 'Vaadin Select');
|
||||
};
|
||||
|
||||
window.Vaadin.Flow.selectConnector = {
|
||||
initLazy: (select) =>
|
||||
tryCatchWrapper(function (select) {
|
||||
const _findListBoxElement = tryCatchWrapper(function () {
|
||||
for (let i = 0; i < select.childElementCount; i++) {
|
||||
const child = select.children[i];
|
||||
if ('VAADIN-SELECT-LIST-BOX' === child.tagName.toUpperCase()) {
|
||||
return child;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// do not init this connector twice for the given select
|
||||
if (select.$connector) {
|
||||
return;
|
||||
}
|
||||
|
||||
select.$connector = {};
|
||||
|
||||
select.renderer = tryCatchWrapper(function (root) {
|
||||
const listBox = _findListBoxElement();
|
||||
if (listBox) {
|
||||
if (root.firstChild) {
|
||||
root.removeChild(root.firstChild);
|
||||
}
|
||||
root.appendChild(listBox);
|
||||
}
|
||||
});
|
||||
})(select)
|
||||
};
|
||||
})();
|
11
frontend/generated/jar-resources/tooltip.ts
Normal file
11
frontend/generated/jar-resources/tooltip.ts
Normal file
@ -0,0 +1,11 @@
|
||||
import { Tooltip } from '@vaadin/tooltip';
|
||||
|
||||
const _window = window as any;
|
||||
_window.Vaadin = _window.Vaadin || {};
|
||||
_window.Vaadin.Flow = _window.Vaadin.Flow || {};
|
||||
|
||||
_window.Vaadin.Flow.tooltip = {
|
||||
setDefaultHideDelay: (hideDelay: number) => Tooltip.setDefaultHideDelay(hideDelay),
|
||||
setDefaultFocusDelay: (focusDelay: number) => Tooltip.setDefaultFocusDelay(focusDelay),
|
||||
setDefaultHoverDelay: (hoverDelay: number) => Tooltip.setDefaultHoverDelay(hoverDelay),
|
||||
}
|
77
frontend/generated/jar-resources/vaadin-big-decimal-field.js
Normal file
77
frontend/generated/jar-resources/vaadin-big-decimal-field.js
Normal file
@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright 2000-2022 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.
|
||||
*/
|
||||
(function() {
|
||||
|
||||
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);
|
||||
|
||||
});
|
||||
})();
|
119
frontend/generated/jar-resources/vaadin-dev-tools.d.ts
vendored
Normal file
119
frontend/generated/jar-resources/vaadin-dev-tools.d.ts
vendored
Normal file
@ -0,0 +1,119 @@
|
||||
import { LitElement } from 'lit';
|
||||
import { Product } from './License';
|
||||
interface Feature {
|
||||
id: string;
|
||||
title: string;
|
||||
moreInfoLink: string;
|
||||
requiresServerRestart: boolean;
|
||||
enabled: boolean;
|
||||
}
|
||||
declare enum ConnectionStatus {
|
||||
ACTIVE = "active",
|
||||
INACTIVE = "inactive",
|
||||
UNAVAILABLE = "unavailable",
|
||||
ERROR = "error"
|
||||
}
|
||||
export declare class Connection extends Object {
|
||||
static HEARTBEAT_INTERVAL: number;
|
||||
status: ConnectionStatus;
|
||||
webSocket?: WebSocket;
|
||||
constructor(url?: string);
|
||||
onHandshake(): void;
|
||||
onReload(): void;
|
||||
onConnectionError(_: string): void;
|
||||
onStatusChange(_: ConnectionStatus): void;
|
||||
onMessage(message: any): void;
|
||||
handleMessage(msg: any): void;
|
||||
handleError(msg: any): void;
|
||||
setActive(yes: boolean): void;
|
||||
setStatus(status: ConnectionStatus): void;
|
||||
private send;
|
||||
setFeature(featureId: string, enabled: boolean): void;
|
||||
sendTelemetry(browserData: any): void;
|
||||
sendLicenseCheck(product: Product): void;
|
||||
}
|
||||
declare enum MessageType {
|
||||
LOG = "log",
|
||||
INFORMATION = "information",
|
||||
WARNING = "warning",
|
||||
ERROR = "error"
|
||||
}
|
||||
interface Message {
|
||||
id: number;
|
||||
type: MessageType;
|
||||
message: string;
|
||||
details?: string;
|
||||
link?: string;
|
||||
persistentId?: string;
|
||||
dontShowAgain: boolean;
|
||||
deleted: boolean;
|
||||
}
|
||||
export declare class VaadinDevTools extends LitElement {
|
||||
static BLUE_HSL: import("lit").CSSResult;
|
||||
static GREEN_HSL: import("lit").CSSResult;
|
||||
static GREY_HSL: import("lit").CSSResult;
|
||||
static YELLOW_HSL: import("lit").CSSResult;
|
||||
static RED_HSL: import("lit").CSSResult;
|
||||
static MAX_LOG_ROWS: number;
|
||||
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;
|
||||
static notificationDismissed(persistentId: string): boolean;
|
||||
url?: string;
|
||||
liveReloadDisabled?: boolean;
|
||||
backend?: string;
|
||||
springBootLiveReloadPort?: number;
|
||||
expanded: boolean;
|
||||
messages: Message[];
|
||||
splashMessage?: string;
|
||||
notifications: Message[];
|
||||
frontendStatus: ConnectionStatus;
|
||||
javaStatus: ConnectionStatus;
|
||||
private tabs;
|
||||
private activeTab;
|
||||
private serverInfo;
|
||||
private features;
|
||||
private unreadErrors;
|
||||
private root;
|
||||
private javaConnection?;
|
||||
private frontendConnection?;
|
||||
private nextMessageId;
|
||||
private disableEventListener?;
|
||||
private transitionDuration;
|
||||
elementTelemetry(): void;
|
||||
openWebSocketConnection(): void;
|
||||
getDedicatedWebSocketUrl(): string | undefined;
|
||||
getSpringBootWebSocketUrl(location: any): string;
|
||||
connectedCallback(): void;
|
||||
format(o: any): string;
|
||||
catchErrors(): void;
|
||||
disconnectedCallback(): void;
|
||||
toggleExpanded(): void;
|
||||
showSplashMessage(msg: string | undefined): void;
|
||||
demoteSplashMessage(): void;
|
||||
checkLicense(productInfo: Product): void;
|
||||
log(type: MessageType, message: string, details?: string, link?: string): void;
|
||||
showNotification(type: MessageType, message: string, details?: string, link?: string, persistentId?: string): void;
|
||||
dismissNotification(id: number): void;
|
||||
findNotificationIndex(id: number): number;
|
||||
toggleDontShowAgain(id: number): void;
|
||||
setActive(yes: boolean): void;
|
||||
getStatusColor(status: ConnectionStatus | undefined): import("lit").CSSResult;
|
||||
renderMessage(messageObject: Message): import("lit-html").TemplateResult<1>;
|
||||
render(): import("lit-html").TemplateResult<1>;
|
||||
renderLog(): import("lit-html").TemplateResult<1>;
|
||||
activateLog(): void;
|
||||
renderInfo(): import("lit-html").TemplateResult<1>;
|
||||
private renderFeatures;
|
||||
copyInfoToClipboard(): void;
|
||||
toggleFeatureFlag(e: Event, feature: Feature): void;
|
||||
}
|
||||
export {};
|
1477
frontend/generated/jar-resources/vaadin-dev-tools.js
Normal file
1477
frontend/generated/jar-resources/vaadin-dev-tools.js
Normal file
File diff suppressed because it is too large
Load Diff
1
frontend/generated/jar-resources/vaadin-dev-tools.js.map
Normal file
1
frontend/generated/jar-resources/vaadin-dev-tools.js.map
Normal file
File diff suppressed because one or more lines are too long
@ -0,0 +1,156 @@
|
||||
import '@vaadin/grid/vaadin-grid-column.js';
|
||||
import { GridColumn } from '@vaadin/grid/src/vaadin-grid-column.js';
|
||||
{
|
||||
class GridFlowSelectionColumnElement extends GridColumn {
|
||||
|
||||
static get is() {
|
||||
return 'vaadin-grid-flow-selection-column';
|
||||
}
|
||||
|
||||
static get properties() {
|
||||
return {
|
||||
|
||||
/**
|
||||
* Automatically sets the width of the column based on the column contents when this is set to `true`.
|
||||
*/
|
||||
autoWidth: {
|
||||
type: Boolean,
|
||||
value: true
|
||||
},
|
||||
|
||||
/**
|
||||
* Width of the cells for this column.
|
||||
*/
|
||||
width: {
|
||||
type: String,
|
||||
value: '56px'
|
||||
},
|
||||
|
||||
/**
|
||||
* Flex grow ratio for the cell widths. When set to 0, cell width is fixed.
|
||||
*/
|
||||
flexGrow: {
|
||||
type: Number,
|
||||
value: 0
|
||||
},
|
||||
|
||||
/**
|
||||
* When true, all the items are selected.
|
||||
*/
|
||||
selectAll: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
notify: true
|
||||
},
|
||||
|
||||
/**
|
||||
* Whether to display the select all checkbox in indeterminate state,
|
||||
* which means some, but not all, items are selected
|
||||
*/
|
||||
indeterminate: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
notify: true
|
||||
},
|
||||
|
||||
selectAllHidden: Boolean
|
||||
};
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this._boundOnSelectEvent = this._onSelectEvent.bind(this);
|
||||
this._boundOnDeselectEvent = this._onDeselectEvent.bind(this);
|
||||
}
|
||||
|
||||
static get observers() {
|
||||
return [
|
||||
'_onHeaderRendererOrBindingChanged(_headerRenderer, _headerCell, path, header, selectAll, indeterminate, selectAllHidden)'
|
||||
];
|
||||
}
|
||||
|
||||
/** @private */
|
||||
connectedCallback() {
|
||||
super.connectedCallback();
|
||||
if (this._grid) {
|
||||
this._grid.addEventListener('select', this._boundOnSelectEvent);
|
||||
this._grid.addEventListener('deselect', this._boundOnDeselectEvent);
|
||||
}
|
||||
}
|
||||
|
||||
/** @private */
|
||||
disconnectedCallback() {
|
||||
super.disconnectedCallback();
|
||||
if (this._grid) {
|
||||
this._grid.removeEventListener('select', this._boundOnSelectEvent);
|
||||
this._grid.removeEventListener('deselect', this._boundOnDeselectEvent);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the Select All checkbox to the header cell.
|
||||
*
|
||||
* @override
|
||||
*/
|
||||
_defaultHeaderRenderer(root, _column) {
|
||||
let checkbox = root.firstElementChild;
|
||||
if (!checkbox) {
|
||||
checkbox = document.createElement('vaadin-checkbox');
|
||||
checkbox.id = 'selectAllCheckbox';
|
||||
checkbox.setAttribute('aria-label', 'Select All');
|
||||
checkbox.classList.add('vaadin-grid-select-all-checkbox');
|
||||
checkbox.addEventListener('click', this._onSelectAllClick.bind(this));
|
||||
root.appendChild(checkbox);
|
||||
}
|
||||
|
||||
const checked = this.selectAll;
|
||||
checkbox.hidden = this.selectAllHidden;
|
||||
checkbox.checked = checked;
|
||||
checkbox.indeterminate = this.indeterminate;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renders the Select Row checkbox to the body cell.
|
||||
*
|
||||
* @override
|
||||
*/
|
||||
_defaultRenderer(root, _column, { item, selected }) {
|
||||
let checkbox = root.firstElementChild;
|
||||
if (!checkbox) {
|
||||
checkbox = document.createElement('vaadin-checkbox');
|
||||
checkbox.setAttribute('aria-label', 'Select Row');
|
||||
checkbox.addEventListener('click', this._onSelectClick.bind(this));
|
||||
root.appendChild(checkbox);
|
||||
}
|
||||
|
||||
checkbox.__item = item;
|
||||
checkbox.checked = selected;
|
||||
}
|
||||
|
||||
_onSelectClick(e) {
|
||||
e.currentTarget.checked ? this._grid.$connector.doDeselection([e.currentTarget.__item], true) : this._grid.$connector.doSelection([e.currentTarget.__item], true);
|
||||
}
|
||||
|
||||
_onSelectAllClick(e) {
|
||||
e.preventDefault();
|
||||
if (this._grid.hasAttribute('disabled')) {
|
||||
e.currentTarget.checked = !e.currentTarget.checked;
|
||||
return;
|
||||
}
|
||||
this.selectAll ? this.$server.deselectAll() : this.$server.selectAll();
|
||||
}
|
||||
|
||||
_onSelectEvent(e) {
|
||||
}
|
||||
|
||||
_onDeselectEvent(e) {
|
||||
if (e.detail.userOriginated) {
|
||||
this.selectAll = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define(GridFlowSelectionColumnElement.is, GridFlowSelectionColumnElement);
|
||||
|
||||
Vaadin.GridFlowSelectionColumnElement = GridFlowSelectionColumnElement;
|
||||
}
|
183
frontend/generated/jar-resources/vaadin-time-picker/helpers.js
Normal file
183
frontend/generated/jar-resources/vaadin-time-picker/helpers.js
Normal file
@ -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,178 @@
|
||||
import {
|
||||
TEST_PM_TIME,
|
||||
formatMilliseconds,
|
||||
parseMillisecondsIntoInteger,
|
||||
parseDigitsIntoInteger,
|
||||
getAmString,
|
||||
getPmString,
|
||||
getSeparator,
|
||||
searchAmOrPmToken
|
||||
} from './helpers.js';
|
||||
|
||||
(function () {
|
||||
const tryCatchWrapper = function (callback) {
|
||||
return window.Vaadin.Flow.tryCatchWrapper(callback, 'Vaadin Time Picker');
|
||||
};
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
window.Vaadin.Flow.timepickerConnector = {
|
||||
initLazy: (timepicker) =>
|
||||
tryCatchWrapper(function (timepicker) {
|
||||
// Check whether the connector was already initialized for the timepicker
|
||||
if (timepicker.$connector) {
|
||||
return;
|
||||
}
|
||||
|
||||
timepicker.$connector = {};
|
||||
|
||||
timepicker.$connector.setLocale = tryCatchWrapper(function (locale) {
|
||||
// capture previous value if any
|
||||
let previousValueObject;
|
||||
if (timepicker.value && timepicker.value !== '') {
|
||||
previousValueObject = timepicker.i18n.parseTime(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: tryCatchWrapper(function (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: tryCatchWrapper(function (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;
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
});
|
||||
})(timepicker)
|
||||
};
|
||||
})();
|
130
frontend/generated/jar-resources/virtualListConnector.js
Normal file
130
frontend/generated/jar-resources/virtualListConnector.js
Normal file
@ -0,0 +1,130 @@
|
||||
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) {
|
||||
originalRenderer.call(list, root, list, {
|
||||
...model,
|
||||
item: list.$connector.placeholderItem
|
||||
});
|
||||
} else {
|
||||
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 = {}) {
|
||||
placeholderItem.__placeholder = true;
|
||||
list.$connector.placeholderItem = placeholderItem;
|
||||
};
|
||||
}
|
||||
};
|
11
frontend/generated/vaadin-featureflags.ts
Normal file
11
frontend/generated/vaadin-featureflags.ts
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.hillaPush = false;
|
||||
window.Vaadin.featureFlags.hillaEngine = false;
|
||||
window.Vaadin.featureFlags.oldLicenseChecker = false;
|
||||
window.Vaadin.featureFlags.collaborationEngineBackend = false;
|
||||
window.Vaadin.featureFlags.webpackForFrontendBuild = false;
|
||||
window.Vaadin.featureFlags.enforceFieldValidation = false;
|
||||
export {};
|
5
frontend/generated/vaadin.ts
Normal file
5
frontend/generated/vaadin.ts
Normal file
@ -0,0 +1,5 @@
|
||||
import './vaadin-featureflags.ts';
|
||||
|
||||
import './index';
|
||||
|
||||
import 'Frontend/generated/jar-resources/vaadin-dev-tools.js';
|
31
frontend/generated/vite-devmode.ts
Normal file
31
frontend/generated/vite-devmode.ts
Normal file
@ -0,0 +1,31 @@
|
||||
// @ts-ignore
|
||||
if (import.meta.hot) {
|
||||
// @ts-ignore
|
||||
const hot = import.meta.hot;
|
||||
|
||||
const isLiveReloadDisabled = () => {
|
||||
// Checks if live reload is disabled in the debug window
|
||||
return sessionStorage.getItem('vaadin.live-reload.active') === 'false';
|
||||
};
|
||||
|
||||
const preventViteReload = (payload: any) => {
|
||||
// Changing the path prevents Vite from reloading
|
||||
payload.path = '/_fake/path.html';
|
||||
};
|
||||
|
||||
let pendingNavigationTo: string | undefined = undefined;
|
||||
|
||||
window.addEventListener('vaadin-router-go', (routerEvent: any) => {
|
||||
pendingNavigationTo = routerEvent.detail.pathname + routerEvent.detail.search;
|
||||
});
|
||||
hot.on('vite:beforeFullReload', (payload: any) => {
|
||||
if (isLiveReloadDisabled()) {
|
||||
preventViteReload(payload);
|
||||
}
|
||||
if (pendingNavigationTo) {
|
||||
// Force reload with the new URL
|
||||
location.href = pendingNavigationTo;
|
||||
preventViteReload(payload);
|
||||
}
|
||||
});
|
||||
}
|
23
frontend/index.html
Normal file
23
frontend/index.html
Normal file
@ -0,0 +1,23 @@
|
||||
<!DOCTYPE html>
|
||||
<!--
|
||||
This file is auto-generated by Vaadin.
|
||||
-->
|
||||
|
||||
<html lang="en">
|
||||
<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>
|
316
mvnw
vendored
Normal file
316
mvnw
vendored
Normal file
@ -0,0 +1,316 @@
|
||||
#!/bin/sh
|
||||
# ----------------------------------------------------------------------------
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you 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.
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# Maven Start Up Batch script
|
||||
#
|
||||
# Required ENV vars:
|
||||
# ------------------
|
||||
# JAVA_HOME - location of a JDK home dir
|
||||
#
|
||||
# Optional ENV vars
|
||||
# -----------------
|
||||
# M2_HOME - location of maven2's installed home dir
|
||||
# MAVEN_OPTS - parameters passed to the Java VM when running Maven
|
||||
# e.g. to debug Maven itself, use
|
||||
# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
|
||||
# MAVEN_SKIP_RC - flag to disable loading of mavenrc files
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
if [ -z "$MAVEN_SKIP_RC" ] ; then
|
||||
|
||||
if [ -f /usr/local/etc/mavenrc ] ; then
|
||||
. /usr/local/etc/mavenrc
|
||||
fi
|
||||
|
||||
if [ -f /etc/mavenrc ] ; then
|
||||
. /etc/mavenrc
|
||||
fi
|
||||
|
||||
if [ -f "$HOME/.mavenrc" ] ; then
|
||||
. "$HOME/.mavenrc"
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
# OS specific support. $var _must_ be set to either true or false.
|
||||
cygwin=false;
|
||||
darwin=false;
|
||||
mingw=false
|
||||
case "`uname`" in
|
||||
CYGWIN*) cygwin=true ;;
|
||||
MINGW*) mingw=true;;
|
||||
Darwin*) darwin=true
|
||||
# Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
|
||||
# See https://developer.apple.com/library/mac/qa/qa1170/_index.html
|
||||
if [ -z "$JAVA_HOME" ]; then
|
||||
if [ -x "/usr/libexec/java_home" ]; then
|
||||
export JAVA_HOME="`/usr/libexec/java_home`"
|
||||
else
|
||||
export JAVA_HOME="/Library/Java/Home"
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -z "$JAVA_HOME" ] ; then
|
||||
if [ -r /etc/gentoo-release ] ; then
|
||||
JAVA_HOME=`java-config --jre-home`
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "$M2_HOME" ] ; then
|
||||
## resolve links - $0 may be a link to maven's home
|
||||
PRG="$0"
|
||||
|
||||
# need this for relative symlinks
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG="`dirname "$PRG"`/$link"
|
||||
fi
|
||||
done
|
||||
|
||||
saveddir=`pwd`
|
||||
|
||||
M2_HOME=`dirname "$PRG"`/..
|
||||
|
||||
# make it fully qualified
|
||||
M2_HOME=`cd "$M2_HOME" && pwd`
|
||||
|
||||
cd "$saveddir"
|
||||
# echo Using m2 at $M2_HOME
|
||||
fi
|
||||
|
||||
# For Cygwin, ensure paths are in UNIX format before anything is touched
|
||||
if $cygwin ; then
|
||||
[ -n "$M2_HOME" ] &&
|
||||
M2_HOME=`cygpath --unix "$M2_HOME"`
|
||||
[ -n "$JAVA_HOME" ] &&
|
||||
JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
|
||||
[ -n "$CLASSPATH" ] &&
|
||||
CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
|
||||
fi
|
||||
|
||||
# For Mingw, ensure paths are in UNIX format before anything is touched
|
||||
if $mingw ; then
|
||||
[ -n "$M2_HOME" ] &&
|
||||
M2_HOME="`(cd "$M2_HOME"; pwd)`"
|
||||
[ -n "$JAVA_HOME" ] &&
|
||||
JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
|
||||
fi
|
||||
|
||||
if [ -z "$JAVA_HOME" ]; then
|
||||
javaExecutable="`which javac`"
|
||||
if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
|
||||
# readlink(1) is not available as standard on Solaris 10.
|
||||
readLink=`which readlink`
|
||||
if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
|
||||
if $darwin ; then
|
||||
javaHome="`dirname \"$javaExecutable\"`"
|
||||
javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
|
||||
else
|
||||
javaExecutable="`readlink -f \"$javaExecutable\"`"
|
||||
fi
|
||||
javaHome="`dirname \"$javaExecutable\"`"
|
||||
javaHome=`expr "$javaHome" : '\(.*\)/bin'`
|
||||
JAVA_HOME="$javaHome"
|
||||
export JAVA_HOME
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "$JAVACMD" ] ; then
|
||||
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
|
||||
else
|
||||
JAVACMD="`\\unset -f command; \\command -v java`"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
echo "Error: JAVA_HOME is not defined correctly." >&2
|
||||
echo " We cannot execute $JAVACMD" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$JAVA_HOME" ] ; then
|
||||
echo "Warning: JAVA_HOME environment variable is not set."
|
||||
fi
|
||||
|
||||
CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
|
||||
|
||||
# traverses directory structure from process work directory to filesystem root
|
||||
# first directory with .mvn subdirectory is considered project base directory
|
||||
find_maven_basedir() {
|
||||
|
||||
if [ -z "$1" ]
|
||||
then
|
||||
echo "Path not specified to find_maven_basedir"
|
||||
return 1
|
||||
fi
|
||||
|
||||
basedir="$1"
|
||||
wdir="$1"
|
||||
while [ "$wdir" != '/' ] ; do
|
||||
if [ -d "$wdir"/.mvn ] ; then
|
||||
basedir=$wdir
|
||||
break
|
||||
fi
|
||||
# workaround for JBEAP-8937 (on Solaris 10/Sparc)
|
||||
if [ -d "${wdir}" ]; then
|
||||
wdir=`cd "$wdir/.."; pwd`
|
||||
fi
|
||||
# end of workaround
|
||||
done
|
||||
echo "${basedir}"
|
||||
}
|
||||
|
||||
# concatenates all lines of a file
|
||||
concat_lines() {
|
||||
if [ -f "$1" ]; then
|
||||
echo "$(tr -s '\n' ' ' < "$1")"
|
||||
fi
|
||||
}
|
||||
|
||||
BASE_DIR=`find_maven_basedir "$(pwd)"`
|
||||
if [ -z "$BASE_DIR" ]; then
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
##########################################################################################
|
||||
# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
|
||||
# This allows using the maven wrapper in projects that prohibit checking in binary data.
|
||||
##########################################################################################
|
||||
if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo "Found .mvn/wrapper/maven-wrapper.jar"
|
||||
fi
|
||||
else
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..."
|
||||
fi
|
||||
if [ -n "$MVNW_REPOURL" ]; then
|
||||
jarUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
|
||||
else
|
||||
jarUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
|
||||
fi
|
||||
while IFS="=" read key value; do
|
||||
case "$key" in (wrapperUrl) jarUrl="$value"; break ;;
|
||||
esac
|
||||
done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties"
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo "Downloading from: $jarUrl"
|
||||
fi
|
||||
wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar"
|
||||
if $cygwin; then
|
||||
wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"`
|
||||
fi
|
||||
|
||||
if command -v wget > /dev/null; then
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo "Found wget ... using wget"
|
||||
fi
|
||||
if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
|
||||
wget "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
|
||||
else
|
||||
wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
|
||||
fi
|
||||
elif command -v curl > /dev/null; then
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo "Found curl ... using curl"
|
||||
fi
|
||||
if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
|
||||
curl -o "$wrapperJarPath" "$jarUrl" -f
|
||||
else
|
||||
curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f
|
||||
fi
|
||||
|
||||
else
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo "Falling back to using Java to download"
|
||||
fi
|
||||
javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
|
||||
# For Cygwin, switch paths to Windows format before running javac
|
||||
if $cygwin; then
|
||||
javaClass=`cygpath --path --windows "$javaClass"`
|
||||
fi
|
||||
if [ -e "$javaClass" ]; then
|
||||
if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo " - Compiling MavenWrapperDownloader.java ..."
|
||||
fi
|
||||
# Compiling the Java class
|
||||
("$JAVA_HOME/bin/javac" "$javaClass")
|
||||
fi
|
||||
if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
|
||||
# Running the downloader
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo " - Running MavenWrapperDownloader.java ..."
|
||||
fi
|
||||
("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR")
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
##########################################################################################
|
||||
# End of extension
|
||||
##########################################################################################
|
||||
|
||||
export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo $MAVEN_PROJECTBASEDIR
|
||||
fi
|
||||
MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
|
||||
|
||||
# For Cygwin, switch paths to Windows format before running java
|
||||
if $cygwin; then
|
||||
[ -n "$M2_HOME" ] &&
|
||||
M2_HOME=`cygpath --path --windows "$M2_HOME"`
|
||||
[ -n "$JAVA_HOME" ] &&
|
||||
JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
|
||||
[ -n "$CLASSPATH" ] &&
|
||||
CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
|
||||
[ -n "$MAVEN_PROJECTBASEDIR" ] &&
|
||||
MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
|
||||
fi
|
||||
|
||||
# Provide a "standardized" way to retrieve the CLI args that will
|
||||
# work with both Windows and non-Windows executions.
|
||||
MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@"
|
||||
export MAVEN_CMD_LINE_ARGS
|
||||
|
||||
WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
|
||||
|
||||
exec "$JAVACMD" \
|
||||
$MAVEN_OPTS \
|
||||
$MAVEN_DEBUG_OPTS \
|
||||
-classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
|
||||
"-Dmaven.home=${M2_HOME}" \
|
||||
"-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
|
||||
${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
|
188
mvnw.cmd
vendored
Normal file
188
mvnw.cmd
vendored
Normal file
@ -0,0 +1,188 @@
|
||||
@REM ----------------------------------------------------------------------------
|
||||
@REM Licensed to the Apache Software Foundation (ASF) under one
|
||||
@REM or more contributor license agreements. See the NOTICE file
|
||||
@REM distributed with this work for additional information
|
||||
@REM regarding copyright ownership. The ASF licenses this file
|
||||
@REM to you under the Apache License, Version 2.0 (the
|
||||
@REM "License"); you may not use this file except in compliance
|
||||
@REM with the License. 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,
|
||||
@REM software distributed under the License is distributed on an
|
||||
@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
@REM KIND, either express or implied. See the License for the
|
||||
@REM specific language governing permissions and limitations
|
||||
@REM under the License.
|
||||
@REM ----------------------------------------------------------------------------
|
||||
|
||||
@REM ----------------------------------------------------------------------------
|
||||
@REM Maven Start Up Batch script
|
||||
@REM
|
||||
@REM Required ENV vars:
|
||||
@REM JAVA_HOME - location of a JDK home dir
|
||||
@REM
|
||||
@REM Optional ENV vars
|
||||
@REM M2_HOME - location of maven2's installed home dir
|
||||
@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
|
||||
@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending
|
||||
@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
|
||||
@REM e.g. to debug Maven itself, use
|
||||
@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
|
||||
@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
|
||||
@REM ----------------------------------------------------------------------------
|
||||
|
||||
@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
|
||||
@echo off
|
||||
@REM set title of command window
|
||||
title %0
|
||||
@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'
|
||||
@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
|
||||
|
||||
@REM set %HOME% to equivalent of $HOME
|
||||
if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
|
||||
|
||||
@REM Execute a user defined script before this one
|
||||
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
|
||||
@REM check for pre script, once with legacy .bat ending and once with .cmd ending
|
||||
if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %*
|
||||
if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %*
|
||||
:skipRcPre
|
||||
|
||||
@setlocal
|
||||
|
||||
set ERROR_CODE=0
|
||||
|
||||
@REM To isolate internal variables from possible post scripts, we use another setlocal
|
||||
@setlocal
|
||||
|
||||
@REM ==== START VALIDATION ====
|
||||
if not "%JAVA_HOME%" == "" goto OkJHome
|
||||
|
||||
echo.
|
||||
echo Error: JAVA_HOME not found in your environment. >&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the >&2
|
||||
echo location of your Java installation. >&2
|
||||
echo.
|
||||
goto error
|
||||
|
||||
:OkJHome
|
||||
if exist "%JAVA_HOME%\bin\java.exe" goto init
|
||||
|
||||
echo.
|
||||
echo Error: JAVA_HOME is set to an invalid directory. >&2
|
||||
echo JAVA_HOME = "%JAVA_HOME%" >&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the >&2
|
||||
echo location of your Java installation. >&2
|
||||
echo.
|
||||
goto error
|
||||
|
||||
@REM ==== END VALIDATION ====
|
||||
|
||||
:init
|
||||
|
||||
@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
|
||||
@REM Fallback to current working directory if not found.
|
||||
|
||||
set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
|
||||
IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
|
||||
|
||||
set EXEC_DIR=%CD%
|
||||
set WDIR=%EXEC_DIR%
|
||||
:findBaseDir
|
||||
IF EXIST "%WDIR%"\.mvn goto baseDirFound
|
||||
cd ..
|
||||
IF "%WDIR%"=="%CD%" goto baseDirNotFound
|
||||
set WDIR=%CD%
|
||||
goto findBaseDir
|
||||
|
||||
:baseDirFound
|
||||
set MAVEN_PROJECTBASEDIR=%WDIR%
|
||||
cd "%EXEC_DIR%"
|
||||
goto endDetectBaseDir
|
||||
|
||||
:baseDirNotFound
|
||||
set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
|
||||
cd "%EXEC_DIR%"
|
||||
|
||||
:endDetectBaseDir
|
||||
|
||||
IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
|
||||
|
||||
@setlocal EnableExtensions EnableDelayedExpansion
|
||||
for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
|
||||
@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
|
||||
|
||||
:endReadAdditionalConfig
|
||||
|
||||
SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
|
||||
set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
|
||||
set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
|
||||
|
||||
set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
|
||||
|
||||
FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
|
||||
IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B
|
||||
)
|
||||
|
||||
@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
|
||||
@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
|
||||
if exist %WRAPPER_JAR% (
|
||||
if "%MVNW_VERBOSE%" == "true" (
|
||||
echo Found %WRAPPER_JAR%
|
||||
)
|
||||
) else (
|
||||
if not "%MVNW_REPOURL%" == "" (
|
||||
SET DOWNLOAD_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
|
||||
)
|
||||
if "%MVNW_VERBOSE%" == "true" (
|
||||
echo Couldn't find %WRAPPER_JAR%, downloading it ...
|
||||
echo Downloading from: %DOWNLOAD_URL%
|
||||
)
|
||||
|
||||
powershell -Command "&{"^
|
||||
"$webclient = new-object System.Net.WebClient;"^
|
||||
"if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^
|
||||
"$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^
|
||||
"}"^
|
||||
"[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^
|
||||
"}"
|
||||
if "%MVNW_VERBOSE%" == "true" (
|
||||
echo Finished downloading %WRAPPER_JAR%
|
||||
)
|
||||
)
|
||||
@REM End of extension
|
||||
|
||||
@REM Provide a "standardized" way to retrieve the CLI args that will
|
||||
@REM work with both Windows and non-Windows executions.
|
||||
set MAVEN_CMD_LINE_ARGS=%*
|
||||
|
||||
%MAVEN_JAVA_EXE% ^
|
||||
%JVM_CONFIG_MAVEN_PROPS% ^
|
||||
%MAVEN_OPTS% ^
|
||||
%MAVEN_DEBUG_OPTS% ^
|
||||
-classpath %WRAPPER_JAR% ^
|
||||
"-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^
|
||||
%WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
|
||||
if ERRORLEVEL 1 goto error
|
||||
goto end
|
||||
|
||||
:error
|
||||
set ERROR_CODE=1
|
||||
|
||||
:end
|
||||
@endlocal & set ERROR_CODE=%ERROR_CODE%
|
||||
|
||||
if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost
|
||||
@REM check for post script, once with legacy .bat ending and once with .cmd ending
|
||||
if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat"
|
||||
if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd"
|
||||
:skipRcPost
|
||||
|
||||
@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
|
||||
if "%MAVEN_BATCH_PAUSE%"=="on" pause
|
||||
|
||||
if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE%
|
||||
|
||||
cmd /C exit /B %ERROR_CODE%
|
12371
package-lock.json
generated
Normal file
12371
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
360
package.json
Normal file
360
package.json
Normal file
@ -0,0 +1,360 @@
|
||||
{
|
||||
"name": "no-name",
|
||||
"license": "UNLICENSED",
|
||||
"dependencies": {
|
||||
"@polymer/iron-icon": "3.0.1",
|
||||
"@polymer/iron-iconset-svg": "3.0.1",
|
||||
"@polymer/iron-list": "3.1.0",
|
||||
"@polymer/iron-meta": "3.0.1",
|
||||
"@polymer/iron-resizable-behavior": "3.0.1",
|
||||
"@polymer/polymer": "3.5.1",
|
||||
"@vaadin/accordion": "23.3.5",
|
||||
"@vaadin/app-layout": "23.3.5",
|
||||
"@vaadin/avatar": "23.3.5",
|
||||
"@vaadin/avatar-group": "23.3.5",
|
||||
"@vaadin/bundles": "23.3.5",
|
||||
"@vaadin/button": "23.3.5",
|
||||
"@vaadin/checkbox": "23.3.5",
|
||||
"@vaadin/checkbox-group": "23.3.5",
|
||||
"@vaadin/combo-box": "23.3.5",
|
||||
"@vaadin/common-frontend": "0.0.17",
|
||||
"@vaadin/component-base": "23.3.5",
|
||||
"@vaadin/confirm-dialog": "23.3.5",
|
||||
"@vaadin/context-menu": "23.3.5",
|
||||
"@vaadin/custom-field": "23.3.5",
|
||||
"@vaadin/date-picker": "23.3.5",
|
||||
"@vaadin/date-time-picker": "23.3.5",
|
||||
"@vaadin/details": "23.3.5",
|
||||
"@vaadin/dialog": "23.3.5",
|
||||
"@vaadin/email-field": "23.3.5",
|
||||
"@vaadin/field-base": "23.3.5",
|
||||
"@vaadin/field-highlighter": "23.3.5",
|
||||
"@vaadin/form-layout": "23.3.5",
|
||||
"@vaadin/grid": "23.3.5",
|
||||
"@vaadin/horizontal-layout": "23.3.5",
|
||||
"@vaadin/icon": "23.3.5",
|
||||
"@vaadin/icons": "23.3.5",
|
||||
"@vaadin/input-container": "23.3.5",
|
||||
"@vaadin/integer-field": "23.3.5",
|
||||
"@vaadin/item": "23.3.5",
|
||||
"@vaadin/list-box": "23.3.5",
|
||||
"@vaadin/lit-renderer": "23.3.5",
|
||||
"@vaadin/login": "23.3.5",
|
||||
"@vaadin/menu-bar": "23.3.5",
|
||||
"@vaadin/message-input": "23.3.5",
|
||||
"@vaadin/message-list": "23.3.5",
|
||||
"@vaadin/multi-select-combo-box": "23.3.5",
|
||||
"@vaadin/notification": "23.3.5",
|
||||
"@vaadin/number-field": "23.3.5",
|
||||
"@vaadin/password-field": "23.3.5",
|
||||
"@vaadin/polymer-legacy-adapter": "23.3.5",
|
||||
"@vaadin/progress-bar": "23.3.5",
|
||||
"@vaadin/radio-group": "23.3.5",
|
||||
"@vaadin/router": "1.7.4",
|
||||
"@vaadin/scroller": "23.3.5",
|
||||
"@vaadin/select": "23.3.5",
|
||||
"@vaadin/split-layout": "23.3.5",
|
||||
"@vaadin/tabs": "23.3.5",
|
||||
"@vaadin/tabsheet": "23.3.5",
|
||||
"@vaadin/text-area": "23.3.5",
|
||||
"@vaadin/text-field": "23.3.5",
|
||||
"@vaadin/time-picker": "23.3.5",
|
||||
"@vaadin/tooltip": "23.3.5",
|
||||
"@vaadin/upload": "23.3.5",
|
||||
"@vaadin/vaadin-accordion": "23.3.5",
|
||||
"@vaadin/vaadin-app-layout": "23.3.5",
|
||||
"@vaadin/vaadin-avatar": "23.3.5",
|
||||
"@vaadin/vaadin-button": "23.3.5",
|
||||
"@vaadin/vaadin-checkbox": "23.3.5",
|
||||
"@vaadin/vaadin-combo-box": "23.3.5",
|
||||
"@vaadin/vaadin-confirm-dialog": "23.3.5",
|
||||
"@vaadin/vaadin-context-menu": "23.3.5",
|
||||
"@vaadin/vaadin-custom-field": "23.3.5",
|
||||
"@vaadin/vaadin-date-picker": "23.3.5",
|
||||
"@vaadin/vaadin-date-time-picker": "23.3.5",
|
||||
"@vaadin/vaadin-details": "23.3.5",
|
||||
"@vaadin/vaadin-development-mode-detector": "2.0.5",
|
||||
"@vaadin/vaadin-dialog": "23.3.5",
|
||||
"@vaadin/vaadin-form-layout": "23.3.5",
|
||||
"@vaadin/vaadin-grid": "23.3.5",
|
||||
"@vaadin/vaadin-icon": "23.3.5",
|
||||
"@vaadin/vaadin-icons": "23.3.5",
|
||||
"@vaadin/vaadin-item": "23.3.5",
|
||||
"@vaadin/vaadin-list-box": "23.3.5",
|
||||
"@vaadin/vaadin-list-mixin": "23.3.5",
|
||||
"@vaadin/vaadin-login": "23.3.5",
|
||||
"@vaadin/vaadin-lumo-styles": "23.3.5",
|
||||
"@vaadin/vaadin-material-styles": "23.3.5",
|
||||
"@vaadin/vaadin-menu-bar": "23.3.5",
|
||||
"@vaadin/vaadin-messages": "23.3.5",
|
||||
"@vaadin/vaadin-notification": "23.3.5",
|
||||
"@vaadin/vaadin-ordered-layout": "23.3.5",
|
||||
"@vaadin/vaadin-overlay": "23.3.5",
|
||||
"@vaadin/vaadin-progress-bar": "23.3.5",
|
||||
"@vaadin/vaadin-radio-button": "23.3.5",
|
||||
"@vaadin/vaadin-select": "23.3.5",
|
||||
"@vaadin/vaadin-split-layout": "23.3.5",
|
||||
"@vaadin/vaadin-tabs": "23.3.5",
|
||||
"@vaadin/vaadin-template-renderer": "23.3.5",
|
||||
"@vaadin/vaadin-text-field": "23.3.5",
|
||||
"@vaadin/vaadin-themable-mixin": "23.3.5",
|
||||
"@vaadin/vaadin-time-picker": "23.3.5",
|
||||
"@vaadin/vaadin-upload": "23.3.5",
|
||||
"@vaadin/vaadin-usage-statistics": "2.1.2",
|
||||
"@vaadin/vaadin-virtual-list": "23.3.5",
|
||||
"@vaadin/vertical-layout": "23.3.5",
|
||||
"@vaadin/virtual-list": "23.3.5",
|
||||
"construct-style-sheets-polyfill": "3.1.0",
|
||||
"date-fns": "2.29.3",
|
||||
"lit": "2.6.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@rollup/plugin-replace": "3.1.0",
|
||||
"@rollup/pluginutils": "4.1.0",
|
||||
"async": "3.2.2",
|
||||
"glob": "7.2.3",
|
||||
"mkdirp": "1.0.4",
|
||||
"rollup-plugin-brotli": "3.1.0",
|
||||
"strip-css-comments": "5.0.0",
|
||||
"transform-ast": "2.4.4",
|
||||
"typescript": "4.9.3",
|
||||
"vite": "3.2.5",
|
||||
"vite-plugin-checker": "0.5.1",
|
||||
"workbox-build": "6.5.4",
|
||||
"workbox-core": "6.5.4",
|
||||
"workbox-precaching": "6.5.4"
|
||||
},
|
||||
"vaadin": {
|
||||
"dependencies": {
|
||||
"@polymer/iron-icon": "3.0.1",
|
||||
"@polymer/iron-iconset-svg": "3.0.1",
|
||||
"@polymer/iron-list": "3.1.0",
|
||||
"@polymer/iron-meta": "3.0.1",
|
||||
"@polymer/iron-resizable-behavior": "3.0.1",
|
||||
"@polymer/polymer": "3.5.1",
|
||||
"@vaadin/accordion": "23.3.5",
|
||||
"@vaadin/app-layout": "23.3.5",
|
||||
"@vaadin/avatar": "23.3.5",
|
||||
"@vaadin/avatar-group": "23.3.5",
|
||||
"@vaadin/bundles": "23.3.5",
|
||||
"@vaadin/button": "23.3.5",
|
||||
"@vaadin/checkbox": "23.3.5",
|
||||
"@vaadin/checkbox-group": "23.3.5",
|
||||
"@vaadin/combo-box": "23.3.5",
|
||||
"@vaadin/common-frontend": "0.0.17",
|
||||
"@vaadin/component-base": "23.3.5",
|
||||
"@vaadin/confirm-dialog": "23.3.5",
|
||||
"@vaadin/context-menu": "23.3.5",
|
||||
"@vaadin/custom-field": "23.3.5",
|
||||
"@vaadin/date-picker": "23.3.5",
|
||||
"@vaadin/date-time-picker": "23.3.5",
|
||||
"@vaadin/details": "23.3.5",
|
||||
"@vaadin/dialog": "23.3.5",
|
||||
"@vaadin/email-field": "23.3.5",
|
||||
"@vaadin/field-base": "23.3.5",
|
||||
"@vaadin/field-highlighter": "23.3.5",
|
||||
"@vaadin/form-layout": "23.3.5",
|
||||
"@vaadin/grid": "23.3.5",
|
||||
"@vaadin/horizontal-layout": "23.3.5",
|
||||
"@vaadin/icon": "23.3.5",
|
||||
"@vaadin/icons": "23.3.5",
|
||||
"@vaadin/input-container": "23.3.5",
|
||||
"@vaadin/integer-field": "23.3.5",
|
||||
"@vaadin/item": "23.3.5",
|
||||
"@vaadin/list-box": "23.3.5",
|
||||
"@vaadin/lit-renderer": "23.3.5",
|
||||
"@vaadin/login": "23.3.5",
|
||||
"@vaadin/menu-bar": "23.3.5",
|
||||
"@vaadin/message-input": "23.3.5",
|
||||
"@vaadin/message-list": "23.3.5",
|
||||
"@vaadin/multi-select-combo-box": "23.3.5",
|
||||
"@vaadin/notification": "23.3.5",
|
||||
"@vaadin/number-field": "23.3.5",
|
||||
"@vaadin/password-field": "23.3.5",
|
||||
"@vaadin/polymer-legacy-adapter": "23.3.5",
|
||||
"@vaadin/progress-bar": "23.3.5",
|
||||
"@vaadin/radio-group": "23.3.5",
|
||||
"@vaadin/router": "1.7.4",
|
||||
"@vaadin/scroller": "23.3.5",
|
||||
"@vaadin/select": "23.3.5",
|
||||
"@vaadin/split-layout": "23.3.5",
|
||||
"@vaadin/tabs": "23.3.5",
|
||||
"@vaadin/tabsheet": "23.3.5",
|
||||
"@vaadin/text-area": "23.3.5",
|
||||
"@vaadin/text-field": "23.3.5",
|
||||
"@vaadin/time-picker": "23.3.5",
|
||||
"@vaadin/tooltip": "23.3.5",
|
||||
"@vaadin/upload": "23.3.5",
|
||||
"@vaadin/vaadin-accordion": "23.3.5",
|
||||
"@vaadin/vaadin-app-layout": "23.3.5",
|
||||
"@vaadin/vaadin-avatar": "23.3.5",
|
||||
"@vaadin/vaadin-button": "23.3.5",
|
||||
"@vaadin/vaadin-checkbox": "23.3.5",
|
||||
"@vaadin/vaadin-combo-box": "23.3.5",
|
||||
"@vaadin/vaadin-confirm-dialog": "23.3.5",
|
||||
"@vaadin/vaadin-context-menu": "23.3.5",
|
||||
"@vaadin/vaadin-custom-field": "23.3.5",
|
||||
"@vaadin/vaadin-date-picker": "23.3.5",
|
||||
"@vaadin/vaadin-date-time-picker": "23.3.5",
|
||||
"@vaadin/vaadin-details": "23.3.5",
|
||||
"@vaadin/vaadin-development-mode-detector": "2.0.5",
|
||||
"@vaadin/vaadin-dialog": "23.3.5",
|
||||
"@vaadin/vaadin-form-layout": "23.3.5",
|
||||
"@vaadin/vaadin-grid": "23.3.5",
|
||||
"@vaadin/vaadin-icon": "23.3.5",
|
||||
"@vaadin/vaadin-icons": "23.3.5",
|
||||
"@vaadin/vaadin-item": "23.3.5",
|
||||
"@vaadin/vaadin-list-box": "23.3.5",
|
||||
"@vaadin/vaadin-list-mixin": "23.3.5",
|
||||
"@vaadin/vaadin-login": "23.3.5",
|
||||
"@vaadin/vaadin-lumo-styles": "23.3.5",
|
||||
"@vaadin/vaadin-material-styles": "23.3.5",
|
||||
"@vaadin/vaadin-menu-bar": "23.3.5",
|
||||
"@vaadin/vaadin-messages": "23.3.5",
|
||||
"@vaadin/vaadin-notification": "23.3.5",
|
||||
"@vaadin/vaadin-ordered-layout": "23.3.5",
|
||||
"@vaadin/vaadin-overlay": "23.3.5",
|
||||
"@vaadin/vaadin-progress-bar": "23.3.5",
|
||||
"@vaadin/vaadin-radio-button": "23.3.5",
|
||||
"@vaadin/vaadin-select": "23.3.5",
|
||||
"@vaadin/vaadin-split-layout": "23.3.5",
|
||||
"@vaadin/vaadin-tabs": "23.3.5",
|
||||
"@vaadin/vaadin-template-renderer": "23.3.5",
|
||||
"@vaadin/vaadin-text-field": "23.3.5",
|
||||
"@vaadin/vaadin-themable-mixin": "23.3.5",
|
||||
"@vaadin/vaadin-time-picker": "23.3.5",
|
||||
"@vaadin/vaadin-upload": "23.3.5",
|
||||
"@vaadin/vaadin-usage-statistics": "2.1.2",
|
||||
"@vaadin/vaadin-virtual-list": "23.3.5",
|
||||
"@vaadin/vertical-layout": "23.3.5",
|
||||
"@vaadin/virtual-list": "23.3.5",
|
||||
"construct-style-sheets-polyfill": "3.1.0",
|
||||
"date-fns": "2.29.3",
|
||||
"lit": "2.6.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@rollup/plugin-replace": "3.1.0",
|
||||
"@rollup/pluginutils": "4.1.0",
|
||||
"async": "3.2.2",
|
||||
"glob": "7.2.3",
|
||||
"mkdirp": "1.0.4",
|
||||
"rollup-plugin-brotli": "3.1.0",
|
||||
"strip-css-comments": "5.0.0",
|
||||
"transform-ast": "2.4.4",
|
||||
"typescript": "4.9.3",
|
||||
"vite": "3.2.5",
|
||||
"vite-plugin-checker": "0.5.1",
|
||||
"workbox-build": "6.5.4",
|
||||
"workbox-core": "6.5.4",
|
||||
"workbox-precaching": "6.5.4"
|
||||
},
|
||||
"hash": "4fbd84d097de8f423b32ad784ed7600eba86a880677dae141a768b1c60913627"
|
||||
},
|
||||
"overrides": {
|
||||
"@vaadin/bundles": "$@vaadin/bundles",
|
||||
"@vaadin/accordion": "$@vaadin/accordion",
|
||||
"@vaadin/app-layout": "$@vaadin/app-layout",
|
||||
"@vaadin/avatar": "$@vaadin/avatar",
|
||||
"@vaadin/avatar-group": "$@vaadin/avatar-group",
|
||||
"@vaadin/button": "$@vaadin/button",
|
||||
"@vaadin/checkbox": "$@vaadin/checkbox",
|
||||
"@vaadin/checkbox-group": "$@vaadin/checkbox-group",
|
||||
"@vaadin/combo-box": "$@vaadin/combo-box",
|
||||
"@vaadin/component-base": "$@vaadin/component-base",
|
||||
"@vaadin/confirm-dialog": "$@vaadin/confirm-dialog",
|
||||
"@vaadin/context-menu": "$@vaadin/context-menu",
|
||||
"@vaadin/custom-field": "$@vaadin/custom-field",
|
||||
"@vaadin/date-picker": "$@vaadin/date-picker",
|
||||
"@vaadin/date-time-picker": "$@vaadin/date-time-picker",
|
||||
"@vaadin/details": "$@vaadin/details",
|
||||
"@vaadin/dialog": "$@vaadin/dialog",
|
||||
"@vaadin/email-field": "$@vaadin/email-field",
|
||||
"@vaadin/field-base": "$@vaadin/field-base",
|
||||
"@vaadin/field-highlighter": "$@vaadin/field-highlighter",
|
||||
"@vaadin/form-layout": "$@vaadin/form-layout",
|
||||
"@vaadin/grid": "$@vaadin/grid",
|
||||
"@vaadin/horizontal-layout": "$@vaadin/horizontal-layout",
|
||||
"@vaadin/icon": "$@vaadin/icon",
|
||||
"@vaadin/icons": "$@vaadin/icons",
|
||||
"@vaadin/input-container": "$@vaadin/input-container",
|
||||
"@vaadin/integer-field": "$@vaadin/integer-field",
|
||||
"@polymer/iron-icon": "$@polymer/iron-icon",
|
||||
"@polymer/iron-iconset-svg": "$@polymer/iron-iconset-svg",
|
||||
"@polymer/iron-list": "$@polymer/iron-list",
|
||||
"@polymer/iron-meta": "$@polymer/iron-meta",
|
||||
"@polymer/iron-resizable-behavior": "$@polymer/iron-resizable-behavior",
|
||||
"@vaadin/item": "$@vaadin/item",
|
||||
"@vaadin/list-box": "$@vaadin/list-box",
|
||||
"@vaadin/lit-renderer": "$@vaadin/lit-renderer",
|
||||
"@vaadin/login": "$@vaadin/login",
|
||||
"@vaadin/menu-bar": "$@vaadin/menu-bar",
|
||||
"@vaadin/message-input": "$@vaadin/message-input",
|
||||
"@vaadin/message-list": "$@vaadin/message-list",
|
||||
"@vaadin/multi-select-combo-box": "$@vaadin/multi-select-combo-box",
|
||||
"@vaadin/notification": "$@vaadin/notification",
|
||||
"@vaadin/number-field": "$@vaadin/number-field",
|
||||
"@vaadin/password-field": "$@vaadin/password-field",
|
||||
"@vaadin/polymer-legacy-adapter": "$@vaadin/polymer-legacy-adapter",
|
||||
"@vaadin/progress-bar": "$@vaadin/progress-bar",
|
||||
"@vaadin/radio-group": "$@vaadin/radio-group",
|
||||
"@vaadin/scroller": "$@vaadin/scroller",
|
||||
"@vaadin/select": "$@vaadin/select",
|
||||
"@vaadin/split-layout": "$@vaadin/split-layout",
|
||||
"@vaadin/tabs": "$@vaadin/tabs",
|
||||
"@vaadin/tabsheet": "$@vaadin/tabsheet",
|
||||
"@vaadin/text-area": "$@vaadin/text-area",
|
||||
"@vaadin/text-field": "$@vaadin/text-field",
|
||||
"@vaadin/time-picker": "$@vaadin/time-picker",
|
||||
"@vaadin/tooltip": "$@vaadin/tooltip",
|
||||
"@vaadin/upload": "$@vaadin/upload",
|
||||
"@vaadin/vaadin-accordion": "$@vaadin/vaadin-accordion",
|
||||
"@vaadin/vaadin-app-layout": "$@vaadin/vaadin-app-layout",
|
||||
"@vaadin/vaadin-avatar": "$@vaadin/vaadin-avatar",
|
||||
"@vaadin/vaadin-button": "$@vaadin/vaadin-button",
|
||||
"@vaadin/vaadin-checkbox": "$@vaadin/vaadin-checkbox",
|
||||
"@vaadin/vaadin-combo-box": "$@vaadin/vaadin-combo-box",
|
||||
"@vaadin/vaadin-confirm-dialog": "$@vaadin/vaadin-confirm-dialog",
|
||||
"@vaadin/vaadin-context-menu": "$@vaadin/vaadin-context-menu",
|
||||
"@vaadin/vaadin-custom-field": "$@vaadin/vaadin-custom-field",
|
||||
"@vaadin/vaadin-date-picker": "$@vaadin/vaadin-date-picker",
|
||||
"@vaadin/vaadin-date-time-picker": "$@vaadin/vaadin-date-time-picker",
|
||||
"@vaadin/vaadin-details": "$@vaadin/vaadin-details",
|
||||
"@vaadin/vaadin-development-mode-detector": "$@vaadin/vaadin-development-mode-detector",
|
||||
"@vaadin/vaadin-dialog": "$@vaadin/vaadin-dialog",
|
||||
"@vaadin/vaadin-form-layout": "$@vaadin/vaadin-form-layout",
|
||||
"@vaadin/vaadin-grid": "$@vaadin/vaadin-grid",
|
||||
"@vaadin/vaadin-icon": "$@vaadin/vaadin-icon",
|
||||
"@vaadin/vaadin-icons": "$@vaadin/vaadin-icons",
|
||||
"@vaadin/vaadin-item": "$@vaadin/vaadin-item",
|
||||
"@vaadin/vaadin-list-box": "$@vaadin/vaadin-list-box",
|
||||
"@vaadin/vaadin-list-mixin": "$@vaadin/vaadin-list-mixin",
|
||||
"@vaadin/vaadin-login": "$@vaadin/vaadin-login",
|
||||
"@vaadin/vaadin-lumo-styles": "$@vaadin/vaadin-lumo-styles",
|
||||
"@vaadin/vaadin-material-styles": "$@vaadin/vaadin-material-styles",
|
||||
"@vaadin/vaadin-menu-bar": "$@vaadin/vaadin-menu-bar",
|
||||
"@vaadin/vaadin-messages": "$@vaadin/vaadin-messages",
|
||||
"@vaadin/vaadin-notification": "$@vaadin/vaadin-notification",
|
||||
"@vaadin/vaadin-ordered-layout": "$@vaadin/vaadin-ordered-layout",
|
||||
"@vaadin/vaadin-overlay": "$@vaadin/vaadin-overlay",
|
||||
"@vaadin/vaadin-progress-bar": "$@vaadin/vaadin-progress-bar",
|
||||
"@vaadin/vaadin-radio-button": "$@vaadin/vaadin-radio-button",
|
||||
"@vaadin/router": "$@vaadin/router",
|
||||
"@vaadin/vaadin-select": "$@vaadin/vaadin-select",
|
||||
"@vaadin/vaadin-split-layout": "$@vaadin/vaadin-split-layout",
|
||||
"@vaadin/vaadin-tabs": "$@vaadin/vaadin-tabs",
|
||||
"@vaadin/vaadin-template-renderer": "$@vaadin/vaadin-template-renderer",
|
||||
"@vaadin/vaadin-text-field": "$@vaadin/vaadin-text-field",
|
||||
"@vaadin/vaadin-themable-mixin": "$@vaadin/vaadin-themable-mixin",
|
||||
"@vaadin/vaadin-time-picker": "$@vaadin/vaadin-time-picker",
|
||||
"@vaadin/vaadin-upload": "$@vaadin/vaadin-upload",
|
||||
"@vaadin/vaadin-usage-statistics": "$@vaadin/vaadin-usage-statistics",
|
||||
"@vaadin/vaadin-virtual-list": "$@vaadin/vaadin-virtual-list",
|
||||
"@vaadin/vertical-layout": "$@vaadin/vertical-layout",
|
||||
"@vaadin/virtual-list": "$@vaadin/virtual-list",
|
||||
"@vaadin/common-frontend": "$@vaadin/common-frontend",
|
||||
"construct-style-sheets-polyfill": "$construct-style-sheets-polyfill",
|
||||
"lit": "$lit",
|
||||
"@polymer/polymer": "$@polymer/polymer",
|
||||
"date-fns": "$date-fns"
|
||||
}
|
||||
}
|
96
pom.xml
Normal file
96
pom.xml
Normal file
@ -0,0 +1,96 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>2.7.8</version>
|
||||
<relativePath/> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
<groupId>edu.janmod</groupId>
|
||||
<artifactId>SvarTalk</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<name>SvarTalk</name>
|
||||
<description>Projekt komunikatora</description>
|
||||
<properties>
|
||||
<java.version>17</java.version>
|
||||
<vaadin.version>23.3.5</vaadin.version>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.vaadin</groupId>
|
||||
<artifactId>vaadin-spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-devtools</artifactId>
|
||||
<scope>runtime</scope>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
<scope>runtime</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.vaadin</groupId>
|
||||
<artifactId>vaadin-bom</artifactId>
|
||||
<version>${vaadin.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>production</id>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>com.vaadin</groupId>
|
||||
<artifactId>vaadin-maven-plugin</artifactId>
|
||||
<version>${vaadin.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>frontend</id>
|
||||
<phase>compile</phase>
|
||||
<goals>
|
||||
<goal>prepare-frontend</goal>
|
||||
<goal>build-frontend</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<productionMode>true</productionMode>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
</project>
|
78
src/main/java/edu/janmod/SvarTalk/MainView.java
Normal file
78
src/main/java/edu/janmod/SvarTalk/MainView.java
Normal file
@ -0,0 +1,78 @@
|
||||
package edu.janmod.SvarTalk;
|
||||
|
||||
import com.vaadin.flow.component.Component;
|
||||
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.grid.Grid;
|
||||
import com.vaadin.flow.component.html.Paragraph;
|
||||
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
|
||||
import com.vaadin.flow.component.textfield.EmailField;
|
||||
import com.vaadin.flow.component.textfield.TextField;
|
||||
import com.vaadin.flow.component.html.H1;
|
||||
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
|
||||
import com.vaadin.flow.data.binder.Binder;
|
||||
import com.vaadin.flow.data.binder.ValidationException;
|
||||
import com.vaadin.flow.router.Route;
|
||||
|
||||
@Route("")
|
||||
public class MainView extends VerticalLayout {
|
||||
|
||||
private PersonRepository repository;
|
||||
private TextField firstName = new TextField("Imię");
|
||||
private TextField lastName = new TextField("Nazwisko");
|
||||
private EmailField email = new EmailField("Email");
|
||||
private Grid<Person> grid = new Grid<>(Person.class);
|
||||
private Binder<Person> binder = new Binder<>(Person.class);
|
||||
|
||||
public MainView(PersonRepository repository) {
|
||||
this.repository = repository;
|
||||
|
||||
grid.setColumns("firstName", "lastName", "email");
|
||||
add(getForm(), grid);
|
||||
refreshGrid();
|
||||
|
||||
|
||||
/*var button = new Button("Przycisk");
|
||||
var textField = new TextField();
|
||||
|
||||
add(new HorizontalLayout(textField, button));
|
||||
|
||||
button.addClickListener(e -> {
|
||||
add(new Paragraph("Hello, " + textField.getValue()));
|
||||
textField.clear();
|
||||
});*/
|
||||
/* add(new H1("Hello!")); */
|
||||
}
|
||||
|
||||
private Component getForm() {
|
||||
var layout = new HorizontalLayout();
|
||||
layout.setAlignItems(Alignment.BASELINE);
|
||||
|
||||
var addButton = new Button("Add");
|
||||
addButton.addClickShortcut(Key.ENTER);
|
||||
addButton.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
|
||||
layout.add(firstName, lastName, email, addButton);
|
||||
|
||||
binder.bindInstanceFields(this);
|
||||
|
||||
addButton.addClickListener(click -> {
|
||||
try{
|
||||
var person = new Person();
|
||||
binder.writeBean(person);
|
||||
repository.save(person);
|
||||
binder.readBean(new Person());
|
||||
refreshGrid();
|
||||
|
||||
}catch(ValidationException e) {
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
return layout;
|
||||
}
|
||||
|
||||
private void refreshGrid() {
|
||||
grid.setItems(repository.findAll());
|
||||
}
|
||||
}
|
41
src/main/java/edu/janmod/SvarTalk/Person.java
Normal file
41
src/main/java/edu/janmod/SvarTalk/Person.java
Normal file
@ -0,0 +1,41 @@
|
||||
package edu.janmod.SvarTalk;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.Id;
|
||||
|
||||
@Entity
|
||||
public class Person {
|
||||
@Id
|
||||
@GeneratedValue
|
||||
private Long id;
|
||||
|
||||
private String firstName;
|
||||
private String lastName;
|
||||
private String email;
|
||||
|
||||
|
||||
public String getFirstName() {
|
||||
return firstName;
|
||||
}
|
||||
|
||||
public void setFirstName(String firstName) {
|
||||
this.firstName = firstName;
|
||||
}
|
||||
|
||||
public String getLastName() {
|
||||
return lastName;
|
||||
}
|
||||
|
||||
public void setLastName(String lastName) {
|
||||
this.lastName = lastName;
|
||||
}
|
||||
|
||||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
|
||||
public void setEmail(String email) {
|
||||
this.email = email;
|
||||
}
|
||||
}
|
7
src/main/java/edu/janmod/SvarTalk/PersonRepository.java
Normal file
7
src/main/java/edu/janmod/SvarTalk/PersonRepository.java
Normal file
@ -0,0 +1,7 @@
|
||||
package edu.janmod.SvarTalk;
|
||||
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
|
||||
public interface PersonRepository extends JpaRepository<Person, Long> {
|
||||
|
||||
}
|
13
src/main/java/edu/janmod/SvarTalk/SvarTalkApplication.java
Normal file
13
src/main/java/edu/janmod/SvarTalk/SvarTalkApplication.java
Normal file
@ -0,0 +1,13 @@
|
||||
package edu.janmod.SvarTalk;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class SvarTalkApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(SvarTalkApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
1
src/main/resources/application.properties
Normal file
1
src/main/resources/application.properties
Normal file
@ -0,0 +1 @@
|
||||
|
@ -0,0 +1,13 @@
|
||||
package edu.janmod.SvarTalk;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
@SpringBootTest
|
||||
class SvarTalkApplicationTests {
|
||||
|
||||
@Test
|
||||
void contextLoads() {
|
||||
}
|
||||
|
||||
}
|
37
tsconfig.json
Normal file
37
tsconfig.json
Normal file
@ -0,0 +1,37 @@
|
||||
// This TypeScript configuration file is generated by vaadin-maven-plugin.
|
||||
// This is needed for TypeScript compiler to compile your TypeScript code in the project.
|
||||
// It is recommended to commit this file to the VCS.
|
||||
// You might want to change the configurations to fit your preferences
|
||||
// For more information about the configurations, please refer to http://www.typescriptlang.org/docs/handbook/tsconfig-json.html
|
||||
{
|
||||
"flow_version": "23.3.0.1",
|
||||
"compilerOptions": {
|
||||
"sourceMap": true,
|
||||
"jsx": "react-jsx",
|
||||
"inlineSources": true,
|
||||
"module": "esNext",
|
||||
"target": "es2020",
|
||||
"moduleResolution": "node",
|
||||
"strict": true,
|
||||
"skipLibCheck": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"noImplicitReturns": true,
|
||||
"noImplicitAny": true,
|
||||
"noImplicitThis": true,
|
||||
"noUnusedLocals": false,
|
||||
"noUnusedParameters": false,
|
||||
"experimentalDecorators": true,
|
||||
"useDefineForClassFields": false,
|
||||
"baseUrl": "frontend",
|
||||
"paths": {
|
||||
"@vaadin/flow-frontend": ["generated/jar-resources"],
|
||||
"@vaadin/flow-frontend/*": ["generated/jar-resources/*"],
|
||||
"Frontend/*": ["*"]
|
||||
}
|
||||
},
|
||||
"include": [
|
||||
"frontend/**/*",
|
||||
"types.d.ts"
|
||||
],
|
||||
"exclude": []
|
||||
}
|
10
types.d.ts
vendored
Normal file
10
types.d.ts
vendored
Normal file
@ -0,0 +1,10 @@
|
||||
// This TypeScript modules definition file is generated by vaadin-maven-plugin.
|
||||
// You can not directly import your different static files into TypeScript,
|
||||
// This is needed for TypeScript compiler to declare and export as a TypeScript module.
|
||||
// It is recommended to commit this file to the VCS.
|
||||
// You might want to change the configurations to fit your preferences
|
||||
declare module '*.css' {
|
||||
import { CSSResultGroup } from 'lit';
|
||||
const content: CSSResultGroup;
|
||||
export default content;
|
||||
}
|
9
vite.config.ts
Normal file
9
vite.config.ts
Normal file
@ -0,0 +1,9 @@
|
||||
import { UserConfigFn } from 'vite';
|
||||
import { overrideVaadinConfig } from './vite.generated';
|
||||
|
||||
const customConfig: UserConfigFn = (env) => ({
|
||||
// Here you can add custom Vite parameters
|
||||
// https://vitejs.dev/config/
|
||||
});
|
||||
|
||||
export default overrideVaadinConfig(customConfig);
|
639
vite.generated.ts
Normal file
639
vite.generated.ts
Normal file
@ -0,0 +1,639 @@
|
||||
/**
|
||||
* NOTICE: this is an auto-generated file
|
||||
*
|
||||
* This file has been generated by the `flow:prepare-frontend` maven goal.
|
||||
* This file will be overwritten on every run. Any custom changes should be made to vite.config.ts
|
||||
*/
|
||||
import path from 'path';
|
||||
import { readFileSync, existsSync, writeFileSync, mkdirSync } from 'fs';
|
||||
import * as net from 'net';
|
||||
|
||||
import { processThemeResources } from './target/plugins/application-theme-plugin/theme-handle.js';
|
||||
import { rewriteCssUrls } from './target/plugins/theme-loader/theme-loader-utils.js';
|
||||
import settings from './target/vaadin-dev-server-settings.json';
|
||||
import { defineConfig, mergeConfig, PluginOption, ResolvedConfig, UserConfigFn, OutputOptions, AssetInfo, ChunkInfo } from 'vite';
|
||||
import { getManifest } from 'workbox-build';
|
||||
|
||||
import * as rollup from 'rollup';
|
||||
import brotli from 'rollup-plugin-brotli';
|
||||
import replace from '@rollup/plugin-replace';
|
||||
import checker from 'vite-plugin-checker';
|
||||
import postcssLit from './target/plugins/rollup-plugin-postcss-lit-custom/rollup-plugin-postcss-lit.js';
|
||||
|
||||
const appShellUrl = '.';
|
||||
|
||||
const frontendFolder = path.resolve(__dirname, settings.frontendFolder);
|
||||
const themeFolder = path.resolve(frontendFolder, settings.themeFolder);
|
||||
const statsFolder = path.resolve(__dirname, settings.statsOutput);
|
||||
const frontendBundleFolder = path.resolve(__dirname, settings.frontendBundleOutput);
|
||||
const jarResourcesFolder = path.resolve(__dirname, settings.jarResourcesFolder);
|
||||
const generatedFlowImportsFolder = path.resolve(__dirname, settings.generatedFlowImportsFolder);
|
||||
const themeResourceFolder = path.resolve(__dirname, settings.themeResourceFolder);
|
||||
|
||||
const statsFile = path.resolve(statsFolder, 'stats.json');
|
||||
|
||||
const projectStaticAssetsFolders = [
|
||||
path.resolve(__dirname, 'src', 'main', 'resources', 'META-INF', 'resources'),
|
||||
path.resolve(__dirname, 'src', 'main', 'resources', 'static'),
|
||||
frontendFolder
|
||||
];
|
||||
|
||||
// Folders in the project which can contain application themes
|
||||
const themeProjectFolders = projectStaticAssetsFolders.map((folder) => path.resolve(folder, settings.themeFolder));
|
||||
|
||||
const themeOptions = {
|
||||
devMode: false,
|
||||
// The following matches folder 'frontend/generated/themes/'
|
||||
// (not 'frontend/themes') for theme in JAR that is copied there
|
||||
themeResourceFolder: path.resolve(themeResourceFolder, settings.themeFolder),
|
||||
themeProjectFolders: themeProjectFolders,
|
||||
projectStaticAssetsOutputFolder: path.resolve(__dirname, settings.staticOutput),
|
||||
frontendGeneratedFolder: path.resolve(frontendFolder, settings.generatedFolder)
|
||||
};
|
||||
|
||||
const hasExportedWebComponents = existsSync(path.resolve(frontendFolder, 'web-component.html'));
|
||||
|
||||
// Block debug and trace logs.
|
||||
console.trace = () => {};
|
||||
console.debug = () => {};
|
||||
|
||||
function injectManifestToSWPlugin(): rollup.Plugin {
|
||||
const rewriteManifestIndexHtmlUrl = (manifest) => {
|
||||
const indexEntry = manifest.find((entry) => entry.url === 'index.html');
|
||||
if (indexEntry) {
|
||||
indexEntry.url = appShellUrl;
|
||||
}
|
||||
|
||||
return { manifest, warnings: [] };
|
||||
};
|
||||
|
||||
return {
|
||||
name: 'vaadin:inject-manifest-to-sw',
|
||||
async transform(code, id) {
|
||||
if (/sw\.(ts|js)$/.test(id)) {
|
||||
const { manifestEntries } = await getManifest({
|
||||
globDirectory: frontendBundleFolder,
|
||||
globPatterns: ['**/*'],
|
||||
globIgnores: ['**/*.br'],
|
||||
manifestTransforms: [rewriteManifestIndexHtmlUrl],
|
||||
maximumFileSizeToCacheInBytes: 100 * 1024 * 1024, // 100mb,
|
||||
});
|
||||
|
||||
return code.replace('self.__WB_MANIFEST', JSON.stringify(manifestEntries));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function buildSWPlugin(opts): PluginOption {
|
||||
let config: ResolvedConfig;
|
||||
const devMode = opts.devMode;
|
||||
|
||||
const swObj = {}
|
||||
|
||||
async function build(action: 'generate' | 'write', additionalPlugins: rollup.Plugin[] = []) {
|
||||
const includedPluginNames = [
|
||||
'alias',
|
||||
'vite:resolve',
|
||||
'vite:esbuild',
|
||||
'rollup-plugin-dynamic-import-variables',
|
||||
'vite:esbuild-transpile',
|
||||
'vite:terser',
|
||||
]
|
||||
const plugins: rollup.Plugin[] = config.plugins.filter((p) => {
|
||||
return includedPluginNames.includes(p.name)
|
||||
});
|
||||
plugins.push(
|
||||
replace({
|
||||
values: {
|
||||
'process.env.NODE_ENV': JSON.stringify(config.mode),
|
||||
...config.define,
|
||||
},
|
||||
preventAssignment: true
|
||||
})
|
||||
);
|
||||
if (additionalPlugins) {
|
||||
plugins.push(...additionalPlugins);
|
||||
}
|
||||
const bundle = await rollup.rollup({
|
||||
input: path.resolve(settings.clientServiceWorkerSource),
|
||||
plugins
|
||||
});
|
||||
|
||||
try {
|
||||
return await bundle[action]({
|
||||
file: path.resolve(frontendBundleFolder, 'sw.js'),
|
||||
format: 'es',
|
||||
exports: 'none',
|
||||
sourcemap: config.command === 'serve' || config.build.sourcemap,
|
||||
inlineDynamicImports: true,
|
||||
});
|
||||
} finally {
|
||||
await bundle.close();
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
name: 'vaadin:build-sw',
|
||||
enforce: 'post',
|
||||
async configResolved(resolvedConfig) {
|
||||
config = resolvedConfig;
|
||||
},
|
||||
async buildStart() {
|
||||
if (devMode) {
|
||||
const { output } = await build('generate');
|
||||
swObj.code = output[0].code;
|
||||
swObj.map = output[0].map;
|
||||
}
|
||||
},
|
||||
async load(id) {
|
||||
if (id.endsWith('sw.js')) {
|
||||
return '';
|
||||
}
|
||||
},
|
||||
async transform(_code, id) {
|
||||
if (id.endsWith('sw.js')) {
|
||||
return swObj;
|
||||
}
|
||||
},
|
||||
async closeBundle() {
|
||||
await build('write', [
|
||||
injectManifestToSWPlugin(),
|
||||
brotli(),
|
||||
]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function statsExtracterPlugin(): PluginOption {
|
||||
return {
|
||||
name: 'vaadin:stats',
|
||||
enforce: 'post',
|
||||
async writeBundle(options: OutputOptions, bundle: { [fileName: string]: AssetInfo | ChunkInfo }) {
|
||||
const modules = Object.values(bundle).flatMap((b) => (b.modules ? Object.keys(b.modules) : []));
|
||||
const nodeModulesFolders = modules.filter((id) => id.includes('node_modules'));
|
||||
const npmModules = nodeModulesFolders
|
||||
.map((id) => id.replace(/.*node_modules./, ''))
|
||||
.map((id) => {
|
||||
const parts = id.split('/');
|
||||
if (id.startsWith('@')) {
|
||||
return parts[0] + '/' + parts[1];
|
||||
} else {
|
||||
return parts[0];
|
||||
}
|
||||
})
|
||||
.sort()
|
||||
.filter((value, index, self) => self.indexOf(value) === index);
|
||||
|
||||
mkdirSync(path.dirname(statsFile), { recursive: true });
|
||||
writeFileSync(statsFile, JSON.stringify({ npmModules }, null, 1));
|
||||
}
|
||||
};
|
||||
}
|
||||
function vaadinBundlesPlugin(): PluginOption {
|
||||
type ExportInfo =
|
||||
| string
|
||||
| {
|
||||
namespace?: string;
|
||||
source: string;
|
||||
};
|
||||
|
||||
type ExposeInfo = {
|
||||
exports: ExportInfo[];
|
||||
};
|
||||
|
||||
type PackageInfo = {
|
||||
version: string;
|
||||
exposes: Record<string, ExposeInfo>;
|
||||
};
|
||||
|
||||
type BundleJson = {
|
||||
packages: Record<string, PackageInfo>;
|
||||
};
|
||||
|
||||
const disabledMessage = 'Vaadin component dependency bundles are disabled.';
|
||||
|
||||
const modulesDirectory = path.resolve(__dirname, 'node_modules').replace(/\\/g, '/');
|
||||
|
||||
let vaadinBundleJson: BundleJson;
|
||||
|
||||
function parseModuleId(id: string): { packageName: string; modulePath: string } {
|
||||
const [scope, scopedPackageName] = id.split('/', 3);
|
||||
const packageName = scope.startsWith('@') ? `${scope}/${scopedPackageName}` : scope;
|
||||
const modulePath = `.${id.substring(packageName.length)}`;
|
||||
return {
|
||||
packageName,
|
||||
modulePath
|
||||
};
|
||||
}
|
||||
|
||||
function getExports(id: string): string[] | undefined {
|
||||
const { packageName, modulePath } = parseModuleId(id);
|
||||
const packageInfo = vaadinBundleJson.packages[packageName];
|
||||
|
||||
if (!packageInfo) return;
|
||||
|
||||
const exposeInfo: ExposeInfo = packageInfo.exposes[modulePath];
|
||||
if (!exposeInfo) return;
|
||||
|
||||
const exportsSet = new Set<string>();
|
||||
for (const e of exposeInfo.exports) {
|
||||
if (typeof e === 'string') {
|
||||
exportsSet.add(e);
|
||||
} else {
|
||||
const { namespace, source } = e;
|
||||
if (namespace) {
|
||||
exportsSet.add(namespace);
|
||||
} else {
|
||||
const sourceExports = getExports(source);
|
||||
if (sourceExports) {
|
||||
sourceExports.forEach((e) => exportsSet.add(e));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return Array.from(exportsSet);
|
||||
}
|
||||
|
||||
function getExportBinding(binding: string) {
|
||||
return binding === 'default' ? '_default as default' : binding;
|
||||
}
|
||||
|
||||
function getImportAssigment(binding: string) {
|
||||
return binding === 'default' ? 'default: _default' : binding;
|
||||
}
|
||||
|
||||
return {
|
||||
name: 'vaadin:bundles',
|
||||
enforce: 'pre',
|
||||
apply(config, { command }) {
|
||||
if (command !== 'serve') return false;
|
||||
|
||||
try {
|
||||
const vaadinBundleJsonPath = require.resolve('@vaadin/bundles/vaadin-bundle.json');
|
||||
vaadinBundleJson = JSON.parse(readFileSync(vaadinBundleJsonPath, { encoding: 'utf8' }));
|
||||
} catch (e: unknown) {
|
||||
if (typeof e === 'object' && (e as { code: string }).code === 'MODULE_NOT_FOUND') {
|
||||
vaadinBundleJson = { packages: {} };
|
||||
console.info(`@vaadin/bundles npm package is not found, ${disabledMessage}`);
|
||||
return false;
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
const versionMismatches: Array<{ name: string; bundledVersion: string; installedVersion: string }> = [];
|
||||
for (const [name, packageInfo] of Object.entries(vaadinBundleJson.packages)) {
|
||||
let installedVersion: string | undefined = undefined;
|
||||
try {
|
||||
const { version: bundledVersion } = packageInfo;
|
||||
const installedPackageJsonFile = path.resolve(modulesDirectory, name, 'package.json');
|
||||
const packageJson = JSON.parse(readFileSync(installedPackageJsonFile, { encoding: 'utf8' }));
|
||||
installedVersion = packageJson.version;
|
||||
if (installedVersion && installedVersion !== bundledVersion) {
|
||||
versionMismatches.push({
|
||||
name,
|
||||
bundledVersion,
|
||||
installedVersion
|
||||
});
|
||||
}
|
||||
} catch (_) {
|
||||
// ignore package not found
|
||||
}
|
||||
}
|
||||
if (versionMismatches.length) {
|
||||
console.info(`@vaadin/bundles has version mismatches with installed packages, ${disabledMessage}`);
|
||||
console.info(`Packages with version mismatches: ${JSON.stringify(versionMismatches, undefined, 2)}`);
|
||||
vaadinBundleJson = { packages: {} };
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
async config(config) {
|
||||
return mergeConfig(
|
||||
{
|
||||
optimizeDeps: {
|
||||
exclude: [
|
||||
// Vaadin bundle
|
||||
'@vaadin/bundles',
|
||||
...Object.keys(vaadinBundleJson.packages)
|
||||
]
|
||||
}
|
||||
},
|
||||
config
|
||||
);
|
||||
},
|
||||
load(rawId) {
|
||||
const [path, params] = rawId.split('?');
|
||||
if (!path.startsWith(modulesDirectory)) return;
|
||||
|
||||
const id = path.substring(modulesDirectory.length + 1);
|
||||
const bindings = getExports(id);
|
||||
if (bindings === undefined) return;
|
||||
|
||||
const cacheSuffix = params ? `?${params}` : '';
|
||||
const bundlePath = `@vaadin/bundles/vaadin.js${cacheSuffix}`;
|
||||
|
||||
return `import { init as VaadinBundleInit, get as VaadinBundleGet } from '${bundlePath}';
|
||||
await VaadinBundleInit('default');
|
||||
const { ${bindings.map(getImportAssigment).join(', ')} } = (await VaadinBundleGet('./node_modules/${id}'))();
|
||||
export { ${bindings.map(getExportBinding).join(', ')} };`;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function themePlugin(opts): PluginOption {
|
||||
const fullThemeOptions = {...themeOptions, devMode: opts.devMode };
|
||||
return {
|
||||
name: 'vaadin:theme',
|
||||
config() {
|
||||
processThemeResources(fullThemeOptions, console);
|
||||
},
|
||||
configureServer(server) {
|
||||
function handleThemeFileCreateDelete(themeFile, stats) {
|
||||
if (themeFile.startsWith(themeFolder)) {
|
||||
const changed = path.relative(themeFolder, themeFile)
|
||||
console.debug('Theme file ' + (!!stats ? 'created' : 'deleted'), changed);
|
||||
processThemeResources(fullThemeOptions, console);
|
||||
}
|
||||
}
|
||||
server.watcher.on('add', handleThemeFileCreateDelete);
|
||||
server.watcher.on('unlink', handleThemeFileCreateDelete);
|
||||
},
|
||||
handleHotUpdate(context) {
|
||||
const contextPath = path.resolve(context.file);
|
||||
const themePath = path.resolve(themeFolder);
|
||||
if (contextPath.startsWith(themePath)) {
|
||||
const changed = path.relative(themePath, contextPath);
|
||||
|
||||
console.debug('Theme file changed', changed);
|
||||
|
||||
if (changed.startsWith(settings.themeName)) {
|
||||
processThemeResources(fullThemeOptions, console);
|
||||
}
|
||||
}
|
||||
},
|
||||
async resolveId(id, importer) {
|
||||
// force theme generation if generated theme sources does not yet exist
|
||||
// this may happen for example during Java hot reload when updating
|
||||
// @Theme annotation value
|
||||
if (path.resolve(themeOptions.frontendGeneratedFolder, "theme.js") === importer &&
|
||||
!existsSync(path.resolve(themeOptions.frontendGeneratedFolder, id))) {
|
||||
console.debug('Generate theme file ' + id + ' not existing. Processing theme resource');
|
||||
processThemeResources(fullThemeOptions, console);
|
||||
return;
|
||||
}
|
||||
if (!id.startsWith(settings.themeFolder)) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const location of [themeResourceFolder, frontendFolder]) {
|
||||
const result = await this.resolve(path.resolve(location, id));
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
},
|
||||
async transform(raw, id, options) {
|
||||
// rewrite urls for the application theme css files
|
||||
const [bareId, query] = id.split('?');
|
||||
if (!bareId?.startsWith(themeFolder) || !bareId?.endsWith('.css')) {
|
||||
return;
|
||||
}
|
||||
const [themeName] = bareId.substring(themeFolder.length + 1).split('/');
|
||||
return rewriteCssUrls(raw, path.dirname(bareId), path.resolve(themeFolder, themeName), console, opts);
|
||||
}
|
||||
};
|
||||
}
|
||||
function lenientLitImportPlugin(): PluginOption {
|
||||
return {
|
||||
name: 'vaadin:lenient-lit-import',
|
||||
async transform(code, id) {
|
||||
const decoratorImports = [
|
||||
/import (.*?) from (['"])(lit\/decorators)(['"])/,
|
||||
/import (.*?) from (['"])(lit-element\/decorators)(['"])/
|
||||
];
|
||||
const directiveImports = [
|
||||
/import (.*?) from (['"])(lit\/directives\/)([^\\.]*?)(['"])/,
|
||||
/import (.*?) from (['"])(lit-html\/directives\/)([^\\.]*?)(['"])/
|
||||
];
|
||||
|
||||
decoratorImports.forEach((decoratorImport) => {
|
||||
let decoratorMatch;
|
||||
while ((decoratorMatch = code.match(decoratorImport))) {
|
||||
console.warn(
|
||||
`Warning: the file ${id} imports from '${decoratorMatch[3]}' when it should import from '${decoratorMatch[3]}.js'`
|
||||
);
|
||||
code = code.replace(decoratorImport, 'import $1 from $2$3.js$4');
|
||||
}
|
||||
});
|
||||
|
||||
directiveImports.forEach((directiveImport) => {
|
||||
let directiveMatch;
|
||||
while ((directiveMatch = code.match(directiveImport))) {
|
||||
console.warn(
|
||||
`Warning: the file ${id} imports from '${directiveMatch[3]}${directiveMatch[4]}' when it should import from '${directiveMatch[3]}${directiveMatch[4]}.js'`
|
||||
);
|
||||
code = code.replace(directiveImport, 'import $1 from $2$3$4.js$5');
|
||||
}
|
||||
});
|
||||
|
||||
return code;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function runWatchDog(watchDogPort, watchDogHost) {
|
||||
const client = net.Socket();
|
||||
client.setEncoding('utf8');
|
||||
client.on('error', function (err) {
|
||||
console.log('Watchdog connection error. Terminating vite process...', err);
|
||||
client.destroy();
|
||||
process.exit(0);
|
||||
});
|
||||
client.on('close', function () {
|
||||
client.destroy();
|
||||
runWatchDog(watchDogPort, watchDogHost);
|
||||
});
|
||||
|
||||
client.connect(watchDogPort, watchDogHost || 'localhost');
|
||||
}
|
||||
|
||||
let spaMiddlewareForceRemoved = false;
|
||||
|
||||
const allowedFrontendFolders = [
|
||||
frontendFolder,
|
||||
path.resolve(generatedFlowImportsFolder), // Contains only generated-flow-imports
|
||||
path.resolve(__dirname, 'node_modules')
|
||||
];
|
||||
|
||||
function setHmrPortToServerPort(): PluginOption {
|
||||
return {
|
||||
name: 'set-hmr-port-to-server-port',
|
||||
configResolved(config) {
|
||||
if (config.server.strictPort && config.server.hmr !== false) {
|
||||
if (config.server.hmr === true) config.server.hmr = {};
|
||||
config.server.hmr = config.server.hmr || {};
|
||||
config.server.hmr.clientPort = config.server.port;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
function showRecompileReason(): PluginOption {
|
||||
return {
|
||||
name: 'vaadin:why-you-compile',
|
||||
handleHotUpdate(context) {
|
||||
console.log('Recompiling because', context.file, 'changed');
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export const vaadinConfig: UserConfigFn = (env) => {
|
||||
const devMode = env.mode === 'development';
|
||||
|
||||
if (devMode && process.env.watchDogPort) {
|
||||
// Open a connection with the Java dev-mode handler in order to finish
|
||||
// vite when it exits or crashes.
|
||||
runWatchDog(process.env.watchDogPort, process.env.watchDogHost);
|
||||
}
|
||||
|
||||
return {
|
||||
root: frontendFolder,
|
||||
base: '',
|
||||
resolve: {
|
||||
alias: {
|
||||
'@vaadin/flow-frontend': jarResourcesFolder,
|
||||
Frontend: frontendFolder
|
||||
},
|
||||
preserveSymlinks: true
|
||||
},
|
||||
define: {
|
||||
OFFLINE_PATH: settings.offlinePath,
|
||||
VITE_ENABLED: 'true'
|
||||
},
|
||||
server: {
|
||||
host: '127.0.0.1',
|
||||
strictPort: true,
|
||||
fs: {
|
||||
allow: allowedFrontendFolders
|
||||
}
|
||||
},
|
||||
build: {
|
||||
outDir: frontendBundleFolder,
|
||||
assetsDir: 'VAADIN/build',
|
||||
rollupOptions: {
|
||||
input: {
|
||||
indexhtml: path.resolve(frontendFolder, 'index.html'),
|
||||
|
||||
...hasExportedWebComponents
|
||||
? { webcomponenthtml: path.resolve(frontendFolder, 'web-component.html') }
|
||||
: {}
|
||||
}
|
||||
}
|
||||
},
|
||||
optimizeDeps: {
|
||||
entries: [
|
||||
// Pre-scan entrypoints in Vite to avoid reloading on first open
|
||||
'generated/vaadin.ts'
|
||||
],
|
||||
exclude: [
|
||||
'@vaadin/router',
|
||||
'@vaadin/vaadin-license-checker',
|
||||
'@vaadin/vaadin-usage-statistics',
|
||||
'workbox-core',
|
||||
'workbox-precaching',
|
||||
'workbox-routing',
|
||||
'workbox-strategies'
|
||||
]
|
||||
},
|
||||
plugins: [
|
||||
!devMode && brotli(),
|
||||
devMode && vaadinBundlesPlugin(),
|
||||
devMode && setHmrPortToServerPort(),
|
||||
devMode && showRecompileReason(),
|
||||
settings.offlineEnabled && buildSWPlugin({ devMode }),
|
||||
!devMode && statsExtracterPlugin(),
|
||||
themePlugin({devMode}),
|
||||
lenientLitImportPlugin(),
|
||||
postcssLit({
|
||||
include: ['**/*.css', '**/*.css\?*'],
|
||||
exclude: [
|
||||
`${themeFolder}/**/*.css`,
|
||||
`${themeFolder}/**/*.css\?*`,
|
||||
`${themeResourceFolder}/**/*.css`,
|
||||
`${themeResourceFolder}/**/*.css\?*`,
|
||||
'**/*\?html-proxy*'
|
||||
]
|
||||
}),
|
||||
{
|
||||
name: 'vaadin:force-remove-html-middleware',
|
||||
transformIndexHtml: {
|
||||
enforce: 'pre',
|
||||
transform(_html, { server }) {
|
||||
if (server && !spaMiddlewareForceRemoved) {
|
||||
server.middlewares.stack = server.middlewares.stack.filter((mw) => {
|
||||
const handleName = '' + mw.handle;
|
||||
return !handleName.includes('viteHtmlFallbackMiddleware');
|
||||
});
|
||||
spaMiddlewareForceRemoved = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
hasExportedWebComponents && {
|
||||
name: 'vaadin:inject-entrypoints-to-web-component-html',
|
||||
transformIndexHtml: {
|
||||
enforce: 'pre',
|
||||
transform(_html, { path, server }) {
|
||||
if (path !== '/web-component.html') {
|
||||
return;
|
||||
}
|
||||
|
||||
return [
|
||||
{
|
||||
tag: 'script',
|
||||
attrs: { type: 'module', src: `/generated/vaadin-web-component.ts` },
|
||||
injectTo: 'head'
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'vaadin:inject-entrypoints-to-index-html',
|
||||
transformIndexHtml: {
|
||||
enforce: 'pre',
|
||||
transform(_html, { path, server }) {
|
||||
if (path !== '/index.html') {
|
||||
return;
|
||||
}
|
||||
|
||||
const scripts = [];
|
||||
|
||||
if (devMode) {
|
||||
scripts.push({
|
||||
tag: 'script',
|
||||
attrs: { type: 'module', src: `/generated/vite-devmode.ts` },
|
||||
injectTo: 'head'
|
||||
});
|
||||
}
|
||||
scripts.push({
|
||||
tag: 'script',
|
||||
attrs: { type: 'module', src: '/generated/vaadin.ts' },
|
||||
injectTo: 'head'
|
||||
});
|
||||
return scripts;
|
||||
}
|
||||
}
|
||||
},
|
||||
checker({
|
||||
typescript: true
|
||||
})
|
||||
]
|
||||
};
|
||||
};
|
||||
|
||||
export const overrideVaadinConfig = (customConfig: UserConfigFn) => {
|
||||
return defineConfig((env) => mergeConfig(vaadinConfig(env), customConfig(env)));
|
||||
};
|
Loading…
Reference in New Issue
Block a user