News
This commit is contained in:
parent
ec14ca334a
commit
14bef2383f
|
@ -179,10 +179,17 @@ const generateSqlQuery = () => {
|
|||
};
|
||||
|
||||
onMounted(async () => {
|
||||
if (!props.formInitialData && props.autoLoad) {
|
||||
if (!props.formInitialData) {
|
||||
fetchFormData();
|
||||
} else {
|
||||
formData.value = { ...props.formInitialData };
|
||||
// Como no se ejecuta la query fetchFormData y no se obtienen las columnas de la tabla, se inicializan con las keys del objeto formInitialData
|
||||
modelInfo.value = {
|
||||
columns: Object.keys(props.formInitialData).map(col => ({
|
||||
name: col
|
||||
})),
|
||||
data: [props.formInitialData]
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -197,7 +204,7 @@ defineExpose({
|
|||
<QForm
|
||||
v-if="!loading"
|
||||
ref="addressFormRef"
|
||||
class="column full-width"
|
||||
class="form"
|
||||
:class="separationBetweenInputs"
|
||||
@submit="submit()"
|
||||
>
|
||||
|
@ -224,12 +231,12 @@ defineExpose({
|
|||
<QBtn
|
||||
v-if="defaultActions"
|
||||
:label="t('save')"
|
||||
type="submit"
|
||||
:icon="showBottomActions ? undefined : 'check'"
|
||||
rounded
|
||||
no-caps
|
||||
flat
|
||||
:disabled="!showBottomActions && !updatedColumns.length"
|
||||
@click="submit()"
|
||||
/>
|
||||
<slot name="actions" :data="formData" />
|
||||
</component>
|
||||
|
@ -242,9 +249,16 @@ defineExpose({
|
|||
.form-container {
|
||||
width: 100%;
|
||||
height: max-content;
|
||||
padding: 0 !important;
|
||||
max-width: 544px;
|
||||
padding: 32px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.form {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 32px;
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -61,5 +61,6 @@ export default {
|
|||
adminNewsDetails: 'Afegir o editar notícia',
|
||||
//
|
||||
orderLoadedIntoBasket: 'Comanda carregada a la cistella!',
|
||||
at: 'a les'
|
||||
at: 'a les',
|
||||
back: 'Tornar'
|
||||
};
|
||||
|
|
|
@ -75,6 +75,7 @@ export default {
|
|||
//
|
||||
orderLoadedIntoBasket: 'Order loaded into basket!',
|
||||
at: 'at',
|
||||
back: 'Back',
|
||||
|
||||
orders: 'Orders',
|
||||
order: 'Pending order',
|
||||
|
|
|
@ -81,6 +81,7 @@ export default {
|
|||
//
|
||||
orderLoadedIntoBasket: '¡Pedido cargado en la cesta!',
|
||||
at: 'a las',
|
||||
back: 'Volver',
|
||||
|
||||
orders: 'Pedidos',
|
||||
order: 'Pedido pendiente',
|
||||
|
|
|
@ -61,5 +61,6 @@ export default {
|
|||
adminNewsDetails: 'Ajouter ou editer nouvelles',
|
||||
//
|
||||
orderLoadedIntoBasket: 'Commande chargée dans le panier!',
|
||||
at: 'à'
|
||||
at: 'à',
|
||||
back: 'Retour'
|
||||
};
|
||||
|
|
|
@ -62,5 +62,6 @@ export default {
|
|||
adminNewsDetails: 'Ajouter ou editer nouvelles',
|
||||
//
|
||||
orderLoadedIntoBasket: 'Pedido carregado na cesta!',
|
||||
at: 'às'
|
||||
at: 'às',
|
||||
back: 'Voltar'
|
||||
};
|
||||
|
|
|
@ -37,12 +37,18 @@ export const generateInsertSqlQuery = (
|
|||
columnsUpdated,
|
||||
createModelDefault
|
||||
) => {
|
||||
const columns = [createModelDefault.field, ...columnsUpdated].join(', ');
|
||||
const values = [
|
||||
createModelDefault.value,
|
||||
...columnsUpdated.map(colName => sanitizeValue(formData[colName]))
|
||||
].join(', ');
|
||||
const columns = createModelDefault.field
|
||||
? [createModelDefault.field, ...columnsUpdated].join(', ')
|
||||
: columnsUpdated.join(', ');
|
||||
|
||||
const values = createModelDefault.value
|
||||
? [
|
||||
createModelDefault.value,
|
||||
...columnsUpdated.map(colName => sanitizeValue(formData[colName]))
|
||||
].join(', ')
|
||||
: columnsUpdated
|
||||
.map(colName => sanitizeValue(formData[colName]))
|
||||
.join(', ');
|
||||
return `
|
||||
START TRANSACTION;
|
||||
INSERT INTO ${schema}.${table} (${columns}) VALUES (${values});
|
||||
|
|
|
@ -117,7 +117,6 @@ onMounted(() => getCountries());
|
|||
|
||||
<i18n lang="yaml">
|
||||
en-US:
|
||||
back: Back
|
||||
accept: Accept
|
||||
addEditAddress: Add or edit address
|
||||
name: Consignee
|
||||
|
@ -128,7 +127,6 @@ en-US:
|
|||
province: Province
|
||||
addressChangedSuccessfully: Address changed successfully
|
||||
es-ES:
|
||||
back: Volver
|
||||
accept: Aceptar
|
||||
addEditAddress: Añadir o modificar dirección
|
||||
name: Consignatario
|
||||
|
@ -139,7 +137,6 @@ es-ES:
|
|||
province: Distrito
|
||||
addressChangedSuccessfully: Dirección modificada correctamente
|
||||
ca-ES:
|
||||
back: Tornar
|
||||
accept: Acceptar
|
||||
addEditAddress: Afegir o modificar adreça
|
||||
name: Consignatari
|
||||
|
@ -150,7 +147,6 @@ ca-ES:
|
|||
province: Província
|
||||
addressChangedSuccessfully: Adreça modificada correctament
|
||||
fr-FR:
|
||||
back: Retour
|
||||
accept: Accepter
|
||||
addEditAddress: Ajouter ou modifier l'adresse
|
||||
name: Destinataire
|
||||
|
@ -161,7 +157,6 @@ fr-FR:
|
|||
province: Province
|
||||
addressChangedSuccessfully: Adresse modifié avec succès
|
||||
pt-PT:
|
||||
back: Voltar
|
||||
accept: Aceitar
|
||||
addEditAddress: Adicionar ou modificar morada
|
||||
name: Consignatario
|
||||
|
|
|
@ -1 +1,253 @@
|
|||
<template>Admin news details</template>
|
||||
<script setup>
|
||||
import { onMounted, ref, inject, computed } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useRouter, useRoute } from 'vue-router';
|
||||
|
||||
import VnImg from 'src/components/ui/VnImg.vue';
|
||||
import VnForm from 'src/components/common/VnForm.vue';
|
||||
import VnSelect from 'src/components/common/VnSelect.vue';
|
||||
import VnInput from 'src/components/common/VnInput.vue';
|
||||
|
||||
import { useAppStore } from 'stores/app';
|
||||
import { storeToRefs } from 'pinia';
|
||||
|
||||
const jApi = inject('jApi');
|
||||
const { t } = useI18n();
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
const appStore = useAppStore();
|
||||
const { isHeaderMounted } = storeToRefs(appStore);
|
||||
|
||||
const newsTags = ref([]);
|
||||
const pks = computed(() => ({ id: route.params.id }));
|
||||
const isEditMode = !!route.params.id;
|
||||
const formData = ref(
|
||||
!route.params.id
|
||||
? {
|
||||
title: '',
|
||||
tag: '',
|
||||
priority: '',
|
||||
text: ''
|
||||
}
|
||||
: undefined
|
||||
);
|
||||
|
||||
const fetchNewDataSql = computed(() => {
|
||||
if (!route.params.id) return undefined;
|
||||
return {
|
||||
query: `
|
||||
SELECT id, title, text, tag, priority, image
|
||||
FROM news WHERE id = #id`,
|
||||
params: { id: route.params.id }
|
||||
};
|
||||
});
|
||||
|
||||
const getNewsTag = async () => {
|
||||
try {
|
||||
newsTags.value = await jApi.query(
|
||||
`SELECT name, description FROM newsTag
|
||||
ORDER BY description`
|
||||
);
|
||||
} catch (error) {
|
||||
console.error('Error getting newsTag:', error);
|
||||
}
|
||||
};
|
||||
|
||||
const goBack = () => router.push({ name: 'adminNews' });
|
||||
|
||||
onMounted(async () => {
|
||||
getNewsTag();
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<QPage class="vn-w-sm">
|
||||
<Teleport v-if="isHeaderMounted" to="#actions">
|
||||
<QBtn
|
||||
:label="t('back')"
|
||||
icon="close"
|
||||
rounded
|
||||
no-caps
|
||||
@click="goBack()"
|
||||
/>
|
||||
</Teleport>
|
||||
<VnForm
|
||||
ref="vnFormRef"
|
||||
:fetchFormDataSql="fetchNewDataSql"
|
||||
:formInitialData="formData"
|
||||
:createModelDefault="{
|
||||
field: 'userFk',
|
||||
value: 'account.myUser_getId()'
|
||||
}"
|
||||
:pks="pks"
|
||||
:isEditMode="isEditMode"
|
||||
table="news"
|
||||
schema="hedera"
|
||||
separationBetweenInputs="lg"
|
||||
@onDataSaved="goBack()"
|
||||
>
|
||||
<template #form="{ data }">
|
||||
<VnImg
|
||||
storage="catalog"
|
||||
size="200x200"
|
||||
width="80px"
|
||||
height="80px"
|
||||
class="full-width"
|
||||
:id="data.image"
|
||||
rounded
|
||||
editable
|
||||
editSchema="catalog"
|
||||
/>
|
||||
<VnInput
|
||||
v-model="data.title"
|
||||
:label="t('title')"
|
||||
:clearable="false"
|
||||
/>
|
||||
<div class="row justify-between q-gutter-x-md">
|
||||
<VnSelect
|
||||
v-model="data.tag"
|
||||
:label="t('tag')"
|
||||
option-label="description"
|
||||
option-value="name"
|
||||
:options="newsTags"
|
||||
class="col"
|
||||
/>
|
||||
<VnInput
|
||||
v-model="data.priority"
|
||||
:label="t('priority')"
|
||||
:clearable="false"
|
||||
class="col"
|
||||
/>
|
||||
</div>
|
||||
<QEditor
|
||||
v-model="data.text"
|
||||
:toolbar="[
|
||||
[
|
||||
{
|
||||
label: $q.lang.editor.align,
|
||||
icon: $q.iconSet.editor.align,
|
||||
fixedLabel: true,
|
||||
list: 'only-icons',
|
||||
options: ['left', 'center', 'right', 'justify']
|
||||
},
|
||||
{
|
||||
label: $q.lang.editor.align,
|
||||
icon: $q.iconSet.editor.align,
|
||||
fixedLabel: true,
|
||||
options: ['left', 'center', 'right', 'justify']
|
||||
}
|
||||
],
|
||||
[
|
||||
'bold',
|
||||
'italic',
|
||||
'strike',
|
||||
'underline',
|
||||
'subscript',
|
||||
'superscript'
|
||||
],
|
||||
['token', 'hr', 'link', 'custom_btn'],
|
||||
['print', 'fullscreen'],
|
||||
[
|
||||
{
|
||||
label: $q.lang.editor.formatting,
|
||||
icon: $q.iconSet.editor.formatting,
|
||||
list: 'no-icons',
|
||||
options: [
|
||||
'p',
|
||||
'h1',
|
||||
'h2',
|
||||
'h3',
|
||||
'h4',
|
||||
'h5',
|
||||
'h6',
|
||||
'code'
|
||||
]
|
||||
},
|
||||
{
|
||||
label: $q.lang.editor.fontSize,
|
||||
icon: $q.iconSet.editor.fontSize,
|
||||
fixedLabel: true,
|
||||
fixedIcon: true,
|
||||
list: 'no-icons',
|
||||
options: [
|
||||
'size-1',
|
||||
'size-2',
|
||||
'size-3',
|
||||
'size-4',
|
||||
'size-5',
|
||||
'size-6',
|
||||
'size-7'
|
||||
]
|
||||
},
|
||||
{
|
||||
label: $q.lang.editor.defaultFont,
|
||||
icon: $q.iconSet.editor.font,
|
||||
fixedIcon: true,
|
||||
list: 'no-icons',
|
||||
options: [
|
||||
'default_font',
|
||||
'arial',
|
||||
'arial_black',
|
||||
'comic_sans',
|
||||
'courier_new',
|
||||
'impact',
|
||||
'lucida_grande',
|
||||
'times_new_roman',
|
||||
'verdana'
|
||||
]
|
||||
},
|
||||
'removeFormat'
|
||||
],
|
||||
['quote', 'unordered', 'ordered', 'outdent', 'indent'],
|
||||
|
||||
['undo', 'redo'],
|
||||
['viewsource']
|
||||
]"
|
||||
:fonts="{
|
||||
arial: 'Arial',
|
||||
arial_black: 'Arial Black',
|
||||
comic_sans: 'Comic Sans MS',
|
||||
courier_new: 'Courier New',
|
||||
impact: 'Impact',
|
||||
lucida_grande: 'Lucida Grande',
|
||||
times_new_roman: 'Times New Roman',
|
||||
verdana: 'Verdana'
|
||||
}"
|
||||
/>
|
||||
</template>
|
||||
</VnForm>
|
||||
</QPage>
|
||||
</template>
|
||||
|
||||
<i18n lang="yaml">
|
||||
en-US:
|
||||
addNew: Add new
|
||||
confirmDeleteAddress: Are you sure you want to delete this new?
|
||||
title: Title
|
||||
tag: Tag
|
||||
priority: Priority
|
||||
es-ES:
|
||||
addNew: Añadir noticia
|
||||
confirmDeleteAddress: ¿Estás seguro de que quieres eliminar esta noticia?
|
||||
title: Título
|
||||
tag: Etiqueta
|
||||
priority: Prioridad
|
||||
ca-ES:
|
||||
addNew: Afegir noticia
|
||||
confirmDeleteAddress: Estàs segur que vols eliminar aquesta notícia?
|
||||
title: Títol
|
||||
tag: Etiqueta
|
||||
priority: Prioritat
|
||||
fr-FR:
|
||||
addNew: Ajouter nouvelles
|
||||
confirmDeleteAddress: Êtes-vous sûr de vouloir supprimer cette nouvelle?
|
||||
title: Titre
|
||||
tag: Tag
|
||||
priority: Priorité
|
||||
pt-PT:
|
||||
addNew: Adicionar noticia
|
||||
confirmDeleteAddress: Tem a certeza que deseja eliminar esta notícia?
|
||||
title: Título
|
||||
tag: Etiqueta
|
||||
priority: Prioridade
|
||||
</i18n>
|
||||
|
|
|
@ -1 +1,134 @@
|
|||
<template>News view</template>
|
||||
<script setup>
|
||||
import { onMounted, ref, inject } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
import CardList from 'src/components/ui/CardList.vue';
|
||||
import VnImg from 'src/components/ui/VnImg.vue';
|
||||
|
||||
import { useAppStore } from 'stores/app';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { useVnConfirm } from 'src/composables/useVnConfirm.js';
|
||||
import useNotify from 'src/composables/useNotify.js';
|
||||
|
||||
const jApi = inject('jApi');
|
||||
const { t } = useI18n();
|
||||
const appStore = useAppStore();
|
||||
const { openConfirmationModal } = useVnConfirm();
|
||||
const { isHeaderMounted } = storeToRefs(appStore);
|
||||
const { notify } = useNotify();
|
||||
|
||||
const loading = ref(false);
|
||||
const news = ref([]);
|
||||
|
||||
const getNews = async () => {
|
||||
try {
|
||||
news.value = await jApi.query(
|
||||
`SELECT n.id, u.nickname, n.priority, n.image, n.title
|
||||
FROM news n
|
||||
JOIN account.user u ON u.id = n.userFk
|
||||
ORDER BY priority, n.created DESC`
|
||||
);
|
||||
} catch (error) {
|
||||
console.error('Error getting news:', error);
|
||||
}
|
||||
};
|
||||
|
||||
const deleteNew = async (id, index) => {
|
||||
try {
|
||||
await jApi.execQuery(
|
||||
`START TRANSACTION;
|
||||
DELETE FROM hedera.news WHERE ((id = #id));
|
||||
COMMIT`,
|
||||
{
|
||||
id
|
||||
}
|
||||
);
|
||||
news.value.splice(index, 1);
|
||||
notify(t('dataSaved'), 'positive');
|
||||
} catch (error) {
|
||||
console.error('Error deleting news:', error);
|
||||
}
|
||||
};
|
||||
|
||||
onMounted(async () => getNews());
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Teleport v-if="isHeaderMounted" to="#actions">
|
||||
<QBtn
|
||||
:label="t('addNew')"
|
||||
icon="add"
|
||||
:to="{ name: 'adminNewsDetails' }"
|
||||
rounded
|
||||
no-caps
|
||||
/>
|
||||
</Teleport>
|
||||
<QPage class="vn-w-xs">
|
||||
<QList class="flex justify-center">
|
||||
<QSpinner
|
||||
v-if="loading"
|
||||
color="primary"
|
||||
size="3em"
|
||||
:thickness="2"
|
||||
/>
|
||||
<CardList
|
||||
v-else
|
||||
v-for="(newsItem, index) in news"
|
||||
:key="index"
|
||||
:to="{ name: 'adminNewsDetails', params: { id: newsItem.id } }"
|
||||
>
|
||||
<template #prepend>
|
||||
<VnImg
|
||||
:id="newsItem.image"
|
||||
storage="news"
|
||||
editSchema="news"
|
||||
size="200x200"
|
||||
width="80px"
|
||||
height="80px"
|
||||
class="q-mr-md"
|
||||
rounded
|
||||
editable
|
||||
:editImageName="newsItem.image"
|
||||
/>
|
||||
</template>
|
||||
<template #content>
|
||||
<span class="text-bold q-mb-sm">{{ newsItem.title }} </span>
|
||||
<span>{{ newsItem.nickname }} </span>
|
||||
<span>{{ newsItem.priority }}</span>
|
||||
</template>
|
||||
<template #actions>
|
||||
<QBtn
|
||||
icon="delete"
|
||||
flat
|
||||
rounded
|
||||
@click.stop.prevent="
|
||||
openConfirmationModal(
|
||||
null,
|
||||
t('confirmDeleteAddress'),
|
||||
() => deleteNew(newsItem.id, index)
|
||||
)
|
||||
"
|
||||
/>
|
||||
</template>
|
||||
</CardList>
|
||||
</QList>
|
||||
</QPage>
|
||||
</template>
|
||||
|
||||
<i18n lang="yaml">
|
||||
en-US:
|
||||
addNew: Add new
|
||||
confirmDeleteAddress: Are you sure you want to delete this new?
|
||||
es-ES:
|
||||
addNew: Añadir noticia
|
||||
confirmDeleteAddress: ¿Estás seguro de que quieres eliminar esta noticia?
|
||||
ca-ES:
|
||||
addNew: Afegir noticia
|
||||
confirmDeleteAddress: Estàs segur que vols eliminar aquesta notícia?
|
||||
fr-FR:
|
||||
addNew: Ajouter nouvelles
|
||||
confirmDeleteAddress: Êtes-vous sûr de vouloir supprimer cette nouvelle?
|
||||
pt-PT:
|
||||
addNew: Adicionar noticia
|
||||
confirmDeleteAddress: Tem a certeza que deseja eliminar esta notícia?
|
||||
</i18n>
|
||||
|
|
Loading…
Reference in New Issue