first commit

This commit is contained in:
2025-08-02 16:30:27 +02:00
commit 23646bfcee
14851 changed files with 1750626 additions and 0 deletions

11
admin/webpack/@types/global.d.ts vendored Normal file
View File

@@ -0,0 +1,11 @@
declare global {
var CKEDITOR: any;
interface Window {
llm: () => void;
}
}
export {};

View File

@@ -0,0 +1,102 @@
'use strict';
const path = require('path');
const assign = require('object-assign');
const fs = require('fs');
/**
* @class
* @param {Object} options
* @param {String} options.path Path to theme folder, required param
* @param {RegExp} [options.rule=/^@theme/]
* @param {String} [options.env='THEME']
* @param {String} [options.defaultTheme='default']
* @param {String} [options.theme]
* @constructor
*/
function WpjResolverPlugin(options) {
this.options = assign(
{},
{
rule: /^@theme/,
paths: {},
scss: false
},
options
);
this.options.moduleRule = new RegExp(this.options.rule.source + '\\[(.*)\\]');
}
WpjResolverPlugin.prototype.apply = function(compiler) {
const options = this.options;
var target = compiler.ensureHook('internal-resolve');
var root = fs.realpathSync('.');
const resolve = (file, request, resolveContext, finalCallback) => {
const obj = assign({}, request, {
request: './' + file,
path: root,
relativePath: '.',
});
// console.log('Resolving', request.request, file);
compiler.doResolve(target, obj, `found file: ${file}`, resolveContext, function(...args) {
return finalCallback(...args);
});
};
const resolveFiles = (files, request, resolveContext, finalCallback) => {
let resolved = false;
files.some(file => {
if (
(fs.existsSync(file) && fs.lstatSync(file).isFile()) ||
(fs.existsSync(file + '.scss') && fs.lstatSync(file + '.scss').isFile()) ||
(fs.existsSync(file + '.tsx') && fs.lstatSync(file + '.tsx').isFile()) ||
(fs.existsSync(file + '.ts') && fs.lstatSync(file + '.ts').isFile())
) {
resolved = true;
resolve(file, request, resolveContext, finalCallback);
return true;
}
});
if (!resolved) {
return finalCallback();
}
};
compiler.getHook('raw-resolve').tapAsync('WpjResolverPlugin', function(request, resolveContext, finalCallback) {
if (!options.rule.test(request.request)) {
return finalCallback();
}
let attempts = assign({}, options.paths);
let moduleMatch = request.request.match(options.moduleRule);
if (moduleMatch) {
attempts = {};
attempts[moduleMatch[1]] = options.paths[moduleMatch[1]];
}
let files = [];
Object.keys(attempts).forEach(name => {
let prefix = attempts[name];
files.push(request.request.replace(moduleMatch ? options.moduleRule : options.rule, prefix));
if (options.scss) {
let parts = path.parse(request.request);
files.push(
path.join(parts.dir.replace(moduleMatch ? options.moduleRule : options.rule, prefix), '_' + parts.base)
);
}
});
return resolveFiles(files, request, resolveContext, finalCallback);
});
};
module.exports = WpjResolverPlugin;

View File

@@ -0,0 +1,75 @@
// Font
require('@assets/fonts/icons.font.js');
// create global $ and jQuery variables
$ = require('jquery');
global.$ = global.jQuery = $;
require('@static/js/jquery-ui.1.12.1.js');
require('@static/css/jquery-ui-1.8.16.custom.scss');
//require('@static/bootstrap/bootstrap.scss'); // todo presunuto do style.scss
require('@static/bootstrap/js/bootstrap.js');
require('@static/js/chosen.jquery.js');
require('@static/js/ajax-chosen.js');
require('@static/js/chosen.sortable.js');
require('@static/js/jquery.fs.stepper.min.js');
require('@static/js/bootstrap-filestyle.min.js');
// Custom functions -->
const functions = require('@static/js/functions.js');
// Expose exported to global
(function() {
for (let key in functions) {
if (functions.hasOwnProperty(key)) {
window[key] = functions[key];
}
}
})();
require('@static/js/jquery.history.js');
require('@static/js/jquery.hotkeys.js');
const BigNumber = require('@static/js/bignumber.js');
window.BigNumber = BigNumber;
// Admin autocomplete -->
require('@static/js/wpj.template.js');
require('@static/js/wpj.domUtils.js');
require('@static/js/wpj.autocomplete.js');
require('@static/js/wpj.formUtils.js');
require('@static/js/wpj.windowUtils.js');
require('@static/js/wpj.clipboard.js');
require('@static/js/wpj.buttonLoading.js');
require('@static/js/wpj.translationsFigure.js');
/**
* @typedef WidgetProps require('../../static/sections-autocomplete/index.tsx').WidgetProps
*
* @type {{ prepareRuntime: (runtimeElement?: HTMLElement) => HTMLElement; mountAutocomplete: (target: HTMLElement, options?: WidgetProps) => void }}
*/
wpj.SectionsAutocomplete = require('@static/sections-autocomplete/index.tsx');
wpj.llmModal = require('@static/llm-modal/index.tsx');
// Styles
require('@static/scss/style.scss');
const Favico = require('@static/js/favico.js');
window.FavicoInit = function() {
var bgColor = '#1c6ee8';
var currUrl = window.location.href;
if (currUrl.indexOf('kupshop.local') >= 0) {
bgColor = '#e9573f';
}
var favicon = new Favico({
animation: 'popFade',
bgColor: bgColor
});
favicon.badge('A');
};

