Migrate SocialWall to base components

pull/4766/head
Daniel Gayoso González 1 year ago
parent 5894a8c182
commit 7b745bb187
  1. 73
      assets/vue/components/basecomponents/BaseFileUpload.vue
  2. 6
      assets/vue/components/basecomponents/BaseInputText.vue
  3. 2
      assets/vue/components/documents/DocumentAudioRecorder.vue
  4. 2
      assets/vue/components/message/Form.vue
  5. 248
      assets/vue/components/social/SocialWallPostForm.vue

@ -0,0 +1,73 @@
<template>
<div class="flex gap-2 items-center">
<BaseButton
:label="label"
type="primary"
icon="attachment"
@click="showFileDialog"
/>
<p class="text-gray-90">
{{ fileName }}
</p>
</div>
<input
ref="inputFile"
type="file"
class="hidden"
:accept="acceptFileType"
>
</template>
<script setup>
import BaseButton from "./BaseButton.vue"
import {computed, onMounted, ref} from "vue";
const props = defineProps({
modelValue: {
type: File,
required: true,
},
label: {
type: String,
required: true
},
accept: {
type: String,
default: '',
validator: (value) => {
if (value === '') { return true }
return ['image'].includes(value);
},
}
})
const emit = defineEmits(['fileSelected'])
const inputFile = ref(null)
const fileName = ref('')
const acceptFileType = computed(() => {
switch (props.accept) {
case '':
return ''
case 'image':
return 'image/*'
default:
return ''
}
})
onMounted(() => {
inputFile.value.addEventListener("change", fileSelected);
})
const fileSelected = () => {
let file = inputFile.value.files[0];
fileName.value = file.name
emit('fileSelected', file)
}
const showFileDialog = () => {
inputFile.value.click()
}
</script>

