mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-11-24 12:48:30 +00:00
Replace OnTheFly.js with OnTheFly.ts and introduce ThirdPartyEdit.vue for enhanced third-party entity management
- Migrated API functions in `OnTheFly.js` to `OnTheFly.ts` for improved type safety using TypeScript. - Added `ThirdPartyEdit.vue` to streamline third-party creation and editing with a Vue component structure. - Updated third-party-related types in `types.ts` to improve consistency and explicitly distinguish `company`, `contact`, and `child` entities. - Enhanced `AddPersons.vue` and dependent components to support adding third-party contacts. - Adjusted styles and removed `.btn-tpchild` for consistency in button definitions across SCSS.
This commit is contained in:
@@ -36,21 +36,21 @@
|
||||
action="create"
|
||||
:query="query"
|
||||
ref="castPerson"
|
||||
@onPersonCreated="(payload) => emit('onPersonCreated', payload)"
|
||||
@onPersonCreated="onPersonCreated"
|
||||
/>
|
||||
|
||||
<on-the-fly-thirdparty
|
||||
<ThirdPartyEdit
|
||||
v-if="type === 'thirdparty'"
|
||||
:action="action"
|
||||
:query="query"
|
||||
ref="castThirdparty"
|
||||
@onThirdPartyCreated="onThirdPartyCreated"
|
||||
type=""
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { computed, onMounted, ref } from "vue";
|
||||
import OnTheFlyPerson from "ChillPersonAssets/vuejs/_components/OnTheFly/Person.vue";
|
||||
import OnTheFlyThirdparty from "ChillThirdPartyAssets/vuejs/_components/OnTheFly/ThirdParty.vue";
|
||||
import {
|
||||
ONTHEFLY_CREATE_PERSON,
|
||||
ONTHEFLY_CREATE_THIRDPARTY,
|
||||
@@ -59,15 +59,20 @@ import {
|
||||
import { CreatableEntityType, Person } from "ChillPersonAssets/types";
|
||||
import { CreateComponentConfig } from "ChillMainAssets/types";
|
||||
import PersonEdit from "ChillPersonAssets/vuejs/_components/OnTheFly/PersonEdit.vue";
|
||||
import ThirdPartyEdit from "ChillThirdPartyAssets/vuejs/_components/OnTheFly/ThirdPartyEdit.vue";
|
||||
import {Thirdparty} from "../../../../../../ChillThirdPartyBundle/Resources/public/types";
|
||||
|
||||
const props = withDefaults(defineProps<CreateComponentConfig>(), {
|
||||
allowedTypes: ["person"],
|
||||
action: "create",
|
||||
query: "",
|
||||
parent: null,
|
||||
});
|
||||
|
||||
const emit =
|
||||
defineEmits<(e: "onPersonCreated", payload: { person: Person }) => void>();
|
||||
defineEmits<{
|
||||
(e: "onPersonCreated", payload: { person: Person }): void,
|
||||
(e: "onThirdPartyCreated", payload: { thirdParty: Thirdparty }): void,
|
||||
}>();
|
||||
|
||||
const type = ref<CreatableEntityType | null>(null);
|
||||
|
||||
@@ -80,14 +85,10 @@ const radioType = computed<CreatableEntityType | null>({
|
||||
});
|
||||
|
||||
type PersonEditComponent = InstanceType<typeof PersonEdit>;
|
||||
type ThirdPartyEditComponent = InstanceType<typeof ThirdPartyEdit>;
|
||||
|
||||
type AnyComponentInstance =
|
||||
| InstanceType<typeof OnTheFlyPerson>
|
||||
| InstanceType<typeof OnTheFlyThirdparty>
|
||||
| null;
|
||||
|
||||
const castPerson = ref<PersonEditComponent>(null);
|
||||
const castThirdparty = ref<AnyComponentInstance>(null);
|
||||
const castPerson = ref<PersonEditComponent|null>(null);
|
||||
const castThirdparty = ref<ThirdPartyEditComponent|null>(null);
|
||||
|
||||
onMounted(() => {
|
||||
type.value =
|
||||
@@ -104,11 +105,26 @@ const containsThirdParty = computed<boolean>(() =>
|
||||
props.allowedTypes.includes("thirdparty"),
|
||||
);
|
||||
const containsPerson = computed<boolean>(() => {
|
||||
if (props.action === 'addContact') {
|
||||
return false;
|
||||
}
|
||||
return props.allowedTypes.includes("person");
|
||||
});
|
||||
|
||||
function save(): void {
|
||||
castPerson.value.postPerson();
|
||||
if (radioType.value === "person" && castPerson.value !== null) {
|
||||
castPerson.value.postPerson();
|
||||
} else if (radioType.value === "thirdparty" && castThirdparty.value !== null) {
|
||||
castThirdparty.value.postThirdParty();
|
||||
}
|
||||
}
|
||||
|
||||
function onThirdPartyCreated(payload: { thirdParty: Thirdparty }) {
|
||||
emit("onThirdPartyCreated", payload);
|
||||
}
|
||||
|
||||
function onPersonCreated(payload: { person: Person }) {
|
||||
emit("onPersonCreated", payload);
|
||||
}
|
||||
|
||||
defineExpose({ save });
|
||||
|
||||
@@ -5,19 +5,29 @@ import { CreateComponentConfig } from "ChillMainAssets/types";
|
||||
import { trans, SAVE } from "translator";
|
||||
import { useTemplateRef } from "vue";
|
||||
import { Person } from "ChillPersonAssets/types";
|
||||
import {Thirdparty} from "../../../../../../ChillThirdPartyBundle/Resources/public/types";
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: "onPersonCreated", payload: { person: Person }): void;
|
||||
(e: "onThirdPartyCreated", payload: { thirdParty: Thirdparty }): void;
|
||||
(e: "close"): void;
|
||||
}>();
|
||||
|
||||
const props = defineProps<CreateComponentConfig>();
|
||||
const props = defineProps<CreateComponentConfig & {modalTitle: string}>();
|
||||
const modalDialogClass = { "modal-xl": true, "modal-scrollable": true };
|
||||
|
||||
type CreateComponentType = InstanceType<typeof Create>;
|
||||
|
||||
const create = useTemplateRef<CreateComponentType>("create");
|
||||
|
||||
const onPersonCreated = ({person}: {person: Person}): void => {
|
||||
emit("onPersonCreated", {person});
|
||||
};
|
||||
|
||||
const onThirdPartyCreated = ({tp}: {tp: Thirdparty}): void => {
|
||||
emit("onThirdPartyCreated", {thirdParty: tp});
|
||||
}
|
||||
|
||||
function save(): void {
|
||||
console.log("save from CreateModal");
|
||||
create.value?.save();
|
||||
@@ -43,7 +53,8 @@ defineExpose({ save });
|
||||
:allowedTypes="props.allowedTypes"
|
||||
:action="props.action"
|
||||
:query="props.query"
|
||||
@onPersonCreated="(payload) => emit('onPersonCreated', payload)"
|
||||
@onPersonCreated="onPersonCreated"
|
||||
@onThirdPartyCreated="onThirdPartyCreated"
|
||||
></Create>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
class="btn btn-sm"
|
||||
target="_blank"
|
||||
:class="classAction"
|
||||
:title="trans(titleAction)"
|
||||
:title="titleAction"
|
||||
@click="openModal"
|
||||
>
|
||||
{{ buttonText }}<span v-if="isDead"> (‡)</span>
|
||||
@@ -23,14 +23,14 @@
|
||||
>
|
||||
<template #header>
|
||||
<h3 v-if="parent" class="modal-title">
|
||||
{{ trans(titleModal, { q: parent.text }) }}
|
||||
{{ titleModal }}
|
||||
</h3>
|
||||
<h3 v-else class="modal-title">
|
||||
{{ trans(titleModal) }}
|
||||
{{ titleModal }}
|
||||
</h3>
|
||||
</template>
|
||||
|
||||
<template #body v-if="type === 'person'">
|
||||
<template #body v-if="type === 'person' && action !== 'addContact'">
|
||||
<on-the-fly-person
|
||||
:id="id"
|
||||
:type="type"
|
||||
@@ -40,7 +40,7 @@
|
||||
<div v-if="hasResourceComment">
|
||||
<h3>{{ trans(ONTHEFLY_RESOURCE_COMMENT_TITLE) }}</h3>
|
||||
<blockquote class="chill-user-quote">
|
||||
{{ parent.comment }}
|
||||
{{ parent?.comment }}
|
||||
</blockquote>
|
||||
</div>
|
||||
</template>
|
||||
@@ -55,7 +55,7 @@
|
||||
<div v-if="hasResourceComment">
|
||||
<h3>{{ trans(ONTHEFLY_RESOURCE_COMMENT_TITLE) }}</h3>
|
||||
<blockquote class="chill-user-quote">
|
||||
{{ parent.comment }}
|
||||
{{ parent?.comment }}
|
||||
</blockquote>
|
||||
</div>
|
||||
</template>
|
||||
@@ -73,27 +73,23 @@
|
||||
<on-the-fly-create
|
||||
:action="action"
|
||||
:allowed-types="allowedTypes"
|
||||
:query="query"
|
||||
:query="query || ''"
|
||||
ref="castNew"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<template #footer>
|
||||
<a
|
||||
v-if="action === 'show'"
|
||||
:href="buildLocation(id, type)"
|
||||
:title="trans(titleMessage)"
|
||||
:title="titleMessage"
|
||||
class="btn btn-show"
|
||||
>{{ trans(buttonMessage) }}
|
||||
</a>
|
||||
<a v-else class="btn btn-save" @click="saveAction">
|
||||
{{ trans(ACTION_SAVE) }}
|
||||
>{{ buttonMessage }}
|
||||
</a>
|
||||
</template>
|
||||
</modal>
|
||||
</teleport>
|
||||
</template>
|
||||
<script setup>
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, defineEmits, defineProps } from "vue";
|
||||
import Modal from "ChillMainAssets/vuejs/_components/Modal.vue";
|
||||
import OnTheFlyCreate from "./Create.vue";
|
||||
@@ -104,7 +100,6 @@ import {
|
||||
ACTION_SHOW,
|
||||
ACTION_EDIT,
|
||||
ACTION_CREATE,
|
||||
ACTION_ADDCONTACT,
|
||||
ONTHEFLY_CREATE_TITLE_DEFAULT,
|
||||
ONTHEFLY_CREATE_TITLE_PERSON,
|
||||
ONTHEFLY_CREATE_TITLE_THIRDPARTY,
|
||||
@@ -112,40 +107,58 @@ import {
|
||||
ONTHEFLY_SHOW_THIRDPARTY,
|
||||
ONTHEFLY_EDIT_PERSON,
|
||||
ONTHEFLY_EDIT_THIRDPARTY,
|
||||
ONTHEFLY_ADDCONTACT_TITLE,
|
||||
ACTION_REDIRECT_PERSON,
|
||||
ACTION_REDIRECT_THIRDPARTY,
|
||||
ONTHEFLY_SHOW_FILE_PERSON,
|
||||
ONTHEFLY_SHOW_FILE_THIRDPARTY,
|
||||
ONTHEFLY_SHOW_FILE_DEFAULT,
|
||||
ONTHEFLY_RESOURCE_COMMENT_TITLE,
|
||||
ACTION_SAVE,
|
||||
THIRDPARTY_ADDCONTACT,
|
||||
THIRDPARTY_ADDCONTACT_TITLE,
|
||||
} from "translator";
|
||||
|
||||
const props = defineProps({
|
||||
type: String,
|
||||
id: [String, Number],
|
||||
action: String,
|
||||
buttonText: String,
|
||||
displayBadge: Boolean,
|
||||
isDead: Boolean,
|
||||
parent: Object,
|
||||
allowedTypes: Array,
|
||||
query: String,
|
||||
// Types
|
||||
type EntityType = "person" | "thirdparty";
|
||||
type ActionType = "show" | "edit" | "create" | "addContact";
|
||||
|
||||
interface ParentRef {
|
||||
type: string;
|
||||
id: string | number;
|
||||
text?: string;
|
||||
comment?: string | null;
|
||||
}
|
||||
|
||||
interface OnTheFlyComponentProps {
|
||||
type: EntityType;
|
||||
id: number;
|
||||
action: ActionType;
|
||||
buttonText?: string | null;
|
||||
displayBadge?: boolean;
|
||||
isDead?: boolean;
|
||||
parent?: ParentRef | null;
|
||||
allowedTypes?: EntityType[];
|
||||
query?: string;
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<OnTheFlyComponentProps>(), {
|
||||
buttonText: null,
|
||||
displayBadge: false,
|
||||
isDead: false,
|
||||
parent: null,
|
||||
allowedTypes: () => ["person", "thirdparty"] as EntityType[],
|
||||
query: "",
|
||||
});
|
||||
|
||||
const emit = defineEmits(["saveFormOnTheFly"]);
|
||||
const emit = defineEmits<{
|
||||
(e: "saveFormOnTheFly", payload: { type: string | undefined; data: any }): void;
|
||||
}>();
|
||||
|
||||
const modal = ref({
|
||||
const modal = ref<{ showModal: boolean; modalDialogClass: string }>({
|
||||
showModal: false,
|
||||
modalDialogClass: "modal-dialog-scrollable modal-xl",
|
||||
});
|
||||
|
||||
const castPerson = ref();
|
||||
const castThirdparty = ref();
|
||||
const castNew = ref();
|
||||
|
||||
const hasResourceComment = computed(() => {
|
||||
const hasResourceComment = computed<boolean>(() => {
|
||||
return (
|
||||
typeof props.parent !== "undefined" &&
|
||||
props.parent !== null &&
|
||||
@@ -156,7 +169,7 @@ const hasResourceComment = computed(() => {
|
||||
);
|
||||
});
|
||||
|
||||
const classAction = computed(() => {
|
||||
const classAction = computed<string>(() => {
|
||||
switch (props.action) {
|
||||
case "show":
|
||||
return "btn-show";
|
||||
@@ -171,174 +184,112 @@ const classAction = computed(() => {
|
||||
}
|
||||
});
|
||||
|
||||
const titleAction = computed(() => {
|
||||
const titleAction = computed<string>(() => {
|
||||
switch (props.action) {
|
||||
case "show":
|
||||
return ACTION_SHOW;
|
||||
return ACTION_SHOW as unknown as string;
|
||||
case "edit":
|
||||
return ACTION_EDIT;
|
||||
return ACTION_EDIT as unknown as string;
|
||||
case "create":
|
||||
return ACTION_CREATE;
|
||||
return ACTION_CREATE as unknown as string;
|
||||
case "addContact":
|
||||
return ACTION_ADDCONTACT;
|
||||
return THIRDPARTY_ADDCONTACT as unknown as string;
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
});
|
||||
|
||||
const titleCreate = computed(() => {
|
||||
const titleCreate = computed<string>(() => {
|
||||
if (typeof props.allowedTypes === "undefined") {
|
||||
return ONTHEFLY_CREATE_TITLE_DEFAULT;
|
||||
return trans(ONTHEFLY_CREATE_TITLE_DEFAULT)
|
||||
}
|
||||
return props.allowedTypes.every((t) => t === "person")
|
||||
? ONTHEFLY_CREATE_TITLE_PERSON
|
||||
: props.allowedTypes.every((t) => t === "thirdparty")
|
||||
? ONTHEFLY_CREATE_TITLE_THIRDPARTY
|
||||
: ONTHEFLY_CREATE_TITLE_DEFAULT;
|
||||
return props.allowedTypes.every((t: EntityType) => t === "person")
|
||||
? (trans(ONTHEFLY_CREATE_TITLE_PERSON))
|
||||
: props.allowedTypes.every((t: EntityType) => t === "thirdparty")
|
||||
? (trans(ONTHEFLY_CREATE_TITLE_THIRDPARTY))
|
||||
: (trans(ONTHEFLY_CREATE_TITLE_DEFAULT));
|
||||
});
|
||||
|
||||
const titleModal = computed(() => {
|
||||
const titleModal = computed<string>(() => {
|
||||
switch (props.action) {
|
||||
case "show":
|
||||
if (props.type == "person") {
|
||||
return ONTHEFLY_SHOW_PERSON;
|
||||
return trans(ONTHEFLY_SHOW_PERSON)
|
||||
} else if (props.type == "thirdparty") {
|
||||
return ONTHEFLY_SHOW_THIRDPARTY;
|
||||
return trans(ONTHEFLY_SHOW_THIRDPARTY)
|
||||
}
|
||||
break;
|
||||
case "edit":
|
||||
if (props.type == "person") {
|
||||
return ONTHEFLY_EDIT_PERSON;
|
||||
return trans(ONTHEFLY_EDIT_PERSON)
|
||||
} else if (props.type == "thirdparty") {
|
||||
return ONTHEFLY_EDIT_THIRDPARTY;
|
||||
return trans(ONTHEFLY_EDIT_THIRDPARTY)
|
||||
}
|
||||
break;
|
||||
case "create":
|
||||
return titleCreate.value;
|
||||
case "addContact":
|
||||
return ONTHEFLY_ADDCONTACT_TITLE;
|
||||
return trans(THIRDPARTY_ADDCONTACT_TITLE)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return "";
|
||||
});
|
||||
|
||||
const titleMessage = computed(() => {
|
||||
const titleMessage = computed<string>(() => {
|
||||
switch (props.type) {
|
||||
case "person":
|
||||
return ACTION_REDIRECT_PERSON;
|
||||
return trans(ACTION_REDIRECT_PERSON);
|
||||
case "thirdparty":
|
||||
return ACTION_REDIRECT_THIRDPARTY;
|
||||
return trans(ACTION_REDIRECT_THIRDPARTY);
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
});
|
||||
|
||||
const buttonMessage = computed(() => {
|
||||
const buttonMessage = computed<string>(() => {
|
||||
switch (props.type) {
|
||||
case "person":
|
||||
return ONTHEFLY_SHOW_FILE_PERSON;
|
||||
return trans(ONTHEFLY_SHOW_FILE_PERSON);
|
||||
case "thirdparty":
|
||||
return ONTHEFLY_SHOW_FILE_THIRDPARTY;
|
||||
return trans(ONTHEFLY_SHOW_FILE_THIRDPARTY);
|
||||
default:
|
||||
return ONTHEFLY_SHOW_FILE_DEFAULT;
|
||||
return trans(ONTHEFLY_SHOW_FILE_DEFAULT);
|
||||
}
|
||||
});
|
||||
|
||||
const isDisplayBadge = computed(() => {
|
||||
return props.displayBadge === true && props.buttonText !== null;
|
||||
const isDisplayBadge = computed<boolean>(() => {
|
||||
return props.displayBadge && props.buttonText !== null;
|
||||
});
|
||||
|
||||
const badgeType = computed(() => {
|
||||
return "entity-" + props.type + " badge-" + props.type;
|
||||
const badgeType = computed<string>(() => {
|
||||
return "entity-" + (props.type ?? "") + " badge-" + (props.type ?? "");
|
||||
});
|
||||
|
||||
const getReturnPath = computed(() => {
|
||||
const getReturnPath = computed<string>(() => {
|
||||
return `?returnPath=${window.location.pathname}${window.location.search}${window.location.hash}`;
|
||||
});
|
||||
|
||||
function closeModal() {
|
||||
function closeModal(): void {
|
||||
modal.value.showModal = false;
|
||||
}
|
||||
|
||||
function openModal() {
|
||||
function openModal(): void {
|
||||
modal.value.showModal = true;
|
||||
}
|
||||
|
||||
function changeActionTo(action) {
|
||||
console.log(action);
|
||||
// Not reactive in setup, but you can emit or use a ref if needed
|
||||
}
|
||||
|
||||
function saveAction() {
|
||||
let type = props.type,
|
||||
data = {};
|
||||
switch (type) {
|
||||
case "person":
|
||||
data = castPerson.value?.$data.person;
|
||||
break;
|
||||
case "thirdparty":
|
||||
data = castThirdparty.value?.$data.thirdparty;
|
||||
break;
|
||||
default:
|
||||
if (typeof props.type === "undefined") {
|
||||
if (props.action === "addContact") {
|
||||
type = "thirdparty";
|
||||
data = castThirdparty.value?.$data.thirdparty;
|
||||
data.parent = {
|
||||
type: "thirdparty",
|
||||
id: props.parent.id,
|
||||
};
|
||||
data.civility =
|
||||
data.civility !== null
|
||||
? {
|
||||
type: "chill_main_civility",
|
||||
id: data.civility.id,
|
||||
}
|
||||
: null;
|
||||
data.profession = data.profession !== "" ? data.profession : "";
|
||||
} else {
|
||||
type = castNew.value.radioType;
|
||||
data = castNew.value.castDataByType();
|
||||
if (typeof data.civility !== "undefined" && null !== data.civility) {
|
||||
data.civility =
|
||||
data.civility !== null
|
||||
? {
|
||||
type: "chill_main_civility",
|
||||
id: data.civility.id,
|
||||
}
|
||||
: null;
|
||||
}
|
||||
if (
|
||||
typeof data.profession !== "undefined" &&
|
||||
"" !== data.profession
|
||||
) {
|
||||
data.profession = data.profession !== "" ? data.profession : "";
|
||||
}
|
||||
}
|
||||
} else {
|
||||
throw "error with object type";
|
||||
}
|
||||
}
|
||||
emit("saveFormOnTheFly", { type: type, data: data });
|
||||
}
|
||||
|
||||
function buildLocation(id, type) {
|
||||
function buildLocation(id: string | number | undefined, type: EntityType | undefined): string | undefined {
|
||||
if (type === "person") {
|
||||
return encodeURI(`/fr/person/${id}/general${getReturnPath.value}`);
|
||||
} else if (type === "thirdparty") {
|
||||
return encodeURI(`/fr/3party/3party/${id}/view${getReturnPath.value}`);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
openModal,
|
||||
closeModal,
|
||||
changeActionTo,
|
||||
saveAction,
|
||||
castPerson,
|
||||
castThirdparty,
|
||||
castNew,
|
||||
hasResourceComment,
|
||||
modal,
|
||||
isDisplayBadge,
|
||||
|
||||
Reference in New Issue
Block a user