News view refactor #137

Merged
jsegarra merged 4 commits from wbuezas/hedera-web-mindshore:feature/news-view into beta 2025-04-04 11:09:56 +00:00
4 changed files with 48 additions and 54 deletions

View File

@ -69,6 +69,10 @@ const props = defineProps({
filter: {
type: Object,
default: null
},
dataRequired: {
type: Object,
default: () => {}
}
});
@ -122,9 +126,10 @@ onMounted(async () => {
async function fetch() {
try {
let { data } = await api.get(props.url, {
params: { filter: JSON.stringify(props.filter) }
});
const params = props.filter
? { filter: JSON.stringify(props.filter) }
: {};
let { data } = await api.get(props.url, { params });
if (Array.isArray(data)) data = data[0] ?? {};
formData.value = { ...data };
emit('onDataFetched', formData.value);
@ -144,9 +149,10 @@ async function save() {
isLoading.value = true;
try {
const body = props.mapper
let body = props.mapper
? props.mapper(formData.value, originalData.value)
: formData.value;
body = { ...body, ...props.dataRequired };
const method = props.urlCreate ? 'post' : 'patch';
const url = props.urlCreate || props.urlUpdate || props.url;

View File

@ -7,19 +7,21 @@ 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 FormModel from 'src/components/common/FormModel.vue';
import { useAppStore } from 'stores/app';
import { useUserStore } from 'stores/user';
import { storeToRefs } from 'pinia';
const jApi = inject('jApi');
const api = inject('api');
const { t } = useI18n();
const route = useRoute();
const router = useRouter();
const appStore = useAppStore();
const userStore = useUserStore();
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
@ -32,22 +34,25 @@ const formData = ref(
: undefined
);
const fetchNewDataSql = computed(() => {
const initialFetchUrl = 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 }
};
return `news/${route.params.id}`;
});
const urlUpdate = computed(() => {
if (!route.params.id) return undefined;
return `news/${route.params.id}`;
});
const urlCreate = computed(() => {
if (route.params.id) return undefined;
return 'news';
});
const getNewsTag = async () => {
try {
newsTags.value = await jApi.query(
`SELECT name, description FROM newsTag
ORDER BY description`
);
const { data } = await api.get('newsTags');
newsTags.value = data;
} catch (error) {
console.error('Error getting newsTag:', error);
}
@ -73,19 +78,14 @@ onMounted(async () => {
<QTooltip>{{ t('back') }}</QTooltip>
</QBtn>
</Teleport>
<VnForm
ref="vnFormRef"
:fetch-form-data-sql="fetchNewDataSql"
<FormModel
:form-initial-data="formData"
:create-model-default="{
field: 'userFk',
value: 'account.myUser_getId()'
}"
:pks="pks"
:is-edit-mode="isEditMode"
table="news"
schema="hedera"
separation-between-inputs="lg"
:url="initialFetchUrl"
Review

Esto hay que hacerlo por cada componente que use FormModel?
si es una validación tan corta, no podriamos hacerlo dentro de FormModel?

Esto hay que hacerlo por cada componente que use FormModel? si es una validación tan corta, no podriamos hacerlo dentro de FormModel?
Review

Como lo validarias dentro del FormModel?
Asi es como funciona actualmente en el FormModel de Lilium, si se pasa un urlCreate al guardar dispara un post y si no dispara un patch, y la prop url si se manda significa que FormModel deberia fetchear la data con la url que se provee

Como lo validarias dentro del FormModel? Asi es como funciona actualmente en el FormModel de Lilium, si se pasa un urlCreate al guardar dispara un post y si no dispara un patch, y la prop `url` si se manda significa que FormModel deberia fetchear la data con la url que se provee
:auto-load="isEditMode"
:url-create="urlCreate"
:url-update="urlUpdate"
:data-required="{ userFk: userStore.userId }"
Review

esta propiedad es porque el valor nunca debe eliminarse o es que el formulario debe tenerlo de inicio¿?

esta propiedad es porque el valor *nunca* debe eliminarse o es que el formulario debe tenerlo de inicio¿?
Review

Porque es un valor que siempre es requerido tanto para update o create

Porque es un valor que siempre es requerido tanto para update o create
:show-bottom-actions="false"
@on-data-saved="goBack()"
>
<template #form="{ data }">
@ -215,7 +215,7 @@ onMounted(async () => {
}"
/>
</template>
</VnForm>
</FormModel>
</QPage>
</template>

View File

@ -5,47 +5,31 @@ import { useI18n } from 'vue-i18n';
import CardList from 'src/components/ui/CardList.vue';
import VnImg from 'src/components/ui/VnImg.vue';
import VnList from 'src/components/ui/VnList.vue';
import FetchData from 'src/components/common/FetchData.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 api = inject('api');
const { t } = useI18n();
const appStore = useAppStore();
const { openConfirmationModal } = useVnConfirm();
const { isHeaderMounted } = storeToRefs(appStore);
const { notify } = useNotify();
const loading = ref(false);
const loading = ref(true);
const news = ref([]);
const getNews = async () => {
try {
loading.value = true;
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`
);
loading.value = false;
} catch (error) {
console.error('Error getting news:', error);
}
const onFetch = data => {

Seria lo mismo que usar FetchData, no?
Y si le ponemos un metodo de onfetch dentro de VnList?

Seria lo mismo que usar FetchData, no? Y si le ponemos un metodo de onfetch dentro de VnList?

Aplique el componente de FetchData

Commit: 824fa28126

Aplique el componente de `FetchData` Commit: https://gitea.verdnatura.es/verdnatura/hedera-web/commit/824fa281265029b5d2940c68510d5586f5930c99
news.value = data;
loading.value = false;
};
const deleteNew = async (id, index) => {
try {
await jApi.execQuery(
`START TRANSACTION;
DELETE FROM hedera.news WHERE ((id = #id));
COMMIT`,
{
id
}
);
await api.delete(`news/${id}`);
news.value.splice(index, 1);
notify(t('dataSaved'), 'positive');
} catch (error) {
@ -57,6 +41,7 @@ onMounted(async () => getNews());
</script>
<template>
<FetchData ref="fetchNewsRef" url="news" auto-load @on-fetch="onFetch" />
<Teleport v-if="isHeaderMounted" to="#actions">
<QBtn
:label="t('addNew')"

View File

@ -296,6 +296,8 @@ export const useUserStore = defineStore('user', () => {
tokenConfig.value = null;
};
const userId = computed(() => user.value?.id);
watch(
[mainUser, supplantedUser],
() => (user.value = supplantedUser.value || mainUser.value),
@ -336,6 +338,7 @@ export const useUserStore = defineStore('user', () => {
updateUserLang,
init,
$reset,
onLogin
onLogin,
userId
};
});