@ -10,7 +10,9 @@
/>
<label v-t="label" :class="{ 'p-error': isInvalid }" :for="id" />
</div>
<small v-if="isInvalid" v-t="helpText" class="p-error" />
<slot name="errors">
<small v-if="isInvalid" v-t="errorText" class="p-error" />
</slot>
</div>
</template>
@ -32,7 +34,7 @@ defineProps({
type: String,
required: true,
},
helpText: {
errorText: {
type: String,
required: false,
default: null,

@ -3,7 +3,7 @@
<BaseInputText
v-if="audio"
v-model="recordName"
:help-text="recordError"
:error-text="recordError"
:is-invalid="recordError !== ''"
:label="t('Enter filename here')"
class="max-w-full self-center mb-4 w-60"

@ -3,7 +3,7 @@
<div class="col-span-2">
<BaseInputText
id="item_title"
v-model:help-text="v$.item.title.required.$message"
v-model:error-text="v$.item.title.required.$message"
v-model:is-invalid="v$.item.title.$invalid"
v-model="v$.item.title.$model"
:label="t('Title')"

@ -1,139 +1,141 @@
<template>
<q-card bordered class="mb-4" flat>
<q-card-section>
<q-form
class="q-gutter-md"
<BaseCard plain>
<form>
<BaseInputText
v-model="content"
class="mb-2"
:label="textPlaceholder"
:aria-placeholder="textPlaceholder"
:is-invalid="v$.content.$error"
>
<q-input
v-model="content"
:error="v$.content.$error"
:label="textPlaceholder"
autogrow
<template #errors>
<p
v-for="error in v$.content.$errors"
:key="error.$uid"
class="mt-1 text-error"
>
{{ error.$message }}
</p>
</template>
</BaseInputText>
<div class="mb-2">
<BaseCheckbox
v-if="allowCreatePromoted"
id="is-promoted"
v-model="isPromoted"
:label="$t('Mark as promoted message')"
name="is-promoted"
/>
</div>
<div class="flex mb-2">
<BaseFileUpload
v-model="attachment"
:label="$t('File upload')"
accept="image"
@change="v$.attachment.$touch()"
/>
<div class="row justify-between mt-0">
<q-file
v-model="attachment"
:label="$t('File upload')"
accept="image/*"
clearable
dense
@change="v$.attachment.$touch()"
>
<template v-slot:prepend>
<q-icon name="attach_file" />
</template>
</q-file>
<q-checkbox
v-model="isPromoted"
v-if="allowCreatePromoted"
:label="$t('Mark as promoted message')"
left-label
/>
<q-btn
:label="$t('Post')"
icon="send"
@click="sendPost"
/>
</div>
</q-form>
</q-card-section>
</q-card>
<BaseButton
:label="$t('Post')"
class="ml-auto"
type="primary"
icon="send"
size="small"
@click="sendPost"
/>
</div>
</form>
</BaseCard>
</template>
<script>
<script setup>
import {computed, inject, onMounted, reactive, ref, toRefs, watch} from "vue";
import {useStore} from "vuex";
import {SOCIAL_TYPE_PROMOTED_MESSAGE, SOCIAL_TYPE_WALL_POST} from "./constants";
import useVuelidate from "@vuelidate/core";
import {required} from "@vuelidate/validators";
import {useI18n} from "vue-i18n";
import BaseCard from "../basecomponents/BaseCard.vue";
import BaseButton from "../basecomponents/BaseButton.vue";
import BaseInputText from "../basecomponents/BaseInputText.vue";
import BaseFileUpload from "../basecomponents/BaseFileUpload.vue";
import BaseCheckbox from "../basecomponents/BaseCheckbox.vue";
const store = useStore();
const {t} = useI18n();
const user = inject('social-user');
const currentUser = store.getters['security/getUser'];
const userIsAdmin = store.getters['security/isAdmin'];
const postState = reactive({
content: '',
attachment: null,
isPromoted: false,
textPlaceholder: '',
});
const {content, attachment, isPromoted, textPlaceholder} = toRefs(postState)
const v$ = useVuelidate({
content: {required},
}, postState);
watch(() => user.value, () => {
showTextPlaceholder();
showCheckboxPromoted();
});
onMounted(() => {
showTextPlaceholder();
export default {
name: "WallPostForm",
setup() {
const user = inject('social-user');
const store = useStore();
const {t} = useI18n();
const currentUser = store.getters['security/getUser'];
const userIsAdmin = store.getters['security/isAdmin'];
const postState = reactive({
content: '',
attachment: null,
isPromoted: false,
textPlaceholder: '',
});
function showTextPlaceholder() {
postState.textPlaceholder = currentUser['@id'] === user.value['@id']
? t('What are you thinking about?')
: t('Write something to {0}', [user.value.fullName]);
}
const allowCreatePromoted = ref(false);
function showCheckboxPromoted() {
allowCreatePromoted.value = userIsAdmin && currentUser['@id'] === user.value['@id'];
}
const v$ = useVuelidate({
content: {required},
}, postState);
async function sendPost() {
v$.value.$touch();
if (v$.value.$invalid) {
return;
}
const createPostPayload = {
content: postState.content,
type: postState.isPromoted ? SOCIAL_TYPE_PROMOTED_MESSAGE : SOCIAL_TYPE_WALL_POST,
sender: currentUser['@id'],
userReceiver: currentUser['@id'] === user.value['@id'] ? null : user.value['@id'],
};
await store.dispatch('socialpost/create', createPostPayload);
if (postState.attachment) {
const post = store.state.socialpost.created;
const attachmentPayload = {
postId: post.id,
file: postState.attachment
};
await store.dispatch('messageattachment/createWithFormData', attachmentPayload);
}
postState.content = '';
postState.attachment = null;
postState.isPromoted = false;
}
watch(() => user.value, () => {
showTextPlaceholder();
showCheckboxPromoted();
});
onMounted(() => {
showTextPlaceholder();
showCheckboxPromoted();
});
return {
allowCreatePromoted,
...toRefs(postState),
sendPost,
v$
}
showCheckboxPromoted();
});
function showTextPlaceholder() {
postState.textPlaceholder = currentUser['@id'] === user.value['@id']
? t('What are you thinking about?')
: t('Write something to {0}', [user.value.fullName]);
}
const allowCreatePromoted = ref(false);
function showCheckboxPromoted() {
allowCreatePromoted.value = userIsAdmin && currentUser['@id'] === user.value['@id'];
}
async function sendPost() {
v$.value.$touch();
if (v$.value.$invalid) {
return;
}
const createPostPayload = {
content: postState.content,
type: postState.isPromoted ? SOCIAL_TYPE_PROMOTED_MESSAGE : SOCIAL_TYPE_WALL_POST,
sender: currentUser['@id'],
userReceiver: currentUser['@id'] === user.value['@id'] ? null : user.value['@id'],
};
await store.dispatch('socialpost/create', createPostPayload);
if (postState.attachment) {
const post = store.state.socialpost.created;
const attachmentPayload = {
postId: post.id,
file: postState.attachment
};
await store.dispatch('messageattachment/createWithFormData', attachmentPayload);
}
postState.content = '';
postState.attachment = null;
postState.isPromoted = false;
}
</script>

Loading…
Cancel
Save