Merge branch '6768-VnLocationRefact' of https://gitea.verdnatura.es/verdnatura/salix-front into 6768-VnLocationRefact
gitea/salix-front/pipeline/pr-dev This commit looks good
Details
gitea/salix-front/pipeline/pr-dev This commit looks good
Details
This commit is contained in:
commit
32685efc1c
|
@ -1,6 +1,5 @@
|
|||
FROM node:stretch-slim
|
||||
RUN curl -fsSL https://bun.sh/install | bash
|
||||
RUN bun install -g @quasar/cli
|
||||
RUN npm install -g @quasar/cli
|
||||
WORKDIR /app
|
||||
COPY dist/spa ./
|
||||
CMD ["quasar", "serve", "./", "--history", "--hostname", "0.0.0.0"]
|
||||
|
|
|
@ -2,30 +2,46 @@
|
|||
|
||||
def PROTECTED_BRANCH
|
||||
|
||||
pre: {
|
||||
switch (env.BRANCH_NAME) {
|
||||
case 'test':
|
||||
env.NODE_ENV = 'test'
|
||||
env.BACK_REPLICAS = 2
|
||||
break
|
||||
case 'master':
|
||||
env.NODE_ENV = 'production'
|
||||
env.BACK_REPLICAS = 4
|
||||
break
|
||||
default:
|
||||
env.NODE_ENV = 'dev'
|
||||
env.BACK_REPLICAS = 1
|
||||
def BRANCH_ENV = [
|
||||
test: 'test',
|
||||
master: 'production'
|
||||
]
|
||||
|
||||
node {
|
||||
stage('Setup') {
|
||||
env.FRONT_REPLICAS = 1
|
||||
env.NODE_ENV = BRANCH_ENV[env.BRANCH_NAME] ?: 'dev'
|
||||
|
||||
PROTECTED_BRANCH = [
|
||||
'dev',
|
||||
'test',
|
||||
'master'
|
||||
].contains(env.BRANCH_NAME)
|
||||
|
||||
// https://www.jenkins.io/doc/book/pipeline/jenkinsfile/#using-environment-variables
|
||||
echo "NODE_NAME: ${env.NODE_NAME}"
|
||||
echo "WORKSPACE: ${env.WORKSPACE}"
|
||||
|
||||
configFileProvider([
|
||||
configFile(fileId: 'salix-front.properties',
|
||||
variable: 'PROPS_FILE')
|
||||
]) {
|
||||
def props = readProperties file: PROPS_FILE
|
||||
props.each {key, value -> env."${key}" = value }
|
||||
props.each {key, value -> echo "${key}: ${value}" }
|
||||
}
|
||||
|
||||
if (PROTECTED_BRANCH) {
|
||||
configFileProvider([
|
||||
configFile(fileId: "salix-front.branch.${env.BRANCH_NAME}",
|
||||
variable: 'BRANCH_PROPS_FILE')
|
||||
]) {
|
||||
def props = readProperties file: BRANCH_PROPS_FILE
|
||||
props.each {key, value -> env."${key}" = value }
|
||||
props.each {key, value -> echo "${key}: ${value}" }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PROTECTED_BRANCH = [
|
||||
'dev',
|
||||
'test',
|
||||
'master'
|
||||
].contains(env.BRANCH_NAME)
|
||||
|
||||
// Uncomment to enable debugging
|
||||
// https://loopback.io/doc/en/lb3/Setting-debug-strings.html#debug-strings-reference
|
||||
//env.DEBUG = 'strong-remoting:shared-method'
|
||||
}
|
||||
|
||||
pipeline {
|
||||
|
@ -33,6 +49,9 @@ pipeline {
|
|||
options {
|
||||
disableConcurrentBuilds()
|
||||
}
|
||||
tools {
|
||||
nodejs 'node-v18'
|
||||
}
|
||||
environment {
|
||||
PROJECT_NAME = 'lilium'
|
||||
STACK_NAME = "${env.PROJECT_NAME}-${env.BRANCH_NAME}"
|
||||
|
@ -43,9 +62,7 @@ pipeline {
|
|||
NODE_ENV = ""
|
||||
}
|
||||
steps {
|
||||
nodejs('node-v18') {
|
||||
sh 'bun install --no-audit --prefer-offline'
|
||||
}
|
||||
sh 'npm install --prefer-offline'
|
||||
}
|
||||
}
|
||||
stage('Test') {
|
||||
|
@ -55,11 +72,17 @@ pipeline {
|
|||
environment {
|
||||
NODE_ENV = ""
|
||||
}
|
||||
parallel {
|
||||
stage('Frontend') {
|
||||
steps {
|
||||
nodejs('node-v18') {
|
||||
sh 'bun run test:unit:ci'
|
||||
steps {
|
||||
sh 'npm run test:unit:ci'
|
||||
}
|
||||
post {
|
||||
always {
|
||||
script {
|
||||
try {
|
||||
junit 'junitresults.xml'
|
||||
junit 'junit.xml'
|
||||
} catch (e) {
|
||||
echo e.toString()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -73,8 +96,10 @@ pipeline {
|
|||
CREDENTIALS = credentials('docker-registry')
|
||||
}
|
||||
steps {
|
||||
nodejs('node-v18') {
|
||||
sh 'quasar build'
|
||||
sh 'quasar build'
|
||||
script {
|
||||
def packageJson = readJSON file: 'package.json'
|
||||
env.VERSION = packageJson.version
|
||||
}
|
||||
dockerBuild()
|
||||
}
|
||||
|
@ -87,22 +112,12 @@ pipeline {
|
|||
DOCKER_HOST = "${env.SWARM_HOST}"
|
||||
}
|
||||
steps {
|
||||
script {
|
||||
def packageJson = readJSON file: 'package.json'
|
||||
env.VERSION = packageJson.version
|
||||
}
|
||||
sh "docker stack deploy --with-registry-auth --compose-file docker-compose.yml ${env.STACK_NAME}"
|
||||
}
|
||||
}
|
||||
}
|
||||
post {
|
||||
always {
|
||||
script {
|
||||
if (!PROTECTED_BRANCH) {
|
||||
try {
|
||||
junit 'junitresults.xml'
|
||||
junit 'junit.xml'
|
||||
} catch (e) {
|
||||
echo e.toString()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,20 +1,21 @@
|
|||
<script setup>
|
||||
import { ref } from 'vue';
|
||||
import { onMounted, ref } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useRouter } from 'vue-router';
|
||||
import { useState } from 'src/composables/useState';
|
||||
import { useQuasar } from 'quasar';
|
||||
|
||||
import DepartmentDescriptorProxy from 'src/pages/Department/Card/DepartmentDescriptorProxy.vue';
|
||||
import CreateDepartmentChild from '../CreateDepartmentChild.vue';
|
||||
|
||||
import axios from 'axios';
|
||||
import useNotify from 'src/composables/useNotify.js';
|
||||
import { useRouter } from 'vue-router';
|
||||
|
||||
const quasar = useQuasar();
|
||||
const { t } = useI18n();
|
||||
const router = useRouter();
|
||||
const { notify } = useNotify();
|
||||
const state = useState();
|
||||
const router = useRouter();
|
||||
|
||||
const treeRef = ref(null);
|
||||
const treeRef = ref();
|
||||
const showCreateNodeFormVal = ref(false);
|
||||
const creationNodeSelectedId = ref(null);
|
||||
const expanded = ref([]);
|
||||
|
@ -24,30 +25,35 @@ const nodes = ref([{ id: null, name: t('Departments'), sons: true, children: [{}
|
|||
const fetchedChildrensSet = ref(new Set());
|
||||
|
||||
const onNodeExpanded = (nodeKeysArray) => {
|
||||
// Verificar si el nodo ya fue expandido
|
||||
if (!fetchedChildrensSet.value.has(nodeKeysArray.at(-1))) {
|
||||
fetchedChildrensSet.value.add(nodeKeysArray.at(-1));
|
||||
fetchNodeLeaves(nodeKeysArray.at(-1)); // Llamar a la función para obtener los nodos hijos
|
||||
fetchNodeLeaves(nodeKeysArray.at(-1));
|
||||
}
|
||||
|
||||
state.set('Tree', nodeKeysArray);
|
||||
};
|
||||
|
||||
const fetchNodeLeaves = async (nodeKey) => {
|
||||
try {
|
||||
const node = treeRef.value.getNodeByKey(nodeKey);
|
||||
const node = treeRef.value?.getNodeByKey(nodeKey);
|
||||
|
||||
if (!node || node.sons === 0) return;
|
||||
|
||||
const params = { parentId: node.id };
|
||||
const response = await axios.get('/departments/getLeaves', { params });
|
||||
|
||||
// Si hay datos en la respuesta y tiene hijos, agregarlos al nodo actual
|
||||
if (response.data) {
|
||||
node.children = response.data;
|
||||
node.children.forEach((node) => {
|
||||
if (node.sons) node.children = [{}];
|
||||
node.children = response.data.map((n) => {
|
||||
const hasChildrens = n.sons > 0;
|
||||
|
||||
n.children = hasChildrens ? [{}] : null;
|
||||
n.clickable = true;
|
||||
return n;
|
||||
});
|
||||
}
|
||||
|
||||
state.set('Tree', node);
|
||||
} catch (err) {
|
||||
console.error('Error fetching department leaves');
|
||||
console.error('Error fetching department leaves', err);
|
||||
throw new Error();
|
||||
}
|
||||
};
|
||||
|
@ -84,10 +90,49 @@ const onNodeCreated = async () => {
|
|||
await fetchNodeLeaves(creationNodeSelectedId.value);
|
||||
};
|
||||
|
||||
const redirectToDepartmentSummary = (id) => {
|
||||
if (!id) return;
|
||||
router.push({ name: 'DepartmentSummary', params: { id } });
|
||||
};
|
||||
onMounted(async (n) => {
|
||||
const tree = [...state.get('Tree'), 1];
|
||||
const lastStateTree = state.get('TreeState');
|
||||
if (tree) {
|
||||
for (let n of tree) {
|
||||
await fetchNodeLeaves(n);
|
||||
}
|
||||
expanded.value = tree;
|
||||
|
||||
if (lastStateTree) {
|
||||
tree.push(lastStateTree);
|
||||
await fetchNodeLeaves(lastStateTree);
|
||||
}
|
||||
}
|
||||
setTimeout(() => {
|
||||
if (lastStateTree) {
|
||||
document.getElementById(lastStateTree).scrollIntoView();
|
||||
}
|
||||
}, 1000);
|
||||
});
|
||||
|
||||
function handleEvent(type, event, node) {
|
||||
const isParent = node.sons > 0;
|
||||
const lastId = isParent ? node.id : node.parentFk;
|
||||
|
||||
switch (type) {
|
||||
case 'path':
|
||||
state.set('TreeState', lastId);
|
||||
node.id && router.push({ path: `/department/department/${node.id}/summary` });
|
||||
break;
|
||||
|
||||
case 'tab':
|
||||
state.set('TreeState', lastId);
|
||||
node.id &&
|
||||
window.open(`#/department/department/${node.id}/summary`, '_blank');
|
||||
break;
|
||||
|
||||
default:
|
||||
node.id &&
|
||||
router.push({ path: `#/department/department/${node.id}/summary` });
|
||||
break;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
@ -99,15 +144,27 @@ const redirectToDepartmentSummary = (id) => {
|
|||
label-key="name"
|
||||
v-model:expanded="expanded"
|
||||
@update:expanded="onNodeExpanded($event)"
|
||||
:default-expand-all="true"
|
||||
>
|
||||
<template #default-header="{ node }">
|
||||
<div
|
||||
class="row justify-between full-width q-pr-md cursor-pointer"
|
||||
@click.stop="redirectToDepartmentSummary(node.id)"
|
||||
:id="node.id"
|
||||
class="qtr row justify-between full-width q-pr-md cursor-pointer"
|
||||
>
|
||||
<span class="text-uppercase">
|
||||
{{ node.name }}
|
||||
</span>
|
||||
<div>
|
||||
<span
|
||||
@click="handleEvent('row', $event, node)"
|
||||
class="cursor-pointer"
|
||||
>
|
||||
{{ node.name }}
|
||||
<DepartmentDescriptorProxy :id="node.id" />
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
@click.stop.exact="handleEvent('path', $event, node)"
|
||||
@click.ctrl.stop="handleEvent('tab', $event, node)"
|
||||
style="flex-grow: 1; width: 10px"
|
||||
></div>
|
||||
<div class="row justify-between" style="max-width: max-content">
|
||||
<QIcon
|
||||
v-if="node.id"
|
||||
|
@ -149,6 +206,11 @@ const redirectToDepartmentSummary = (id) => {
|
|||
</QCard>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
span {
|
||||
color: $primary;
|
||||
}
|
||||
</style>
|
||||
<i18n>
|
||||
es:
|
||||
Departments: Departamentos
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
<script setup>
|
||||
import DepartmentDescriptor from './DepartmentDescriptor.vue';
|
||||
import DepartmentSummaryDialog from './DepartmentSummaryDialog.vue';
|
||||
|
||||
const $props = defineProps({
|
||||
id: {
|
||||
type: Number,
|
||||
required: true,
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<QPopupProxy>
|
||||
<DepartmentDescriptor
|
||||
v-if="$props.id"
|
||||
:id="$props.id"
|
||||
:summary="DepartmentSummaryDialog"
|
||||
/>
|
||||
</QPopupProxy>
|
||||
</template>
|
|
@ -0,0 +1,29 @@
|
|||
<script setup>
|
||||
import { useDialogPluginComponent } from 'quasar';
|
||||
import DepartmentSummary from './DepartmentSummary.vue';
|
||||
|
||||
const $props = defineProps({
|
||||
id: {
|
||||
type: Number,
|
||||
required: true,
|
||||
},
|
||||
});
|
||||
|
||||
defineEmits([...useDialogPluginComponent.emits]);
|
||||
|
||||
const { dialogRef, onDialogHide } = useDialogPluginComponent();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<QDialog ref="dialogRef" @hide="onDialogHide">
|
||||
<DepartmentSummary v-if="$props.id" :id="$props.id" />
|
||||
</QDialog>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
.q-dialog .summary .header {
|
||||
position: sticky;
|
||||
z-index: $z-max;
|
||||
top: 0;
|
||||
}
|
||||
</style>
|
Loading…
Reference in New Issue