Changes for eveai_chat_client:

- Modal display of privacy statement & Terms & Conditions
- Consent-flag ==> check of privacy and Terms & Conditions
- customisation option added to show or hide DynamicForm titles
This commit is contained in:
Josako
2025-07-28 21:47:56 +02:00
parent ef138462d9
commit 5e81595622
28 changed files with 1609 additions and 2271 deletions

View File

@@ -2,7 +2,7 @@
<div class="dynamic-form-container">
<div class="dynamic-form" :class="{ 'readonly': readOnly, 'edit': !readOnly }">
<!-- Form header with icon and title -->
<div v-if="formData.title || formData.name || formData.icon" class="form-header">
<div v-if="shouldShowFormHeader" class="form-header">
<div v-if="formData.icon" class="form-icon">
<span class="material-symbols-outlined">{{ formData.icon }}</span>
</div>
@@ -19,6 +19,8 @@
:field-id="field.id || field.name"
:model-value="localFormValues[field.id || field.name]"
@update:model-value="updateFieldValue(field.id || field.name, $event)"
@open-privacy-modal="openPrivacyModal"
@open-terms-modal="openTermsModal"
/>
</template>
<template v-else-if="typeof formData.fields === 'object'">
@@ -29,6 +31,8 @@
:field-id="fieldId"
:model-value="localFormValues[fieldId]"
@update:model-value="updateFieldValue(fieldId, $event)"
@open-privacy-modal="openPrivacyModal"
@open-terms-modal="openTermsModal"
/>
</template>
</div>
@@ -68,12 +72,14 @@
</div>
</div>
</div>
</div>
</template>
<script>
import FormField from './FormField.vue';
import { useIconManager } from '../js/composables/useIconManager.js';
import { injectContentModal } from '../js/composables/useContentModal.js';
export default {
name: 'DynamicForm',
@@ -82,11 +88,14 @@ export default {
},
setup(props) {
const { watchIcon } = useIconManager();
const contentModal = injectContentModal();
// Watch formData.icon for automatic icon loading
watchIcon(() => props.formData?.icon);
return {};
return {
contentModal
};
},
props: {
formData: {
@@ -136,6 +145,10 @@ export default {
hideActions: {
type: Boolean,
default: false
},
apiPrefix: {
type: String,
required: true
}
},
emits: ['submit', 'cancel', 'update:formValues'],
@@ -195,6 +208,16 @@ export default {
}
return missingFields.length === 0;
},
// Title display mode configuration
titleDisplayMode() {
console.log('Title display mode:', window.chatConfig?.form_title_display || 'Full Title');
return window.chatConfig?.form_title_display || 'Full Title';
},
// Determine if form header should be shown
shouldShowFormHeader() {
const hasContent = this.formData.title || this.formData.name || this.formData.icon;
return hasContent && this.titleDisplayMode !== 'No Title';
}
},
watch: {
@@ -393,6 +416,40 @@ export default {
}
return value.toString();
},
// Modal handling methods
openPrivacyModal() {
this.loadContent('privacy');
},
openTermsModal() {
this.loadContent('terms');
},
closeModal() {
this.contentModal.hideModal();
},
retryLoad() {
// Retry loading the last requested content type
const currentTitle = this.contentModal.modalState.title.toLowerCase();
if (currentTitle.includes('privacy')) {
this.loadContent('privacy');
} else if (currentTitle.includes('terms')) {
this.loadContent('terms');
}
},
async loadContent(contentType) {
const title = contentType === 'privacy' ? 'Privacy Statement' : 'Terms & Conditions';
const contentUrl = `${this.apiPrefix}/${contentType}`;
// Use the composable to show modal and load content
await this.contentModal.showModal({
title: title,
contentUrl: contentUrl
});
}
}
};