diff --git a/.husky/addReferenceTag.js b/.husky/addReferenceTag.js
index 857d15739..a88baf2e1 100644
--- a/.husky/addReferenceTag.js
+++ b/.husky/addReferenceTag.js
@@ -26,7 +26,7 @@ if (branchName) {
const splitedMsg = msg.split(':');
if (splitedMsg.length > 1) {
- const finalMsg = splitedMsg[0] + ': ' + referenceTag + splitedMsg.slice(1).join(':');
+ const finalMsg = `${splitedMsg[0]}: ${referenceTag}${splitedMsg.slice(1).join(':')}`;
writeFileSync(msgPath, finalMsg);
}
}
diff --git a/Jenkinsfile b/Jenkinsfile
index 59bf09e22..27bf4f82f 100644
--- a/Jenkinsfile
+++ b/Jenkinsfile
@@ -108,7 +108,6 @@ pipeline {
}
stage('E2E') {
environment {
- CREDS = credentials('docker-registry')
COMPOSE_PROJECT = "${PROJECT_NAME}-${env.BUILD_ID}"
COMPOSE_PARAMS = "-p ${env.COMPOSE_PROJECT} -f test/cypress/docker-compose.yml --project-directory ."
}
@@ -118,23 +117,24 @@ pipeline {
sh 'rm -rf test/cypress/screenshots'
env.COMPOSE_TAG = PROTECTED_BRANCH.contains(env.CHANGE_TARGET) ? env.CHANGE_TARGET : 'dev'
- def image = docker.build('lilium-dev', '-f docs/Dockerfile.dev docs')
-
- sh 'docker login --username $CREDS_USR --password $CREDS_PSW $REGISTRY'
- sh "docker-compose ${env.COMPOSE_PARAMS} pull back"
- sh "docker-compose ${env.COMPOSE_PARAMS} pull db"
- sh "docker-compose ${env.COMPOSE_PARAMS} up -d"
-
- def modules = sh(script: "node test/cypress/docker/find/find.js ${env.COMPOSE_TAG}", returnStdout: true).trim()
+ def modules = sh(
+ script: "node test/cypress/docker/find/find.js ${env.COMPOSE_TAG}",
+ returnStdout: true
+ ).trim()
echo "E2E MODULES: ${modules}"
- image.inside("--network ${env.COMPOSE_PROJECT}_default -e CI -e TZ --init") {
- sh "sh test/cypress/docker/cypressParallel.sh 1 '${modules}'"
+
+ script {
+ def image = docker.build('lilium-dev', '-f docs/Dockerfile.dev docs')
+ sh "docker compose ${env.COMPOSE_PARAMS} up -d"
+ image.inside("--network ${env.COMPOSE_PROJECT}_default -e CI -e TZ --init") {
+ sh "sh test/cypress/docker/cypressParallel.sh 1 '${modules}'"
+ }
}
}
}
post {
always {
- sh "docker-compose ${env.COMPOSE_PARAMS} down -v"
+ sh "docker compose ${env.COMPOSE_PARAMS} down -v"
archiveArtifacts artifacts: 'test/cypress/screenshots/**/*', allowEmptyArchive: true
junit(
testResults: 'junit/e2e-*.xml',
@@ -153,17 +153,8 @@ pipeline {
VERSION = readFile 'VERSION.txt'
}
steps {
- script {
- sh 'quasar build'
-
- def baseImage = "salix-frontend:${env.VERSION}"
- def image = docker.build(baseImage, ".")
- docker.withRegistry("https://${env.REGISTRY}", 'docker-registry') {
- image.push()
- image.push(env.BRANCH_NAME)
- if (IS_LATEST) image.push('latest')
- }
- }
+ sh 'quasar build'
+ dockerBuild 'salix-frontend', '.'
}
}
stage('Deploy') {
@@ -186,3 +177,53 @@ pipeline {
}
}
+def dockerBuild(imageName, context, dockerfile = null) {
+ if (dockerfile == null)
+ dockerfile = "${context}/Dockerfile"
+
+ def certDir = '/home/jenkins/.buildkit/certs'
+ def buildxArgs = [
+ "--name=buildkitd",
+ "--driver=remote",
+ "--driver-opt="
+ + "cacert=${certDir}/ca.pem,"
+ + "cert=${certDir}/cert.pem,"
+ + "key=${certDir}/key.pem,"
+ + "servername=buildkitd",
+ "tcp://buildkitd:1234"
+ ]
+
+ def cacheImage = "${env.REGISTRY_CACHE}/${imageName}"
+ def pushImage = "${env.REGISTRY}/${imageName}"
+ def baseImage = "${pushImage}:${env.VERSION}"
+
+ def buildArgs = [
+ context,
+ "--push",
+ "--builder=buildkitd",
+ "--file=${dockerfile}",
+ "--cache-from=type=registry,ref=${cacheImage}:cache-${env.BRANCH_NAME}",
+ "--cache-from=type=registry,ref=${cacheImage}:cache-dev",
+ "--cache-to=type=registry,ref=${cacheImage}:cache-${env.BRANCH_NAME},mode=max",
+ "--tag=${pushImage}:${env.BRANCH_NAME}"
+ ]
+
+ def isLatest = ['master', 'main'].contains(env.BRANCH_NAME)
+ if (isLatest)
+ buildArgs.push("--tag=${pushImage}:latest")
+
+ // FIXME: Nested docker.withRegistry() does not work
+ // https://issues.jenkins.io/browse/JENKINS-59777
+ withCredentials([usernamePassword(
+ credentialsId: 'registry-cache',
+ usernameVariable: 'CACHE_USR',
+ passwordVariable: 'CACHE_PSW')
+ ]) {
+ docker.withRegistry("https://${env.REGISTRY}", 'docker-registry') {
+ sh 'echo "$CACHE_PSW" | docker login --username "$CACHE_USR" --password-stdin "http://$REGISTRY_CACHE"'
+ sh "docker buildx create ${buildxArgs.join(' ')}"
+ docker.build(baseImage, buildArgs.join(' '))
+ }
+ }
+}
+
diff --git a/cypress.config.js b/cypress.config.js
index d9cdbe728..90d950450 100644
--- a/cypress.config.js
+++ b/cypress.config.js
@@ -1,6 +1,9 @@
import { defineConfig } from 'cypress';
-let urlHost, reporter, reporterOptions, timeouts;
+let urlHost;
+let reporter;
+let reporterOptions;
+let timeouts;
if (process.env.CI) {
urlHost = 'front';
@@ -44,6 +47,7 @@ export default defineConfig({
supportFile: 'test/cypress/support/index.js',
videosFolder: 'test/cypress/videos',
downloadsFolder: 'test/cypress/downloads',
+ tmpUploadFolder: 'test/cypress/storage/tmp/dms',
video: false,
specPattern: 'test/cypress/integration/**/*.spec.js',
experimentalRunAllSpecs: true,
@@ -60,5 +64,6 @@ export default defineConfig({
...timeouts,
includeShadowDom: true,
waitForAnimations: true,
+ testIsolation: false,
},
});
diff --git a/index.html b/index.html
index c1bd4681b..63b2f2f51 100644
--- a/index.html
+++ b/index.html
@@ -1,4 +1,4 @@
-
+
<%= productName %>
@@ -12,7 +12,12 @@
content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width<% if (ctx.mode.cordova || ctx.mode.capacitor) { %>, viewport-fit=cover<% } %>"
/>
-
+
diff --git a/package.json b/package.json
index 19b4c7a6f..f903a5ab6 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "salix-front",
- "version": "25.16.0",
+ "version": "25.18.0",
"description": "Salix frontend",
"productName": "Salix",
"author": "Verdnatura",
diff --git a/postcss.config.js b/postcss.config.js
index 9ec43d0cb..164f207d4 100644
--- a/postcss.config.js
+++ b/postcss.config.js
@@ -1,4 +1,3 @@
-/* eslint-disable */
// https://github.com/michael-ciniawsky/postcss-load-config
import autoprefixer from 'autoprefixer';
diff --git a/quasar.config.js b/quasar.config.js
index 2bc0be37f..227f5840c 100644
--- a/quasar.config.js
+++ b/quasar.config.js
@@ -13,7 +13,7 @@ import VueI18nPlugin from '@intlify/unplugin-vue-i18n/vite';
import path from 'path';
const target = `http://${process.env.CI ? 'back' : 'localhost'}:3000`;
-export default configure(function (/* ctx */) {
+export default configure((/* ctx */) => {
return {
eslint: {
// fix: true,
diff --git a/quasar.config.js.temporary.compiled.1744020058024.mjs b/quasar.config.js.temporary.compiled.1744020058024.mjs
deleted file mode 100644
index 54ecb84d9..000000000
--- a/quasar.config.js.temporary.compiled.1744020058024.mjs
+++ /dev/null
@@ -1,227 +0,0 @@
-/* eslint-disable */
-/**
- * THIS FILE IS GENERATED AUTOMATICALLY.
- * 1. DO NOT edit this file directly as it won't do anything.
- * 2. EDIT the original quasar.config file INSTEAD.
- * 3. DO NOT git commit this file. It should be ignored.
- *
- * This file is still here because there was an error in
- * the original quasar.config file and this allows you to
- * investigate the Node.js stack error.
- *
- * After you fix the original file, this file will be
- * deleted automatically.
- **/
-
-
-// quasar.config.js
-import { configure } from "quasar/wrappers";
-import VueI18nPlugin from "@intlify/unplugin-vue-i18n/vite";
-import path from "path";
-var __quasar_inject_dirname__ = "/home/jsegarra/Projects/salix-front";
-var target = `http://${process.env.CI ? "back" : "localhost"}:3000`;
-var quasar_config_default = configure(function() {
- return {
- eslint: {
- // fix: true,
- // include = [],
- // exclude = [],
- // rawOptions = {},
- warnings: true,
- errors: true
- },
- // https://v2.quasar.dev/quasar-cli/prefetch-feature
- // preFetch: true,
- // app boot file (/src/boot)
- // --> boot files are part of "main.js"
- // https://v2.quasar.dev/quasar-cli/boot-files
- boot: ["i18n", "axios", "vnDate", "validations", "quasar", "quasar.defaults"],
- // https://v2.quasar.dev/quasar-cli-vite/quasar-config-js#css
- css: ["app.scss"],
- // https://github.com/quasarframework/quasar/tree/dev/extras
- extras: [
- // 'ionicons-v4',
- // 'mdi-v5',
- // 'fontawesome-v6',
- // 'eva-icons',
- // 'themify',
- // 'line-awesome',
- // 'roboto-font-latin-ext', // this or either 'roboto-font', NEVER both!
- "roboto-font",
- "material-icons-outlined",
- "material-symbols-outlined"
- ],
- // Full list of options: https://v2.quasar.dev/quasar-cli-vite/quasar-config-js#build
- build: {
- target: {
- browser: ["es2022", "edge88", "firefox78", "chrome87", "safari13.1"],
- node: "node20"
- },
- vueRouterMode: "hash",
- // available values: 'hash', 'history'
- // vueRouterBase,
- // vueDevtools,
- // vueOptionsAPI: false,
- // rebuildCache: true, // rebuilds Vite/linter/etc cache on startup
- // publicPath: '/',
- // analyze: true,
- // env: {},
- rawDefine: {
- "process.env.NODE_ENV": JSON.stringify(process.env.NODE_ENV)
- },
- // ignorePublicFolder: true,
- // minify: false,
- // polyfillModulePreload: true,
- // distDir
- extendViteConf(viteConf) {
- delete viteConf.build.polyfillModulePreload;
- viteConf.build.modulePreload = {
- polyfill: false
- };
- },
- // viteVuePluginOptions: {},
- alias: {
- composables: path.join(__quasar_inject_dirname__, "./src/composables"),
- filters: path.join(__quasar_inject_dirname__, "./src/filters")
- },
- vitePlugins: [
- [
- VueI18nPlugin({
- strictMessage: false,
- runtimeOnly: false,
- include: [
- path.resolve(__quasar_inject_dirname__, "./src/i18n/locale/**"),
- path.resolve(__quasar_inject_dirname__, "./src/pages/**/locale/**")
- ]
- })
- ]
- ]
- },
- // Full list of options: https://v2.quasar.dev/quasar-cli-vite/quasar-config-js#devServer
- devServer: {
- server: {
- type: "http"
- },
- proxy: {
- "/api": {
- target,
- logLevel: "debug",
- changeOrigin: true,
- secure: false
- }
- },
- open: false,
- allowedHosts: [
- "front",
- // Agrega este nombre de host
- "localhost"
- // Opcional, para pruebas locales
- ]
- },
- // https://v2.quasar.dev/quasar-cli-vite/quasar-config-js#framework
- framework: {
- config: {
- config: {
- dark: "auto"
- }
- },
- lang: "en-GB",
- // iconSet: 'material-icons', // Quasar icon set
- // lang: 'en-US', // Quasar language pack
- // For special cases outside of where the auto-import strategy can have an impact
- // (like functional components as one of the examples),
- // you can manually specify Quasar components/directives to be available everywhere:
- //
- // components: [],
- // directives: [],
- // Quasar plugins
- plugins: ["Notify", "Dialog"],
- all: "auto",
- autoImportComponentCase: "pascal"
- },
- // animations: 'all', // --- includes all animations
- // https://v2.quasar.dev/options/animations
- animations: [],
- // https://v2.quasar.dev/quasar-cli-vite/quasar-config-js#property-sourcefiles
- // sourceFiles: {
- // rootComponent: 'src/App.vue',
- // router: 'src/router/index',
- // store: 'src/store/index',
- // registerServiceWorker: 'src-pwa/register-service-worker',
- // serviceWorker: 'src-pwa/custom-service-worker',
- // pwaManifestFile: 'src-pwa/manifest.json',
- // electronMain: 'src-electron/electron-main',
- // electronPreload: 'src-electron/electron-preload'
- // },
- // https://v2.quasar.dev/quasar-cli/developing-ssr/configuring-ssr
- ssr: {
- // ssrPwaHtmlFilename: 'offline.html', // do NOT use index.html as name!
- // will mess up SSR
- // extendSSRWebserverConf (esbuildConf) {},
- // extendPackageJson (json) {},
- pwa: false,
- // manualStoreHydration: true,
- // manualPostHydrationTrigger: true,
- prodPort: 3e3,
- // The default port that the production server should use
- // (gets superseded if process.env.PORT is specified at runtime)
- middlewares: [
- "render"
- // keep this as last one
- ]
- },
- // https://v2.quasar.dev/quasar-cli/developing-pwa/configuring-pwa
- pwa: {
- workboxMode: "generateSW",
- // or 'injectManifest'
- injectPwaMetaTags: true,
- swFilename: "sw.js",
- manifestFilename: "manifest.json",
- useCredentialsForManifestTag: false
- // useFilenameHashes: true,
- // extendGenerateSWOptions (cfg) {}
- // extendInjectManifestOptions (cfg) {},
- // extendManifestJson (json) {}
- // extendPWACustomSWConf (esbuildConf) {}
- },
- // Full list of options: https://v2.quasar.dev/quasar-cli/developing-cordova-apps/configuring-cordova
- cordova: {
- // noIosLegacyBuildFlag: true, // uncomment only if you know what you are doing
- },
- // Full list of options: https://v2.quasar.dev/quasar-cli/developing-capacitor-apps/configuring-capacitor
- capacitor: {
- hideSplashscreen: true
- },
- // Full list of options: https://v2.quasar.dev/quasar-cli/developing-electron-apps/configuring-electron
- electron: {
- // extendElectronMainConf (esbuildConf)
- // extendElectronPreloadConf (esbuildConf)
- inspectPort: 5858,
- bundler: "packager",
- // 'packager' or 'builder'
- packager: {
- // https://github.com/electron-userland/electron-packager/blob/master/docs/api.md#options
- // OS X / Mac App Store
- // appBundleId: '',
- // appCategoryType: '',
- // osxSign: '',
- // protocol: 'myapp://path',
- // Windows only
- // win32metadata: { ... }
- },
- builder: {
- // https://www.electron.build/configuration/configuration
- appId: "salix-frontend"
- }
- },
- // Full list of options: https://v2.quasar.dev/quasar-cli-vite/developing-browser-extensions/configuring-bex
- bex: {
- contentScripts: ["my-content-script"]
- // extendBexScriptsConf (esbuildConf) {}
- // extendBexManifestJson (json) {}
- }
- };
-});
-export {
- quasar_config_default as default
-};
diff --git a/quasar.extensions.json b/quasar.extensions.json
index 050f605cc..867769090 100644
--- a/quasar.extensions.json
+++ b/quasar.extensions.json
@@ -1,8 +1,6 @@
{
"@quasar/testing-unit-vitest": {
- "options": [
- "scripts"
- ]
+ "options": ["scripts"]
},
"@quasar/qcalendar": {}
}
diff --git a/quasar.testing.json b/quasar.testing.json
index a59d9af89..6957efe67 100644
--- a/quasar.testing.json
+++ b/quasar.testing.json
@@ -1,5 +1,5 @@
{
- "unit-vitest": {
- "runnerCommand": "vitest run"
- }
-}
\ No newline at end of file
+ "unit-vitest": {
+ "runnerCommand": "vitest run"
+ }
+}
diff --git a/src/App.vue b/src/App.vue
index 27cc34c38..bec50ae9d 100644
--- a/src/App.vue
+++ b/src/App.vue
@@ -2,6 +2,7 @@
import { onMounted } from 'vue';
import { useQuasar, Dark } from 'quasar';
import { useI18n } from 'vue-i18n';
+import VnScroll from './components/common/VnScroll.vue';
const quasar = useQuasar();
const { availableLocales, locale, fallbackLocale } = useI18n();
@@ -38,6 +39,7 @@ quasar.iconMapFn = (iconName) => {
+
diff --git a/src/components/EntityCalendarGrid.vue b/src/components/EntityCalendarGrid.vue
new file mode 100644
index 000000000..19fb5a061
--- /dev/null
+++ b/src/components/EntityCalendarGrid.vue
@@ -0,0 +1,126 @@
+
+
+
+
+
+
+ emit('onDateSelected', data)"
+ />
+
+
+
diff --git a/src/components/FilterTravelForm.vue b/src/components/FilterTravelForm.vue
index 4aad327b2..f2a7a09eb 100644
--- a/src/components/FilterTravelForm.vue
+++ b/src/components/FilterTravelForm.vue
@@ -156,6 +156,9 @@ const selectTravel = ({ id }) => {
option-label="name"
option-value="id"
v-model="travelFilterParams.warehouseOutFk"
+ :where="{
+ isOrigin: true,
+ }"
/>
{
option-label="name"
option-value="id"
v-model="travelFilterParams.warehouseInFk"
+ :where="{
+ isDestiny: true,
+ }"
/>
{},
},
+ preventSubmit: {
+ type: Boolean,
+ default: false,
+ },
+ customMethod: {
+ type: String,
+ default: null,
+ },
});
-const emit = defineEmits(['onFetch', 'onDataSaved']);
+const emit = defineEmits(['onFetch', 'onDataSaved', 'submit']);
const modelValue = computed(
() => $props.model ?? `formModel_${route?.meta?.title ?? route.name}`,
).value;
@@ -234,7 +241,9 @@ async function save() {
const url =
$props.urlCreate || $props.urlUpdate || $props.url || arrayData.store.url;
const response = await Promise.resolve(
- $props.saveFn ? $props.saveFn(body) : axios[method](url, body),
+ $props.saveFn
+ ? $props.saveFn(body)
+ : axios[$props.customMethod ?? method](url, body),
);
if ($props.urlCreate) notify('globals.dataCreated', 'positive');
@@ -301,7 +310,7 @@ function onBeforeSave(formData, originalData) {
);
}
async function onKeyup(evt) {
- if (evt.key === 'Enter' && !('prevent-submit' in attrs)) {
+ if (evt.key === 'Enter' && !$props.preventSubmit) {
const input = evt.target;
if (input.type == 'textarea' && evt.shiftKey) {
let { selectionStart, selectionEnd } = input;
@@ -330,6 +339,7 @@ defineExpose({
{
-
+
{
-
+