feat: QBtn
gitea/salix-front/pipeline/pr-dev This commit looks good Details

This commit is contained in:
Javier Segarra 2024-05-20 10:34:28 +02:00
parent 0884fb2717
commit b16ccc8d1f
8 changed files with 147 additions and 4 deletions

View File

@ -39,6 +39,10 @@ module.exports = configure(function (/* ctx */) {
'customQTh', 'customQTh',
// 'customQInput', // 'customQInput',
// 'customQSelect', // 'customQSelect',
'customQBtn',
'customQBtnGroup',
'vnTranslate', 'vnTranslate',
], ],

51
src/boot/customQBtn.js Normal file
View File

@ -0,0 +1,51 @@
import { boot } from 'quasar/wrappers';
import i18n from 'src/i18n';
export default boot(({ app }) => {
// Usar vue-i18n en la aplicación
app.use(i18n);
// Mixin global para añadir la clase CSS y traducir etiquetas QInput y QSelect
app.mixin({
mounted() {
this.styleBtn(this.$el);
},
methods: {
styleBtn(el) {
if (!el) return;
if (this.$el?.__vueParentComponent?.type?.name === 'QBtn') {
// Recorrer los elementos hijos
const _children = el.children || [];
const childrens = Array.from(_children).filter((child) =>
child.classList.contains('q-btn')
);
for (const btn of childrens) {
btn.classList.add();
}
/* for (let i = 0; i < children.length; i++) {
const child = children[i];
if (
child.tagName === 'DIV' &&
child.classList.contains('q-field__inner')
) {
// Detectar si es un QInput o QSelect
const input = child.querySelector('input');
if (input?.__vueParentComponent?.type?.name === 'QSelect') {
// Traducción de la etiqueta
const labelElement =
child.querySelector('.q-field__label');
if (labelElement) {
const labelKey = labelElement.textContent.trim();
labelElement.textContent = this.$t(labelKey);
}
}
}
// Aplicar la lógica a los elementos hijos recursivamente
this.mixinQSelect(child);
}*/
}
},
},
});
});

View File

@ -0,0 +1,48 @@
import { boot } from 'quasar/wrappers';
import i18n from 'src/i18n';
export default boot(({ app }) => {
// Usar vue-i18n en la aplicación
app.use(i18n);
// Mixin global para añadir la clase CSS y traducir etiquetas QInput y QSelect
app.mixin({
mounted() {
this.styleBtnGroup(this.$el);
},
methods: {
styleBtnGroup(el) {
if (!el) return;
if (this.$el?.__vueParentComponent?.type?.name === 'QBtnGroup') {
// Recorrer los elementos hijos
this.$el.classList.add('q-gutter-x-sm');
this.$el.style.columnGap = '10px';
/*for (let i = 0; i < children.length; i++) {
const child = children[i];
if (
child.tagName === 'DIV' &&
child.classList.contains('q-field__inner')
) {
// Detectar si es un QInput o QSelect
const input = child.querySelector('input');
if (input?.__vueParentComponent?.type?.name === 'QSelect') {
// Traducción de la etiqueta
const labelElement =
child.querySelector('.q-field__label');
if (labelElement) {
const labelKey = labelElement.textContent.trim();
labelElement.textContent = this.$t(labelKey);
}
}
}
// Aplicar la lógica a los elementos hijos recursivamente
this.mixinQSelect(child);
}*/
}
},
},
});
});

30
src/boot/defaults/qBtn.js Normal file
View File

@ -0,0 +1,30 @@
import { QBtn } from 'quasar';
import { QBtnGroup } from 'quasar';
QBtn.props.size = {
type: QBtn.props.size,
default: 'md',
};
// QBtn.props.flat = {
// type: QBtn.props.flat,
// default: false,
// };
// QBtnGroup.props.class = {
// type: QBtn.props.class,
// default: ['q-gutter-x-sm'],
// };
// QBtnGroup.props.style = {
// type: QBtn.props.style,
// default: 'column-gap: 10px',
// };
QBtnGroup.props.push = {
type: QBtn.props.push,
default: true,
};
// QTable.props.columns = {
// type: QTable.props.columns,
// align: 'right',
// format: (value) => `${value}*`,
// };
// QTable.props.noDataLabel = {
// default: 'asd',
// };

View File

@ -1,3 +1,4 @@
export * from './defaults/qTable'; export * from './defaults/qTable';
export * from './defaults/qInput'; export * from './defaults/qInput';
export * from './defaults/qSelect'; export * from './defaults/qSelect';
export * from './defaults/qBtn';

View File

@ -2,8 +2,17 @@ import { boot } from 'quasar/wrappers';
import i18n from 'src/i18n'; import i18n from 'src/i18n';
import { QInput, QSelect } from 'quasar'; import { QInput, QSelect } from 'quasar';
import VnLv from 'src/components/ui/VnLv.vue'; import VnLv from 'src/components/ui/VnLv.vue';
import { QBtn } from 'quasar';
import { QBtnGroup } from 'quasar';
import { QBtnDropdown } from 'quasar';
const VALID_QUASAR_ELEMENTS = [QSelect.name, QInput.name]; const VALID_QUASAR_ELEMENTS = [
QSelect.name,
QInput.name,
QBtn.name,
QBtnGroup.name,
QBtnDropdown.name,
];
const VALID_VN_ELEMENTS = [VnLv.__name]; const VALID_VN_ELEMENTS = [VnLv.__name];
export default boot(({ app }) => { export default boot(({ app }) => {
// Usar vue-i18n en la aplicación // Usar vue-i18n en la aplicación

View File

@ -288,7 +288,7 @@ watch(formUrl, async () => {
</VnPaginate> </VnPaginate>
<SkeletonTable v-if="!formData" /> <SkeletonTable v-if="!formData" />
<Teleport to="#st-actions" v-if="stateStore?.isSubToolbarShown()"> <Teleport to="#st-actions" v-if="stateStore?.isSubToolbarShown()">
<QBtnGroup push style="column-gap: 10px"> <QBtnGroup push>
<slot name="moreBeforeActions" /> <slot name="moreBeforeActions" />
<QBtn <QBtn
:label="tMobile('globals.remove')" :label="tMobile('globals.remove')"

View File

@ -262,13 +262,13 @@ defineExpose({
v-if="stateStore?.isSubToolbarShown() && componentIsRendered" v-if="stateStore?.isSubToolbarShown() && componentIsRendered"
> >
<div v-if="$props.defaultActions"> <div v-if="$props.defaultActions">
<QBtnGroup push class="q-gutter-x-sm"> <QBtnGroup>
<slot name="moreActions" /> <slot name="moreActions" />
<QBtn <QBtn
:label="tMobile(defaultButtons.reset.label)" :label="tMobile(defaultButtons.reset.label)"
:color="defaultButtons.reset.color" :color="defaultButtons.reset.color"
:icon="defaultButtons.reset.icon" :icon="defaultButtons.reset.icon"
flat flat="false"
@click="reset" @click="reset"
:disable="!hasChanges" :disable="!hasChanges"
:title="t(defaultButtons.reset.label)" :title="t(defaultButtons.reset.label)"