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/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/src/components/FormModel.vue b/src/components/FormModel.vue index 43a0d63f0..29f5f1a5a 100644 --- a/src/components/FormModel.vue +++ b/src/components/FormModel.vue @@ -102,6 +102,10 @@ const $props = defineProps({ type: Boolean, default: false, }, + customMethod: { + type: String, + default: null, + }, }); const emit = defineEmits(['onFetch', 'onDataSaved', 'submit']); const modelValue = computed( @@ -237,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'); diff --git a/src/components/VnTable/VnColumn.vue b/src/components/VnTable/VnColumn.vue index b6cc5665f..05c764d73 100644 --- a/src/components/VnTable/VnColumn.vue +++ b/src/components/VnTable/VnColumn.vue @@ -180,10 +180,10 @@ const col = computed(() => { ) newColumn.component = 'checkbox'; if ($props.default && !newColumn.component) newColumn.component = $props.default; - + if (typeof newColumn.component !== 'string') { - newColumn.attrs = { ...newColumn.component.attrs, autofocus: $props.autofocus }; - newColumn.event = { ...newColumn.component.event, ...$props?.eventHandlers }; + newColumn.attrs = { ...newColumn.component?.attrs, autofocus: $props.autofocus }; + newColumn.event = { ...newColumn.component?.event, ...$props?.eventHandlers }; } return newColumn; }); diff --git a/src/components/common/VnLog.vue b/src/components/common/VnLog.vue index 6e9128a43..8d9cacac2 100644 --- a/src/components/common/VnLog.vue +++ b/src/components/common/VnLog.vue @@ -1,7 +1,7 @@