View File

@@ -0,0 +1,4 @@
require('@static/scss/board.scss');
require('@static/js/wpj.changelog.js');

View File

@@ -0,0 +1 @@
require('../fonts/icons-sass.font');

View File

@@ -0,0 +1 @@
require('@static/scss/list.scss');

View File

@@ -0,0 +1 @@
require('@static/js/wpj.adminListEdit.js');

View File

@@ -0,0 +1 @@
require('@static/js/translations.js');

View File

@@ -0,0 +1,16 @@
require('@static/scss/window.scss');
require('@static/js/wpj.focus.js');
$(document).ready(function() {
const $lightbox = $('a[data-rel="bigphoto"]');
if ($lightbox.length) {
require('@static/fancybox2/jquery.fancybox.pack.js');
require('@static/fancybox2/jquery.fancybox.css');
$lightbox.fancybox({
openEffect: 'none',
closeEffect: 'none'
});
}
});

View File

@@ -0,0 +1,26 @@
@font-face {
font-family: "{{fontName}}";
src: {{{src}}};
}
{{baseSelector}}:before {
display: inline-block;
font-family: {{fontName}};
font-style: normal;
font-weight: normal;
font-variant: normal;
line-height: 1;
text-decoration: inherit;
text-rendering: optimizeLegibility;
text-transform: none;
-moz-osx-font-smoothing: grayscale;
-webkit-font-smoothing: antialiased;
width: 1em;
height: 1em;
}
{{#each codepoints}}
.{{../classPrefix}}{{@key}}:before {
content: "\\{{this}}";
}
{{/each}}

View File

@@ -0,0 +1,35 @@
<style>
.preview {
margin: 5px 0;
}
.preview__icon {
margin-right: 10px;
}
.preview__list {
column-count: 3;
font-size: 20px;
}
/* @formatter:off */
.preview__list {{baseSelector}} {
background: #eee;
}
{{{styles}}}
/* @formatter:on */
</style>
<h1 class="text-center m-b-1">{{fontName}}</h1>
<div class="preview__list">
{{#each names}}
<div class="preview">
<span class="preview__icon">
<span class="fc {{../classPrefix}}{{this}}"></span>
</span>
<span>{{this}}</span>
</div>
{{/each}}
</div>

View File

@@ -0,0 +1,31 @@
const process = require('process');
const fs = require('fs');
const path = require('path');
const currDir = process.cwd();
let icons = [];
let iconsNames = [];
if (fs.existsSync(currDir + '/templates/icons/')) {
const filesShop = fs.readdirSync(currDir + '/templates/icons/');
filesShop.forEach(file => {
if (path.extname(file) === '.svg') {
icons.push(currDir + '/templates/icons/' + file);
iconsNames.push(file);
}
});
}
if (fs.existsSync(currDir + '/admin/static/icons/')) {
const filesEngine = fs.readdirSync(currDir + '/admin/static/icons/');
filesEngine.forEach(file => {
if (path.extname(file) === '.svg' && !iconsNames.includes(file)) {
icons.push(currDir + '/admin/static/icons/' + file);
}
});
}
module.exports = icons;

View File

@@ -0,0 +1,19 @@
const icons = require('./icons-merge');
const handlebars = require('handlebars');
handlebars.registerHelper('toHex', int => {
return '\\' + int.toString(16);
});
module.exports = {
'files': icons,
'fontName': '_icons',
'types': [],
'emitCodepoints': [{fileName:'icons-list.json', type: 'json'}],
'html': true,
'htmlDest': '_icons.scss',
'htmlTemplate': 'scss.hbs',
'cssTemplate': 'scss.hbs',
'classPrefix': '',
'baseSelector': '.fc',
};

View File

@@ -0,0 +1,14 @@
const icons = require('./icons-merge');
// const Encore = require('@symfony/webpack-encore');
// const filename = Encore.isProduction() ? 'app.[fontname].[chunkhash].[ext]' : 'app.[fontname].[ext]';
const filename = 'app.[fontname].[chunkhash].[ext]';
module.exports = {
files: icons,
fontName: 'icons',
classPrefix: '',
baseSelector: '.fc',
types: ['woff2', 'woff'],
fileName: filename,
cssTemplate: './css.hbs'
};

View File

@@ -0,0 +1,4 @@
[{"name":"Bez ikony", "value":"","icon":""}
{{#each names}}
,{"name":"{{this}}", "value":"{{this}}","icon":"{{../classPrefix}}{{this}}"}
{{/each}}]

View File

@@ -0,0 +1,30 @@
$webfont-icons: () !default;
$webfont-icons: map-merge($webfont-icons, (
{{#each codepoints}}
'{{@key}}': ('icons' '{{this}}'),
{{/each}}
));
@mixin webfont-icon($name) {
line-height: 1;
$icon: map-get($webfont-icons, $name);
&:before {
font-family: nth($icon, 1) !important;
font-style: normal;
font-weight: normal !important;
vertical-align: top;
content: str-slice('\x', 1, 1) + nth($icon, 2);
}
}
@mixin webfont-content($name) {
$icon: map-get($webfont-icons, $name);
content: str-slice('\x', 1, 1) + nth($icon, 2);
}
{{#each codepoints}}
${{@key}}: '{{toHex this}}';
{{/each}}

View File

@@ -0,0 +1,6 @@
// postcss.config.js
module.exports = {
plugins: {
autoprefixer: {}
}
};

View File

@@ -0,0 +1,144 @@
const Encore = require('@symfony/webpack-encore');
const path = require('path');
const process = require('process');
const WpjResolver = require('../../web/common/webpack/WpjResolver');
const webpack = require('webpack');
const rootDir = process.cwd();
Encore
// directory where compiled assets will be stored
.setOutputPath('admin/static/build/')
// public path used by the web server to access the output path
.setPublicPath('/admin/static/build/')
.addEntry('icons', '@assets/entrypoints/icons.js')
.addEntry('app', '@assets/entrypoints/app.js')
.addEntry('board', '@assets/entrypoints/board.js')
.addEntry('window', '@assets/entrypoints/window.js')
.addEntry('list', '@assets/entrypoints/list.js')
.addEntry('listEdit', '@assets/entrypoints/listEdit.js')
.addEntry('translate', '@assets/entrypoints/translate.js')
.enableSourceMaps(true)
// enables hashed filenames (e.g. app.abc123.css)
.enableVersioning(Encore.isProduction())
.disableSingleRuntimeChunk()
.enableReactPreset()
// uncomment if you use TypeScript
.enableTypeScriptLoader()
// uncomment if you use Sass/SCSS files
.enableSassLoader(options => {
// https://github.com/sass/node-sass#options
options.sassOptions.includePaths = ['common/static/compass/', 'common'];
options.implementation = require('sass');
})
.enablePostCssLoader(options => {
options.postcssOptions = {
// the directory where the postcss.config.js file is stored
config: 'admin/webpack/'
};
}).addPlugin(
new webpack.DefinePlugin({
ADMIN: true
})
)
.configureDevServerOptions(options => {
options.server = {
type: 'https',
options: {
cert: '/etc/ssl/cert.pem',
key: '/etc/ssl/key.pem',
},
};
options.hot = true;
options.allowedHosts = 'all';
options.host = '0.0.0.0';
options.client = {
overlay: true,
};
options.proxy = {
secure: false,
context: () => true,
target: 'https://localhost'
};
});
if (Encore.isDevServer()) {
Encore.disableCssExtraction();
} else {
//Encore.cleanupOutputBeforeBuild();
}
const EncoreProxy = new Proxy(Encore, {
get: (target, prop) => {
if (prop === 'getWebpackConfig') {
return (...parameters) => {
const config = target[prop](...parameters);
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const loaders = [];
if (!Encore.isDevServer()) {
loaders.push(MiniCssExtractPlugin.loader);
} else {
loaders.push('style-loader');
}
// config.stats = 'verbose';
// config.resolve.modules = [path.join(rootDir, 'engine/node_modules'), path.join(rootDir, 'node_modules')];
// config.resolveLoader = config.resolve;
config.module.rules.push({
test: /\.font\.js/,
use: [
...loaders,
{
loader: 'css-loader',
},
{
loader: 'webfonts-loader',
options: {
publicPath: '/admin/static/build/'
}
}
]
});
const WpjResolver = require('./WpjResolver.js');
config.resolve.plugins = [
new WpjResolver({
rule: /^@assets/,
paths: {
common: 'admin/webpack/assets/'
}
}),
new WpjResolver({
rule: /^@static/,
paths: {
common: 'admin/static/'
}
}),
new WpjResolver({
rule: /^@hack/,
paths: {
shop: './admin/static/build' + path.resolve(__dirname, 'assets/fonts/')
}
})
];
return config;
};
}
return (...parameters) => {
const res = target[prop](...parameters);
return (res === target) ? EncoreProxy : res;
};
}
});
module.exports = EncoreProxy.getWebpackConfig();