Merge pull request 'News view refactor' (!137) from wbuezas/hedera-web-mindshore:feature/news-view into beta
gitea/hedera-web/pipeline/head This commit looks good Details

Reviewed-on: #137
Reviewed-by: Javier Segarra <jsegarra@verdnatura.es>
This commit is contained in:
Javier Segarra 2025-04-04 11:09:55 +00:00
commit be54a93e63
4 changed files with 48 additions and 54 deletions

View File

@ -69,6 +69,10 @@ const props = defineProps({
filter: { filter: {
type: Object, type: Object,
default: null default: null
},
dataRequired: {
type: Object,
default: () => {}
} }
}); });
@ -122,9 +126,10 @@ onMounted(async () => {
async function fetch() { async function fetch() {
try { try {
let { data } = await api.get(props.url, { const params = props.filter
params: { filter: JSON.stringify(props.filter) } ? { filter: JSON.stringify(props.filter) }
}); : {};
let { data } = await api.get(props.url, { params });
if (Array.isArray(data)) data = data[0] ?? {}; if (Array.isArray(data)) data = data[0] ?? {};
formData.value = { ...data }; formData.value = { ...data };
emit('onDataFetched', formData.value); emit('onDataFetched', formData.value);
@ -144,9 +149,10 @@ async function save() {
isLoading.value = true; isLoading.value = true;
try { try {
const body = props.mapper let body = props.mapper
? props.mapper(formData.value, originalData.value) ? props.mapper(formData.value, originalData.value)
: formData.value; : formData.value;
body = { ...body, ...props.dataRequired };
const method = props.urlCreate ? 'post' : 'patch'; const method = props.urlCreate ? 'post' : 'patch';
const url = props.urlCreate || props.urlUpdate || props.url; 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 VnForm from 'src/components/common/VnForm.vue';
import VnSelect from 'src/components/common/VnSelect.vue'; import VnSelect from 'src/components/common/VnSelect.vue';
import VnInput from 'src/components/common/VnInput.vue'; import VnInput from 'src/components/common/VnInput.vue';
import FormModel from 'src/components/common/FormModel.vue';
import { useAppStore } from 'stores/app'; import { useAppStore } from 'stores/app';
import { useUserStore } from 'stores/user';
import { storeToRefs } from 'pinia'; import { storeToRefs } from 'pinia';
const jApi = inject('jApi'); const api = inject('api');
const { t } = useI18n(); const { t } = useI18n();
const route = useRoute(); const route = useRoute();
const router = useRouter(); const router = useRouter();
const appStore = useAppStore(); const appStore = useAppStore();
const userStore = useUserStore();
const { isHeaderMounted } = storeToRefs(appStore); const { isHeaderMounted } = storeToRefs(appStore);
const newsTags = ref([]); const newsTags = ref([]);
const pks = computed(() => ({ id: route.params.id }));
const isEditMode = !!route.params.id; const isEditMode = !!route.params.id;
const formData = ref( const formData = ref(
!route.params.id !route.params.id
@ -32,22 +34,25 @@ const formData = ref(
: undefined : undefined
); );
const fetchNewDataSql = computed(() => { const initialFetchUrl = computed(() => {
if (!route.params.id) return undefined; if (!route.params.id) return undefined;
return { return `news/${route.params.id}`;
query: ` });
SELECT id, title, text, tag, priority, image
FROM news WHERE id = #id`, const urlUpdate = computed(() => {
params: { id: route.params.id } 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 () => { const getNewsTag = async () => {
try { try {
newsTags.value = await jApi.query( const { data } = await api.get('newsTags');
`SELECT name, description FROM newsTag newsTags.value = data;
ORDER BY description`
);
} catch (error) { } catch (error) {
console.error('Error getting newsTag:', error); console.error('Error getting newsTag:', error);
} }
@ -73,19 +78,14 @@ onMounted(async () => {
<QTooltip>{{ t('back') }}</QTooltip> <QTooltip>{{ t('back') }}</QTooltip>
</QBtn> </QBtn>
</Teleport> </Teleport>
<VnForm <FormModel
ref="vnFormRef"
:fetch-form-data-sql="fetchNewDataSql"
:form-initial-data="formData" :form-initial-data="formData"
:create-model-default="{ :url="initialFetchUrl"
field: 'userFk', :auto-load="isEditMode"
value: 'account.myUser_getId()' :url-create="urlCreate"
}" :url-update="urlUpdate"
:pks="pks" :data-required="{ userFk: userStore.userId }"
:is-edit-mode="isEditMode" :show-bottom-actions="false"
table="news"
schema="hedera"
separation-between-inputs="lg"
@on-data-saved="goBack()" @on-data-saved="goBack()"
> >
<template #form="{ data }"> <template #form="{ data }">
@ -215,7 +215,7 @@ onMounted(async () => {
}" }"
/> />
</template> </template>
</VnForm> </FormModel>
</QPage> </QPage>
</template> </template>

View File

@ -5,47 +5,31 @@ import { useI18n } from 'vue-i18n';
import CardList from 'src/components/ui/CardList.vue'; import CardList from 'src/components/ui/CardList.vue';
import VnImg from 'src/components/ui/VnImg.vue'; import VnImg from 'src/components/ui/VnImg.vue';
import VnList from 'src/components/ui/VnList.vue'; import VnList from 'src/components/ui/VnList.vue';
import FetchData from 'src/components/common/FetchData.vue';
import { useAppStore } from 'stores/app'; import { useAppStore } from 'stores/app';
import { storeToRefs } from 'pinia'; import { storeToRefs } from 'pinia';
import { useVnConfirm } from 'src/composables/useVnConfirm.js'; import { useVnConfirm } from 'src/composables/useVnConfirm.js';
import useNotify from 'src/composables/useNotify.js'; import useNotify from 'src/composables/useNotify.js';
const jApi = inject('jApi'); const api = inject('api');
const { t } = useI18n(); const { t } = useI18n();
const appStore = useAppStore(); const appStore = useAppStore();
const { openConfirmationModal } = useVnConfirm(); const { openConfirmationModal } = useVnConfirm();
const { isHeaderMounted } = storeToRefs(appStore); const { isHeaderMounted } = storeToRefs(appStore);
const { notify } = useNotify(); const { notify } = useNotify();
const loading = ref(false); const loading = ref(true);
const news = ref([]); const news = ref([]);
const getNews = async () => { const onFetch = data => {
try { news.value = data;
loading.value = true; loading.value = false;
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 deleteNew = async (id, index) => { const deleteNew = async (id, index) => {
try { try {
await jApi.execQuery( await api.delete(`news/${id}`);
`START TRANSACTION;
DELETE FROM hedera.news WHERE ((id = #id));
COMMIT`,
{
id
}
);
news.value.splice(index, 1); news.value.splice(index, 1);
notify(t('dataSaved'), 'positive'); notify(t('dataSaved'), 'positive');
} catch (error) { } catch (error) {
@ -57,6 +41,7 @@ onMounted(async () => getNews());
</script> </script>
<template> <template>
<FetchData ref="fetchNewsRef" url="news" auto-load @on-fetch="onFetch" />
<Teleport v-if="isHeaderMounted" to="#actions"> <Teleport v-if="isHeaderMounted" to="#actions">
<QBtn <QBtn
:label="t('addNew')" :label="t('addNew')"

View File

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