mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-12-12 21:33:13 +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:
@@ -41,6 +41,7 @@
|
|||||||
"typescript": "^5.6.3",
|
"typescript": "^5.6.3",
|
||||||
"typescript-eslint": "^8.13.0",
|
"typescript-eslint": "^8.13.0",
|
||||||
"vue-loader": "^17.0.0",
|
"vue-loader": "^17.0.0",
|
||||||
|
"vue-tsc": "^3.1.1",
|
||||||
"webpack": "^5.75.0",
|
"webpack": "^5.75.0",
|
||||||
"webpack-cli": "^5.0.1"
|
"webpack-cli": "^5.0.1"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -54,7 +54,6 @@ $chill-theme-buttons: (
|
|||||||
&.btn-unlink,
|
&.btn-unlink,
|
||||||
&.btn-action,
|
&.btn-action,
|
||||||
&.btn-edit,
|
&.btn-edit,
|
||||||
&.btn-tpchild,
|
|
||||||
&.btn-wopilink,
|
&.btn-wopilink,
|
||||||
&.btn-update {
|
&.btn-update {
|
||||||
&, &:hover {
|
&, &:hover {
|
||||||
@@ -82,7 +81,6 @@ $chill-theme-buttons: (
|
|||||||
&.btn-remove::before,
|
&.btn-remove::before,
|
||||||
&.btn-choose::before,
|
&.btn-choose::before,
|
||||||
&.btn-notify::before,
|
&.btn-notify::before,
|
||||||
&.btn-tpchild::before,
|
|
||||||
&.btn-download::before,
|
&.btn-download::before,
|
||||||
&.btn-search::before,
|
&.btn-search::before,
|
||||||
&.btn-cancel::before {
|
&.btn-cancel::before {
|
||||||
@@ -112,7 +110,6 @@ $chill-theme-buttons: (
|
|||||||
&.btn-choose::before { content: "\f00c"; } // fa-check // f046 fa-check-square-o
|
&.btn-choose::before { content: "\f00c"; } // fa-check // f046 fa-check-square-o
|
||||||
&.btn-unlink::before { content: "\f127"; } // fa-chain-broken
|
&.btn-unlink::before { content: "\f127"; } // fa-chain-broken
|
||||||
&.btn-notify::before { content: "\f1d8"; } // fa-paper-plane
|
&.btn-notify::before { content: "\f1d8"; } // fa-paper-plane
|
||||||
&.btn-tpchild::before { content: "\f007"; } // fa-user
|
|
||||||
&.btn-download::before { content: "\f019"; } // fa-download
|
&.btn-download::before { content: "\f019"; } // fa-download
|
||||||
&.btn-search::before { content: "\f002"; } // fa-search
|
&.btn-search::before { content: "\f002"; } // fa-search
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { GenericDoc } from "ChillDocStoreAssets/types/generic_doc";
|
import { GenericDoc } from "ChillDocStoreAssets/types/generic_doc";
|
||||||
import { StoredObject, StoredObjectStatus } from "ChillDocStoreAssets/types";
|
import { StoredObject, StoredObjectStatus } from "ChillDocStoreAssets/types";
|
||||||
import { CreatableEntityType } from "ChillPersonAssets/types";
|
import { CreatableEntityType } from "ChillPersonAssets/types";
|
||||||
|
import {ThirdpartyCompany} from "../../../ChillThirdPartyBundle/Resources/public/types";
|
||||||
|
|
||||||
export interface DateTime {
|
export interface DateTime {
|
||||||
datetime: string;
|
datetime: string;
|
||||||
@@ -413,11 +414,22 @@ export interface TabDefinition {
|
|||||||
counter: () => number;
|
counter: () => number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type CreateComponentConfigGeneral = {
|
||||||
|
action: 'create';
|
||||||
|
allowedTypes: CreatableEntityType[];
|
||||||
|
query: string;
|
||||||
|
parent: null;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type CreateComponentThirdPartyAddContact = {
|
||||||
|
action: 'addContact';
|
||||||
|
allowedTypes: readonly ['thirdparty'];
|
||||||
|
query: string;
|
||||||
|
parent: ThirdpartyCompany;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configuration for the CreateModal and Create component
|
* Configuration for the CreateModal and Create component
|
||||||
*/
|
*/
|
||||||
export interface CreateComponentConfig {
|
export type CreateComponentConfig = CreateComponentConfigGeneral | CreateComponentThirdPartyAddContact;
|
||||||
action?: string;
|
|
||||||
allowedTypes: CreatableEntityType[];
|
|
||||||
query?: string;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -36,21 +36,21 @@
|
|||||||
action="create"
|
action="create"
|
||||||
:query="query"
|
:query="query"
|
||||||
ref="castPerson"
|
ref="castPerson"
|
||||||
@onPersonCreated="(payload) => emit('onPersonCreated', payload)"
|
@onPersonCreated="onPersonCreated"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<on-the-fly-thirdparty
|
<ThirdPartyEdit
|
||||||
v-if="type === 'thirdparty'"
|
v-if="type === 'thirdparty'"
|
||||||
:action="action"
|
:action="action"
|
||||||
:query="query"
|
:query="query"
|
||||||
ref="castThirdparty"
|
ref="castThirdparty"
|
||||||
|
@onThirdPartyCreated="onThirdPartyCreated"
|
||||||
|
type=""
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed, onMounted, ref } from "vue";
|
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 {
|
import {
|
||||||
ONTHEFLY_CREATE_PERSON,
|
ONTHEFLY_CREATE_PERSON,
|
||||||
ONTHEFLY_CREATE_THIRDPARTY,
|
ONTHEFLY_CREATE_THIRDPARTY,
|
||||||
@@ -59,15 +59,20 @@ import {
|
|||||||
import { CreatableEntityType, Person } from "ChillPersonAssets/types";
|
import { CreatableEntityType, Person } from "ChillPersonAssets/types";
|
||||||
import { CreateComponentConfig } from "ChillMainAssets/types";
|
import { CreateComponentConfig } from "ChillMainAssets/types";
|
||||||
import PersonEdit from "ChillPersonAssets/vuejs/_components/OnTheFly/PersonEdit.vue";
|
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>(), {
|
const props = withDefaults(defineProps<CreateComponentConfig>(), {
|
||||||
allowedTypes: ["person"],
|
|
||||||
action: "create",
|
action: "create",
|
||||||
query: "",
|
query: "",
|
||||||
|
parent: null,
|
||||||
});
|
});
|
||||||
|
|
||||||
const emit =
|
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);
|
const type = ref<CreatableEntityType | null>(null);
|
||||||
|
|
||||||
@@ -80,14 +85,10 @@ const radioType = computed<CreatableEntityType | null>({
|
|||||||
});
|
});
|
||||||
|
|
||||||
type PersonEditComponent = InstanceType<typeof PersonEdit>;
|
type PersonEditComponent = InstanceType<typeof PersonEdit>;
|
||||||
|
type ThirdPartyEditComponent = InstanceType<typeof ThirdPartyEdit>;
|
||||||
|
|
||||||
type AnyComponentInstance =
|
const castPerson = ref<PersonEditComponent|null>(null);
|
||||||
| InstanceType<typeof OnTheFlyPerson>
|
const castThirdparty = ref<ThirdPartyEditComponent|null>(null);
|
||||||
| InstanceType<typeof OnTheFlyThirdparty>
|
|
||||||
| null;
|
|
||||||
|
|
||||||
const castPerson = ref<PersonEditComponent>(null);
|
|
||||||
const castThirdparty = ref<AnyComponentInstance>(null);
|
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
type.value =
|
type.value =
|
||||||
@@ -104,11 +105,26 @@ const containsThirdParty = computed<boolean>(() =>
|
|||||||
props.allowedTypes.includes("thirdparty"),
|
props.allowedTypes.includes("thirdparty"),
|
||||||
);
|
);
|
||||||
const containsPerson = computed<boolean>(() => {
|
const containsPerson = computed<boolean>(() => {
|
||||||
|
if (props.action === 'addContact') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
return props.allowedTypes.includes("person");
|
return props.allowedTypes.includes("person");
|
||||||
});
|
});
|
||||||
|
|
||||||
function save(): void {
|
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 });
|
defineExpose({ save });
|
||||||
|
|||||||
@@ -5,19 +5,29 @@ import { CreateComponentConfig } from "ChillMainAssets/types";
|
|||||||
import { trans, SAVE } from "translator";
|
import { trans, SAVE } from "translator";
|
||||||
import { useTemplateRef } from "vue";
|
import { useTemplateRef } from "vue";
|
||||||
import { Person } from "ChillPersonAssets/types";
|
import { Person } from "ChillPersonAssets/types";
|
||||||
|
import {Thirdparty} from "../../../../../../ChillThirdPartyBundle/Resources/public/types";
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
(e: "onPersonCreated", payload: { person: Person }): void;
|
(e: "onPersonCreated", payload: { person: Person }): void;
|
||||||
|
(e: "onThirdPartyCreated", payload: { thirdParty: Thirdparty }): void;
|
||||||
(e: "close"): void;
|
(e: "close"): void;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const props = defineProps<CreateComponentConfig>();
|
const props = defineProps<CreateComponentConfig & {modalTitle: string}>();
|
||||||
const modalDialogClass = { "modal-xl": true, "modal-scrollable": true };
|
const modalDialogClass = { "modal-xl": true, "modal-scrollable": true };
|
||||||
|
|
||||||
type CreateComponentType = InstanceType<typeof Create>;
|
type CreateComponentType = InstanceType<typeof Create>;
|
||||||
|
|
||||||
const create = useTemplateRef<CreateComponentType>("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 {
|
function save(): void {
|
||||||
console.log("save from CreateModal");
|
console.log("save from CreateModal");
|
||||||
create.value?.save();
|
create.value?.save();
|
||||||
@@ -43,7 +53,8 @@ defineExpose({ save });
|
|||||||
:allowedTypes="props.allowedTypes"
|
:allowedTypes="props.allowedTypes"
|
||||||
:action="props.action"
|
:action="props.action"
|
||||||
:query="props.query"
|
:query="props.query"
|
||||||
@onPersonCreated="(payload) => emit('onPersonCreated', payload)"
|
@onPersonCreated="onPersonCreated"
|
||||||
|
@onThirdPartyCreated="onThirdPartyCreated"
|
||||||
></Create>
|
></Create>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
class="btn btn-sm"
|
class="btn btn-sm"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
:class="classAction"
|
:class="classAction"
|
||||||
:title="trans(titleAction)"
|
:title="titleAction"
|
||||||
@click="openModal"
|
@click="openModal"
|
||||||
>
|
>
|
||||||
{{ buttonText }}<span v-if="isDead"> (‡)</span>
|
{{ buttonText }}<span v-if="isDead"> (‡)</span>
|
||||||
@@ -23,14 +23,14 @@
|
|||||||
>
|
>
|
||||||
<template #header>
|
<template #header>
|
||||||
<h3 v-if="parent" class="modal-title">
|
<h3 v-if="parent" class="modal-title">
|
||||||
{{ trans(titleModal, { q: parent.text }) }}
|
{{ titleModal }}
|
||||||
</h3>
|
</h3>
|
||||||
<h3 v-else class="modal-title">
|
<h3 v-else class="modal-title">
|
||||||
{{ trans(titleModal) }}
|
{{ titleModal }}
|
||||||
</h3>
|
</h3>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #body v-if="type === 'person'">
|
<template #body v-if="type === 'person' && action !== 'addContact'">
|
||||||
<on-the-fly-person
|
<on-the-fly-person
|
||||||
:id="id"
|
:id="id"
|
||||||
:type="type"
|
:type="type"
|
||||||
@@ -40,7 +40,7 @@
|
|||||||
<div v-if="hasResourceComment">
|
<div v-if="hasResourceComment">
|
||||||
<h3>{{ trans(ONTHEFLY_RESOURCE_COMMENT_TITLE) }}</h3>
|
<h3>{{ trans(ONTHEFLY_RESOURCE_COMMENT_TITLE) }}</h3>
|
||||||
<blockquote class="chill-user-quote">
|
<blockquote class="chill-user-quote">
|
||||||
{{ parent.comment }}
|
{{ parent?.comment }}
|
||||||
</blockquote>
|
</blockquote>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -55,7 +55,7 @@
|
|||||||
<div v-if="hasResourceComment">
|
<div v-if="hasResourceComment">
|
||||||
<h3>{{ trans(ONTHEFLY_RESOURCE_COMMENT_TITLE) }}</h3>
|
<h3>{{ trans(ONTHEFLY_RESOURCE_COMMENT_TITLE) }}</h3>
|
||||||
<blockquote class="chill-user-quote">
|
<blockquote class="chill-user-quote">
|
||||||
{{ parent.comment }}
|
{{ parent?.comment }}
|
||||||
</blockquote>
|
</blockquote>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -73,27 +73,23 @@
|
|||||||
<on-the-fly-create
|
<on-the-fly-create
|
||||||
:action="action"
|
:action="action"
|
||||||
:allowed-types="allowedTypes"
|
:allowed-types="allowedTypes"
|
||||||
:query="query"
|
:query="query || ''"
|
||||||
ref="castNew"
|
ref="castNew"
|
||||||
/>
|
/>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<a
|
<a
|
||||||
v-if="action === 'show'"
|
|
||||||
:href="buildLocation(id, type)"
|
:href="buildLocation(id, type)"
|
||||||
:title="trans(titleMessage)"
|
:title="titleMessage"
|
||||||
class="btn btn-show"
|
class="btn btn-show"
|
||||||
>{{ trans(buttonMessage) }}
|
>{{ buttonMessage }}
|
||||||
</a>
|
|
||||||
<a v-else class="btn btn-save" @click="saveAction">
|
|
||||||
{{ trans(ACTION_SAVE) }}
|
|
||||||
</a>
|
</a>
|
||||||
</template>
|
</template>
|
||||||
</modal>
|
</modal>
|
||||||
</teleport>
|
</teleport>
|
||||||
</template>
|
</template>
|
||||||
<script setup>
|
<script setup lang="ts">
|
||||||
import { ref, computed, defineEmits, defineProps } from "vue";
|
import { ref, computed, defineEmits, defineProps } from "vue";
|
||||||
import Modal from "ChillMainAssets/vuejs/_components/Modal.vue";
|
import Modal from "ChillMainAssets/vuejs/_components/Modal.vue";
|
||||||
import OnTheFlyCreate from "./Create.vue";
|
import OnTheFlyCreate from "./Create.vue";
|
||||||
@@ -104,7 +100,6 @@ import {
|
|||||||
ACTION_SHOW,
|
ACTION_SHOW,
|
||||||
ACTION_EDIT,
|
ACTION_EDIT,
|
||||||
ACTION_CREATE,
|
ACTION_CREATE,
|
||||||
ACTION_ADDCONTACT,
|
|
||||||
ONTHEFLY_CREATE_TITLE_DEFAULT,
|
ONTHEFLY_CREATE_TITLE_DEFAULT,
|
||||||
ONTHEFLY_CREATE_TITLE_PERSON,
|
ONTHEFLY_CREATE_TITLE_PERSON,
|
||||||
ONTHEFLY_CREATE_TITLE_THIRDPARTY,
|
ONTHEFLY_CREATE_TITLE_THIRDPARTY,
|
||||||
@@ -112,40 +107,58 @@ import {
|
|||||||
ONTHEFLY_SHOW_THIRDPARTY,
|
ONTHEFLY_SHOW_THIRDPARTY,
|
||||||
ONTHEFLY_EDIT_PERSON,
|
ONTHEFLY_EDIT_PERSON,
|
||||||
ONTHEFLY_EDIT_THIRDPARTY,
|
ONTHEFLY_EDIT_THIRDPARTY,
|
||||||
ONTHEFLY_ADDCONTACT_TITLE,
|
|
||||||
ACTION_REDIRECT_PERSON,
|
ACTION_REDIRECT_PERSON,
|
||||||
ACTION_REDIRECT_THIRDPARTY,
|
ACTION_REDIRECT_THIRDPARTY,
|
||||||
ONTHEFLY_SHOW_FILE_PERSON,
|
ONTHEFLY_SHOW_FILE_PERSON,
|
||||||
ONTHEFLY_SHOW_FILE_THIRDPARTY,
|
ONTHEFLY_SHOW_FILE_THIRDPARTY,
|
||||||
ONTHEFLY_SHOW_FILE_DEFAULT,
|
ONTHEFLY_SHOW_FILE_DEFAULT,
|
||||||
ONTHEFLY_RESOURCE_COMMENT_TITLE,
|
ONTHEFLY_RESOURCE_COMMENT_TITLE,
|
||||||
ACTION_SAVE,
|
THIRDPARTY_ADDCONTACT,
|
||||||
|
THIRDPARTY_ADDCONTACT_TITLE,
|
||||||
} from "translator";
|
} from "translator";
|
||||||
|
|
||||||
const props = defineProps({
|
// Types
|
||||||
type: String,
|
type EntityType = "person" | "thirdparty";
|
||||||
id: [String, Number],
|
type ActionType = "show" | "edit" | "create" | "addContact";
|
||||||
action: String,
|
|
||||||
buttonText: String,
|
interface ParentRef {
|
||||||
displayBadge: Boolean,
|
type: string;
|
||||||
isDead: Boolean,
|
id: string | number;
|
||||||
parent: Object,
|
text?: string;
|
||||||
allowedTypes: Array,
|
comment?: string | null;
|
||||||
query: String,
|
}
|
||||||
|
|
||||||
|
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,
|
showModal: false,
|
||||||
modalDialogClass: "modal-dialog-scrollable modal-xl",
|
modalDialogClass: "modal-dialog-scrollable modal-xl",
|
||||||
});
|
});
|
||||||
|
|
||||||
const castPerson = ref();
|
const hasResourceComment = computed<boolean>(() => {
|
||||||
const castThirdparty = ref();
|
|
||||||
const castNew = ref();
|
|
||||||
|
|
||||||
const hasResourceComment = computed(() => {
|
|
||||||
return (
|
return (
|
||||||
typeof props.parent !== "undefined" &&
|
typeof props.parent !== "undefined" &&
|
||||||
props.parent !== null &&
|
props.parent !== null &&
|
||||||
@@ -156,7 +169,7 @@ const hasResourceComment = computed(() => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
const classAction = computed(() => {
|
const classAction = computed<string>(() => {
|
||||||
switch (props.action) {
|
switch (props.action) {
|
||||||
case "show":
|
case "show":
|
||||||
return "btn-show";
|
return "btn-show";
|
||||||
@@ -171,174 +184,112 @@ const classAction = computed(() => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const titleAction = computed(() => {
|
const titleAction = computed<string>(() => {
|
||||||
switch (props.action) {
|
switch (props.action) {
|
||||||
case "show":
|
case "show":
|
||||||
return ACTION_SHOW;
|
return ACTION_SHOW as unknown as string;
|
||||||
case "edit":
|
case "edit":
|
||||||
return ACTION_EDIT;
|
return ACTION_EDIT as unknown as string;
|
||||||
case "create":
|
case "create":
|
||||||
return ACTION_CREATE;
|
return ACTION_CREATE as unknown as string;
|
||||||
case "addContact":
|
case "addContact":
|
||||||
return ACTION_ADDCONTACT;
|
return THIRDPARTY_ADDCONTACT as unknown as string;
|
||||||
default:
|
default:
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const titleCreate = computed(() => {
|
const titleCreate = computed<string>(() => {
|
||||||
if (typeof props.allowedTypes === "undefined") {
|
if (typeof props.allowedTypes === "undefined") {
|
||||||
return ONTHEFLY_CREATE_TITLE_DEFAULT;
|
return trans(ONTHEFLY_CREATE_TITLE_DEFAULT)
|
||||||
}
|
}
|
||||||
return props.allowedTypes.every((t) => t === "person")
|
return props.allowedTypes.every((t: EntityType) => t === "person")
|
||||||
? ONTHEFLY_CREATE_TITLE_PERSON
|
? (trans(ONTHEFLY_CREATE_TITLE_PERSON))
|
||||||
: props.allowedTypes.every((t) => t === "thirdparty")
|
: props.allowedTypes.every((t: EntityType) => t === "thirdparty")
|
||||||
? ONTHEFLY_CREATE_TITLE_THIRDPARTY
|
? (trans(ONTHEFLY_CREATE_TITLE_THIRDPARTY))
|
||||||
: ONTHEFLY_CREATE_TITLE_DEFAULT;
|
: (trans(ONTHEFLY_CREATE_TITLE_DEFAULT));
|
||||||
});
|
});
|
||||||
|
|
||||||
const titleModal = computed(() => {
|
const titleModal = computed<string>(() => {
|
||||||
switch (props.action) {
|
switch (props.action) {
|
||||||
case "show":
|
case "show":
|
||||||
if (props.type == "person") {
|
if (props.type == "person") {
|
||||||
return ONTHEFLY_SHOW_PERSON;
|
return trans(ONTHEFLY_SHOW_PERSON)
|
||||||
} else if (props.type == "thirdparty") {
|
} else if (props.type == "thirdparty") {
|
||||||
return ONTHEFLY_SHOW_THIRDPARTY;
|
return trans(ONTHEFLY_SHOW_THIRDPARTY)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "edit":
|
case "edit":
|
||||||
if (props.type == "person") {
|
if (props.type == "person") {
|
||||||
return ONTHEFLY_EDIT_PERSON;
|
return trans(ONTHEFLY_EDIT_PERSON)
|
||||||
} else if (props.type == "thirdparty") {
|
} else if (props.type == "thirdparty") {
|
||||||
return ONTHEFLY_EDIT_THIRDPARTY;
|
return trans(ONTHEFLY_EDIT_THIRDPARTY)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case "create":
|
case "create":
|
||||||
return titleCreate.value;
|
return titleCreate.value;
|
||||||
case "addContact":
|
case "addContact":
|
||||||
return ONTHEFLY_ADDCONTACT_TITLE;
|
return trans(THIRDPARTY_ADDCONTACT_TITLE)
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return "";
|
return "";
|
||||||
});
|
});
|
||||||
|
|
||||||
const titleMessage = computed(() => {
|
const titleMessage = computed<string>(() => {
|
||||||
switch (props.type) {
|
switch (props.type) {
|
||||||
case "person":
|
case "person":
|
||||||
return ACTION_REDIRECT_PERSON;
|
return trans(ACTION_REDIRECT_PERSON);
|
||||||
case "thirdparty":
|
case "thirdparty":
|
||||||
return ACTION_REDIRECT_THIRDPARTY;
|
return trans(ACTION_REDIRECT_THIRDPARTY);
|
||||||
default:
|
default:
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const buttonMessage = computed(() => {
|
const buttonMessage = computed<string>(() => {
|
||||||
switch (props.type) {
|
switch (props.type) {
|
||||||
case "person":
|
case "person":
|
||||||
return ONTHEFLY_SHOW_FILE_PERSON;
|
return trans(ONTHEFLY_SHOW_FILE_PERSON);
|
||||||
case "thirdparty":
|
case "thirdparty":
|
||||||
return ONTHEFLY_SHOW_FILE_THIRDPARTY;
|
return trans(ONTHEFLY_SHOW_FILE_THIRDPARTY);
|
||||||
default:
|
default:
|
||||||
return ONTHEFLY_SHOW_FILE_DEFAULT;
|
return trans(ONTHEFLY_SHOW_FILE_DEFAULT);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const isDisplayBadge = computed(() => {
|
const isDisplayBadge = computed<boolean>(() => {
|
||||||
return props.displayBadge === true && props.buttonText !== null;
|
return props.displayBadge && props.buttonText !== null;
|
||||||
});
|
});
|
||||||
|
|
||||||
const badgeType = computed(() => {
|
const badgeType = computed<string>(() => {
|
||||||
return "entity-" + props.type + " badge-" + props.type;
|
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}`;
|
return `?returnPath=${window.location.pathname}${window.location.search}${window.location.hash}`;
|
||||||
});
|
});
|
||||||
|
|
||||||
function closeModal() {
|
function closeModal(): void {
|
||||||
modal.value.showModal = false;
|
modal.value.showModal = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function openModal() {
|
function openModal(): void {
|
||||||
modal.value.showModal = true;
|
modal.value.showModal = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
function changeActionTo(action) {
|
function buildLocation(id: string | number | undefined, type: EntityType | undefined): string | undefined {
|
||||||
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) {
|
|
||||||
if (type === "person") {
|
if (type === "person") {
|
||||||
return encodeURI(`/fr/person/${id}/general${getReturnPath.value}`);
|
return encodeURI(`/fr/person/${id}/general${getReturnPath.value}`);
|
||||||
} else if (type === "thirdparty") {
|
} else if (type === "thirdparty") {
|
||||||
return encodeURI(`/fr/3party/3party/${id}/view${getReturnPath.value}`);
|
return encodeURI(`/fr/3party/3party/${id}/view${getReturnPath.value}`);
|
||||||
}
|
}
|
||||||
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
defineExpose({
|
defineExpose({
|
||||||
openModal,
|
openModal,
|
||||||
closeModal,
|
closeModal,
|
||||||
changeActionTo,
|
|
||||||
saveAction,
|
|
||||||
castPerson,
|
|
||||||
castThirdparty,
|
|
||||||
castNew,
|
|
||||||
hasResourceComment,
|
hasResourceComment,
|
||||||
modal,
|
modal,
|
||||||
isDisplayBadge,
|
isDisplayBadge,
|
||||||
|
|||||||
@@ -935,6 +935,7 @@ onthefly:
|
|||||||
thirdparty: Détails du tiers
|
thirdparty: Détails du tiers
|
||||||
file_person: Ouvrir la fiche de l'usager
|
file_person: Ouvrir la fiche de l'usager
|
||||||
file_thirdparty: Voir le Tiers
|
file_thirdparty: Voir le Tiers
|
||||||
|
file_default: Voir
|
||||||
edit:
|
edit:
|
||||||
person: Modifier un usager
|
person: Modifier un usager
|
||||||
thirdparty: Modifier un tiers
|
thirdparty: Modifier un tiers
|
||||||
|
|||||||
@@ -369,7 +369,7 @@ export interface AccompanyingPeriodWorkEvaluationDocument {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Entity types that a user can create
|
* Entity types that a user can create through AddPersons component
|
||||||
*/
|
*/
|
||||||
export type CreatableEntityType = "person" | "thirdparty";
|
export type CreatableEntityType = "person" | "thirdparty";
|
||||||
|
|
||||||
@@ -382,15 +382,32 @@ export type EntityType =
|
|||||||
| "user"
|
| "user"
|
||||||
| "household";
|
| "household";
|
||||||
|
|
||||||
export type Entities = (UserGroup | User | Person | Thirdparty | Household) & {
|
export type Entities = (UserGroup | User | Person | Thirdparty | Household);
|
||||||
address?: Address | null;
|
|
||||||
kind?: string;
|
|
||||||
text?: string;
|
|
||||||
profession?: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type EntitiesOrMe = "me" | Entities;
|
export type EntitiesOrMe = "me" | Entities;
|
||||||
|
|
||||||
|
|
||||||
|
// Type guards to discriminate Suggestions by their result kind
|
||||||
|
export function isSuggestionForUserGroup(s: Suggestion): s is Suggestion & { result: UserGroup } {
|
||||||
|
return (s as any)?.result?.type === "user_group";
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isSuggestionForUser(s: Suggestion): s is Suggestion & { result: User } {
|
||||||
|
return (s as any)?.result?.type === "user";
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isSuggestionForPerson(s: Suggestion): s is Suggestion & { result: Person } {
|
||||||
|
return (s as any)?.result?.type === "person";
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isSuggestionForThirdParty(s: Suggestion): s is Suggestion & { result: Thirdparty } {
|
||||||
|
return (s as any)?.result?.type === "thirdparty";
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isSuggestionForHousehold(s: Suggestion): s is Suggestion & { result: Household } {
|
||||||
|
return (s as any)?.result?.type === "household";
|
||||||
|
}
|
||||||
|
|
||||||
export type AddPersonResult = Entities & {
|
export type AddPersonResult = Entities & {
|
||||||
parent?: Entities | null;
|
parent?: Entities | null;
|
||||||
};
|
};
|
||||||
@@ -398,7 +415,7 @@ export type AddPersonResult = Entities & {
|
|||||||
export interface Suggestion {
|
export interface Suggestion {
|
||||||
key: string;
|
key: string;
|
||||||
relevance: number;
|
relevance: number;
|
||||||
result: AddPersonResult;
|
result: Entities;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface SearchPagination {
|
export interface SearchPagination {
|
||||||
|
|||||||
@@ -19,12 +19,27 @@
|
|||||||
@close="closeModalChoose"
|
@close="closeModalChoose"
|
||||||
@addNewPersons="(payload) => emit('addNewPersons', payload)"
|
@addNewPersons="(payload) => emit('addNewPersons', payload)"
|
||||||
@onAskForCreate="onAskForCreate"
|
@onAskForCreate="onAskForCreate"
|
||||||
|
@triggerAddContact="triggerAddContact"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<CreateModal
|
<CreateModal
|
||||||
v-if="creatableEntityTypes.length > 0 && showModalCreate"
|
v-if="creatableEntityTypes.length > 0 && showModalCreate && null == thirdPartyParentAddContact"
|
||||||
|
action="create"
|
||||||
:allowed-types="creatableEntityTypes"
|
:allowed-types="creatableEntityTypes"
|
||||||
:query="query"
|
:query="query"
|
||||||
|
:parent="null"
|
||||||
|
modalTitle="test"
|
||||||
|
@close="closeModalCreate"
|
||||||
|
@onPersonCreated="onPersonCreated"
|
||||||
|
></CreateModal>
|
||||||
|
|
||||||
|
<CreateModal
|
||||||
|
v-if="showModalCreate && thirdPartyParentAddContact !== null"
|
||||||
|
:allowed-types="['thirdparty']"
|
||||||
|
action="addContact"
|
||||||
|
modalTitle="test"
|
||||||
|
:parent="thirdPartyParentAddContact"
|
||||||
|
:query="''"
|
||||||
@close="closeModalCreate"
|
@close="closeModalCreate"
|
||||||
@onPersonCreated="onPersonCreated"
|
@onPersonCreated="onPersonCreated"
|
||||||
></CreateModal>
|
></CreateModal>
|
||||||
@@ -43,6 +58,7 @@ import type {
|
|||||||
import { marked } from "marked";
|
import { marked } from "marked";
|
||||||
import options = marked.options;
|
import options = marked.options;
|
||||||
import CreateModal from "ChillMainAssets/vuejs/OnTheFly/components/CreateModal.vue";
|
import CreateModal from "ChillMainAssets/vuejs/OnTheFly/components/CreateModal.vue";
|
||||||
|
import {ThirdpartyCompany} from "../../../../../ChillThirdPartyBundle/Resources/public/types";
|
||||||
|
|
||||||
interface AddPersonsConfig {
|
interface AddPersonsConfig {
|
||||||
suggested?: Suggestion[];
|
suggested?: Suggestion[];
|
||||||
@@ -69,6 +85,8 @@ const emit =
|
|||||||
const showModalChoose = ref(false);
|
const showModalChoose = ref(false);
|
||||||
const showModalCreate = ref(false);
|
const showModalCreate = ref(false);
|
||||||
const query = ref("");
|
const query = ref("");
|
||||||
|
const thirdPartyParentAddContact = ref<ThirdpartyCompany|null>(null);
|
||||||
|
const allowedTypesAddContact = ['addContact'];
|
||||||
|
|
||||||
const getClassButton = computed(() => {
|
const getClassButton = computed(() => {
|
||||||
const size = props.options?.button?.size ?? "";
|
const size = props.options?.button?.size ?? "";
|
||||||
@@ -95,7 +113,7 @@ const creatableEntityTypes = computed<CreatableEntityType[]>(() => {
|
|||||||
|
|
||||||
function onAskForCreate(payload: { query: string }) {
|
function onAskForCreate(payload: { query: string }) {
|
||||||
query.value = payload.query;
|
query.value = payload.query;
|
||||||
showModalChoose.value = false;
|
closeModalChoose();
|
||||||
showModalCreate.value = true;
|
showModalCreate.value = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,9 +126,19 @@ function closeModalChoose() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function closeModalCreate() {
|
function closeModalCreate() {
|
||||||
|
if (null !== thirdPartyParentAddContact) {
|
||||||
|
thirdPartyParentAddContact.value = null;
|
||||||
|
}
|
||||||
showModalCreate.value = false;
|
showModalCreate.value = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function triggerAddContact({parent}: {parent: ThirdpartyCompany}) {
|
||||||
|
console.log("triggerAddContact", parent);
|
||||||
|
closeModalChoose();
|
||||||
|
thirdPartyParentAddContact.value = parent;
|
||||||
|
showModalCreate.value = true;
|
||||||
|
}
|
||||||
|
|
||||||
function onPersonCreated(payload: { person: Person }) {
|
function onPersonCreated(payload: { person: Person }) {
|
||||||
console.log("onPersonCreated", payload);
|
console.log("onPersonCreated", payload);
|
||||||
showModalCreate.value = false;
|
showModalCreate.value = false;
|
||||||
|
|||||||
@@ -64,8 +64,8 @@
|
|||||||
:item="item"
|
:item="item"
|
||||||
:search="search"
|
:search="search"
|
||||||
:type="checkUniq"
|
:type="checkUniq"
|
||||||
@new-prior-suggestion="newPriorSuggestion"
|
|
||||||
@update-selected="updateSelected"
|
@update-selected="updateSelected"
|
||||||
|
@trigger-add-contact="(payload) => emit('triggerAddContact', payload)"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
@@ -114,12 +114,11 @@ import {
|
|||||||
import type {
|
import type {
|
||||||
Suggestion,
|
Suggestion,
|
||||||
Search,
|
Search,
|
||||||
AddPersonResult as OriginalResult,
|
EntityType,
|
||||||
SearchOptions,
|
SearchOptions,
|
||||||
EntitiesOrMe,
|
EntitiesOrMe,
|
||||||
} from "ChillPersonAssets/types";
|
} from "ChillPersonAssets/types";
|
||||||
|
import {ThirdpartyCompany} from "../../../../../../ChillThirdPartyBundle/Resources/public/types";
|
||||||
type Result = OriginalResult & { addressId?: number };
|
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
modalTitle: string;
|
modalTitle: string;
|
||||||
@@ -143,6 +142,7 @@ const emit = defineEmits<{
|
|||||||
(e: "addNewPersons", payload: { selected: Suggestion[] }): void;
|
(e: "addNewPersons", payload: { selected: Suggestion[] }): void;
|
||||||
(e: "onPickEntities", payload: { selected: EntitiesOrMe[] }): void;
|
(e: "onPickEntities", payload: { selected: EntitiesOrMe[] }): void;
|
||||||
(e: "onAskForCreate", payload: { query: string }): void;
|
(e: "onAskForCreate", payload: { query: string }): void;
|
||||||
|
(e: "triggerAddContact", payload: { parent: ThirdpartyCompany }): void;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const searchRef = ref<HTMLInputElement | null>(null);
|
const searchRef = ref<HTMLInputElement | null>(null);
|
||||||
@@ -200,7 +200,6 @@ function addPriorSuggestion() {
|
|||||||
if (hasPriorSuggestion.value) {
|
if (hasPriorSuggestion.value) {
|
||||||
search.suggested.unshift(priorSuggestion.value as Suggestion);
|
search.suggested.unshift(priorSuggestion.value as Suggestion);
|
||||||
search.selected.unshift(priorSuggestion.value as Suggestion);
|
search.selected.unshift(priorSuggestion.value as Suggestion);
|
||||||
newPriorSuggestion(null);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -285,17 +284,8 @@ function selectAll() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function newPriorSuggestion(entity: Result | null) {
|
function triggerAddContact(payload: {parent: ThirdpartyCompany}) {
|
||||||
if (entity !== null) {
|
emit("triggerAddContact", payload);
|
||||||
const suggestion: Suggestion = {
|
|
||||||
key: entity.type + entity.id,
|
|
||||||
relevance: 0.5,
|
|
||||||
result: entity,
|
|
||||||
} as Suggestion;
|
|
||||||
search.priorSuggestion = suggestion;
|
|
||||||
} else {
|
|
||||||
search.priorSuggestion = {};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -12,28 +12,28 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<suggestion-person
|
<suggestion-person
|
||||||
v-if="item.result.type === 'person'"
|
v-if="isSuggestionForPerson(item)"
|
||||||
:item="item"
|
:item="item"
|
||||||
></suggestion-person>
|
></suggestion-person>
|
||||||
|
|
||||||
<suggestion-third-party
|
<suggestion-third-party
|
||||||
v-if="item.result.type === 'thirdparty'"
|
v-if="isSuggestionForThirdParty(item)"
|
||||||
@newPriorSuggestion="newPriorSuggestion"
|
@trigger-add-contact="triggerAddContact"
|
||||||
:item="item"
|
:item="item"
|
||||||
></suggestion-third-party>
|
></suggestion-third-party>
|
||||||
|
|
||||||
<suggestion-user
|
<suggestion-user
|
||||||
v-if="item.result.type === 'user'"
|
v-if="isSuggestionForUser(item)"
|
||||||
:item="item"
|
:item="item"
|
||||||
></suggestion-user>
|
></suggestion-user>
|
||||||
|
|
||||||
<suggestion-user-group
|
<suggestion-user-group
|
||||||
v-if="item.result.type === 'user_group'"
|
v-if="isSuggestionForUserGroup(item)"
|
||||||
:item="item"
|
:item="item"
|
||||||
></suggestion-user-group>
|
></suggestion-user-group>
|
||||||
|
|
||||||
<suggestion-household
|
<suggestion-household
|
||||||
v-if="item.result.type === 'household'"
|
v-if="isSuggestionForHousehold(item)"
|
||||||
:item="item"
|
:item="item"
|
||||||
></suggestion-household>
|
></suggestion-household>
|
||||||
</label>
|
</label>
|
||||||
@@ -51,14 +51,24 @@ import SuggestionHousehold from "./TypeHousehold.vue";
|
|||||||
import SuggestionUserGroup from "./TypeUserGroup.vue";
|
import SuggestionUserGroup from "./TypeUserGroup.vue";
|
||||||
|
|
||||||
// Types
|
// Types
|
||||||
import { Result, Suggestion } from "ChillPersonAssets/types";
|
import {
|
||||||
|
isSuggestionForHousehold,
|
||||||
|
isSuggestionForPerson,
|
||||||
|
isSuggestionForThirdParty, isSuggestionForUser,
|
||||||
|
isSuggestionForUserGroup,
|
||||||
|
Suggestion
|
||||||
|
} from "ChillPersonAssets/types";
|
||||||
|
import {ThirdpartyCompany} from "../../../../../../ChillThirdPartyBundle/Resources/public/types";
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
item: Suggestion;
|
item: Suggestion;
|
||||||
search: { selected: Suggestion[] };
|
search: { selected: Suggestion[] };
|
||||||
type: string;
|
type: string;
|
||||||
}>();
|
}>();
|
||||||
const emit = defineEmits(["updateSelected", "newPriorSuggestion"]);
|
const emit = defineEmits<{
|
||||||
|
(e: "updateSelected", payload: Suggestion[]): void;
|
||||||
|
(e: "triggerAddContact", payload: { parent: ThirdpartyCompany }): void;
|
||||||
|
}>();
|
||||||
|
|
||||||
// v-model for selected
|
// v-model for selected
|
||||||
const selected = computed({
|
const selected = computed({
|
||||||
@@ -74,8 +84,8 @@ function setValueByType(value: Suggestion, type: string) {
|
|||||||
return type === "radio" ? [value] : value;
|
return type === "radio" ? [value] : value;
|
||||||
}
|
}
|
||||||
|
|
||||||
function newPriorSuggestion(response: Result) {
|
function triggerAddContact(payload: {parent: ThirdpartyCompany}) {
|
||||||
emit("newPriorSuggestion", response);
|
emit("triggerAddContact", payload);
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -16,9 +16,10 @@ import { defineProps } from "vue";
|
|||||||
import BadgeEntity from "ChillMainAssets/vuejs/_components/BadgeEntity.vue";
|
import BadgeEntity from "ChillMainAssets/vuejs/_components/BadgeEntity.vue";
|
||||||
import HouseholdRenderBox from "ChillPersonAssets/vuejs/_components/Entity/HouseholdRenderBox.vue";
|
import HouseholdRenderBox from "ChillPersonAssets/vuejs/_components/Entity/HouseholdRenderBox.vue";
|
||||||
import { Suggestion } from "ChillPersonAssets/types";
|
import { Suggestion } from "ChillPersonAssets/types";
|
||||||
|
import {Household} from "ChillMainAssets/types";
|
||||||
|
|
||||||
interface TypeHouseholdProps {
|
interface TypeHouseholdProps {
|
||||||
item: Suggestion;
|
item: Suggestion & {result: Household};
|
||||||
}
|
}
|
||||||
|
|
||||||
defineProps<TypeHouseholdProps>();
|
defineProps<TypeHouseholdProps>();
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ import { computed, defineProps } from "vue";
|
|||||||
import OnTheFly from "ChillMainAssets/vuejs/OnTheFly/components/OnTheFly.vue";
|
import OnTheFly from "ChillMainAssets/vuejs/OnTheFly/components/OnTheFly.vue";
|
||||||
import BadgeEntity from "ChillMainAssets/vuejs/_components/BadgeEntity.vue";
|
import BadgeEntity from "ChillMainAssets/vuejs/_components/BadgeEntity.vue";
|
||||||
import PersonText from "ChillPersonAssets/vuejs/_components/Entity/PersonText.vue";
|
import PersonText from "ChillPersonAssets/vuejs/_components/Entity/PersonText.vue";
|
||||||
import { Person } from "ChillPersonAssets/types";
|
import {Person, Suggestion} from "ChillPersonAssets/types";
|
||||||
|
|
||||||
function formatDate(dateString: string | undefined, format: string) {
|
function formatDate(dateString: string | undefined, format: string) {
|
||||||
if (!dateString) return "";
|
if (!dateString) return "";
|
||||||
@@ -36,9 +36,7 @@ function formatDate(dateString: string | undefined, format: string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
item: {
|
item: Suggestion & { result: Person },
|
||||||
result: Person; // add other fields as needed
|
|
||||||
};
|
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const hasBirthdate = computed(() => props.item.result.birthdate !== null);
|
const hasBirthdate = computed(() => props.item.result.birthdate !== null);
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="container tpartycontainer">
|
<div class="container tpartycontainer">
|
||||||
<div class="tparty-identification">
|
<div class="tparty-identification">
|
||||||
<span v-if="item.result.profession" class="profession">{{
|
<span v-if="(isThirdpartyChild(item.result) || isThirdpartyContact(item.result)) && item.result.profession" class="profession">{{
|
||||||
item.result.profession
|
item.result.profession
|
||||||
}}</span>
|
}}</span>
|
||||||
<span class="name"> {{ item.result.text }} </span>
|
<span class="name"> {{ item.result.text }} </span>
|
||||||
@@ -12,20 +12,18 @@
|
|||||||
</template>
|
</template>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="tpartyparent" v-if="hasParent">
|
<div class="tpartyparent" v-if="isThirdpartyChild(item.result) && null !== item.result.parent">
|
||||||
<span class="name"> > {{ item.result.parent?.text }} </span>
|
<span class="name"> > {{ item.result.parent.text }} </span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="right_actions">
|
<div class="right_actions">
|
||||||
<badge-entity :entity="item.result" :options="{ displayLong: true }" />
|
<badge-entity :entity="item.result" :options="{ displayLong: true }" />
|
||||||
<on-the-fly
|
<a
|
||||||
v-if="item.result.kind === 'company'"
|
v-if="item.result.type === 'thirdparty' && item.result.kind === 'company'"
|
||||||
:parent="item.result"
|
class="btn btn-tpchild"
|
||||||
@save-form-on-the-fly="saveFormOnTheFly"
|
@click="emit('triggerAddContact', {parent: item.result})"
|
||||||
action="addContact"
|
><i class="bi bi-person-fill-add"></i></a>
|
||||||
ref="onTheFly"
|
|
||||||
/>
|
|
||||||
<on-the-fly type="thirdparty" :id="item.result.id" action="show" />
|
<on-the-fly type="thirdparty" :id="item.result.id" action="show" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -37,15 +35,19 @@ import BadgeEntity from "ChillMainAssets/vuejs/_components/BadgeEntity.vue";
|
|||||||
import { makeFetch } from "ChillMainAssets/lib/api/apiMethods";
|
import { makeFetch } from "ChillMainAssets/lib/api/apiMethods";
|
||||||
import { useToast } from "vue-toast-notification";
|
import { useToast } from "vue-toast-notification";
|
||||||
import { Result, Suggestion } from "ChillPersonAssets/types";
|
import { Result, Suggestion } from "ChillPersonAssets/types";
|
||||||
import { Thirdparty } from "src/Bundle/ChillThirdPartyBundle/Resources/public/types";
|
import {
|
||||||
|
isThirdpartyChild,
|
||||||
|
isThirdpartyContact,
|
||||||
|
Thirdparty, ThirdpartyCompany
|
||||||
|
} from "./../../../../../../ChillThirdPartyBundle/Resources/public/types";
|
||||||
|
|
||||||
interface TypeThirdPartyProps {
|
interface TypeThirdPartyProps {
|
||||||
item: Suggestion;
|
item: Suggestion & {result: Thirdparty};
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = defineProps<TypeThirdPartyProps>();
|
const props = defineProps<TypeThirdPartyProps>();
|
||||||
|
|
||||||
const emit = defineEmits<(e: "newPriorSuggestion", payload: unknown) => void>();
|
const emit = defineEmits<(e: "triggerAddContact", payload: {parent: ThirdpartyCompany}) => void>();
|
||||||
|
|
||||||
const onTheFly = ref<InstanceType<typeof OnTheFly> | null>(null);
|
const onTheFly = ref<InstanceType<typeof OnTheFly> | null>(null);
|
||||||
const toast = useToast();
|
const toast = useToast();
|
||||||
@@ -54,47 +56,23 @@ const hasAddress = computed(() => {
|
|||||||
if (props.item.result.address !== null) {
|
if (props.item.result.address !== null) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (props.item.result.parent !== null) {
|
if (isThirdpartyChild(props.item.result) && props.item.result.parent !== null) {
|
||||||
if (props.item.result.parent) {
|
return props.item.result.parent.address !== null;
|
||||||
return props.item.result.parent.address !== null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
});
|
|
||||||
|
|
||||||
const hasParent = computed(() => {
|
return false;
|
||||||
return props.item.result.parent !== null;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const getAddress = computed(() => {
|
const getAddress = computed(() => {
|
||||||
if (props.item.result.address !== null) {
|
if (props.item.result.address !== null) {
|
||||||
return props.item.result.address;
|
return props.item.result.address;
|
||||||
}
|
}
|
||||||
if (props.item.result.parent && props.item.result.parent.address !== null) {
|
if (isThirdpartyChild(props.item.result) && props.item.result.parent !== null && props.item.result.parent.address !== null) {
|
||||||
return props.item.result.parent.address;
|
return props.item.result.parent.address;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
|
|
||||||
function saveFormOnTheFly({ data }: { data: Thirdparty }) {
|
|
||||||
makeFetch("POST", "/api/1.0/thirdparty/thirdparty.json", data)
|
|
||||||
.then((response: unknown) => {
|
|
||||||
const result = response as Result;
|
|
||||||
emit("newPriorSuggestion", result);
|
|
||||||
if (onTheFly.value) onTheFly.value.closeModal();
|
|
||||||
})
|
|
||||||
.catch((error: unknown) => {
|
|
||||||
const errorResponse = error as { name: string; violations: string[] };
|
|
||||||
if (errorResponse.name === "ValidationException") {
|
|
||||||
for (let v of errorResponse.violations) {
|
|
||||||
if (toast) toast.open({ message: v });
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (toast) toast.open({ message: "An error occurred" });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// i18n config (if needed elsewhere)
|
// i18n config (if needed elsewhere)
|
||||||
const i18n = {
|
const i18n = {
|
||||||
messages: {
|
messages: {
|
||||||
|
|||||||
@@ -14,9 +14,10 @@ import { computed, defineProps } from "vue";
|
|||||||
import BadgeEntity from "ChillMainAssets/vuejs/_components/BadgeEntity.vue";
|
import BadgeEntity from "ChillMainAssets/vuejs/_components/BadgeEntity.vue";
|
||||||
import UserRenderBoxBadge from "ChillMainAssets/vuejs/_components/Entity/UserRenderBoxBadge.vue";
|
import UserRenderBoxBadge from "ChillMainAssets/vuejs/_components/Entity/UserRenderBoxBadge.vue";
|
||||||
import { Suggestion } from "ChillPersonAssets/types";
|
import { Suggestion } from "ChillPersonAssets/types";
|
||||||
|
import {User} from "ChillMainAssets/types";
|
||||||
|
|
||||||
interface TypeUserProps {
|
interface TypeUserProps {
|
||||||
item: Suggestion;
|
item: Suggestion & {result: User};
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = defineProps<TypeUserProps>();
|
const props = defineProps<TypeUserProps>();
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ import UserGroupRenderBox from "ChillMainAssets/vuejs/_components/Entity/UserGro
|
|||||||
import { Suggestion } from "ChillPersonAssets/types";
|
import { Suggestion } from "ChillPersonAssets/types";
|
||||||
|
|
||||||
interface TypeUserGroupProps {
|
interface TypeUserGroupProps {
|
||||||
item: Suggestion;
|
item: Suggestion & {result: UserGroup};
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = defineProps<TypeUserGroupProps>();
|
const props = defineProps<TypeUserGroupProps>();
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-else-if="action === 'edit' || action === 'create'">
|
<div v-else-if="props.action === 'edit' || props.action === 'create'">
|
||||||
<PersonEdit
|
<PersonEdit
|
||||||
:id="props.id"
|
:id="props.id"
|
||||||
:type="props.type"
|
:type="props.type"
|
||||||
@@ -38,13 +38,13 @@ import PersonEdit from "./PersonEdit.vue";
|
|||||||
import type { Person } from "ChillPersonAssets/types";
|
import type { Person } from "ChillPersonAssets/types";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
id: string | number;
|
id: number;
|
||||||
type?: string;
|
type?: string;
|
||||||
action: "show" | "edit" | "create";
|
action: "show" | "edit" | "create";
|
||||||
query?: string;
|
query?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = defineProps<Props>();
|
const props = withDefaults(defineProps<Props>(), {query: ""});
|
||||||
|
|
||||||
const person = ref<Person | null>(null);
|
const person = ref<Person | null>(null);
|
||||||
|
|
||||||
@@ -52,7 +52,7 @@ function loadData(): void {
|
|||||||
if (props.id === undefined || props.id === null) {
|
if (props.id === undefined || props.id === null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const idNum = typeof props.id === "string" ? Number(props.id) : props.id;
|
const idNum = props.id;
|
||||||
if (!Number.isFinite(idNum)) {
|
if (!Number.isFinite(idNum)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,35 +6,96 @@ import {
|
|||||||
User,
|
User,
|
||||||
} from "ChillMainAssets/types";
|
} from "ChillMainAssets/types";
|
||||||
|
|
||||||
export interface Thirdparty {
|
export type ThirdPartyKind = "contact" | "child" | "company";
|
||||||
|
|
||||||
|
export interface BaseThirdParty {
|
||||||
type: "thirdparty";
|
type: "thirdparty";
|
||||||
|
kind: ""|ThirdPartyKind;
|
||||||
text: string;
|
text: string;
|
||||||
acronym: string | null;
|
acronym: string | null;
|
||||||
active: boolean;
|
active: boolean;
|
||||||
address: Address | null;
|
address: Address | null;
|
||||||
canonicalized: string | null;
|
|
||||||
categories: ThirdpartyCategory[];
|
|
||||||
centers: Center[];
|
|
||||||
children: Thirdparty[];
|
|
||||||
civility: Civility | null;
|
|
||||||
comment: string | null;
|
|
||||||
contactDataAnonymous: boolean;
|
|
||||||
createdAt: DateTime;
|
createdAt: DateTime;
|
||||||
createdBy: User | null;
|
createdBy: User | null;
|
||||||
email: string | null;
|
email: string | null;
|
||||||
firstname: string | null;
|
firstname: string | null;
|
||||||
id: number | null;
|
id: number;
|
||||||
kind: string;
|
|
||||||
name: string;
|
|
||||||
nameCompany: string | null;
|
nameCompany: string | null;
|
||||||
parent: Thirdparty | null;
|
|
||||||
profession: string;
|
|
||||||
telephone: string | null;
|
telephone: string | null;
|
||||||
thirdPartyTypes: ThirdpartyType[] | null;
|
|
||||||
updatedAt: DateTime | null;
|
updatedAt: DateTime | null;
|
||||||
updatedBy: User | null;
|
updatedBy: User | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ThirdpartyCompany extends BaseThirdParty {
|
||||||
|
kind: "company";
|
||||||
|
text: string;
|
||||||
|
acronym: string | null;
|
||||||
|
children: Thirdparty[];
|
||||||
|
categories: ThirdpartyCategory[];
|
||||||
|
thirdPartyTypes: ThirdpartyType[] | null;
|
||||||
|
address: Address | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Type guard to distinguish a ThirdpartyCompany
|
||||||
|
export function isThirdpartyCompany(
|
||||||
|
t: BaseThirdParty
|
||||||
|
): t is ThirdpartyCompany {
|
||||||
|
return (
|
||||||
|
t.type === "thirdparty" &&
|
||||||
|
t.kind === "company"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ThirdpartyChild extends BaseThirdParty {
|
||||||
|
kind: "child";
|
||||||
|
civility: Civility | null;
|
||||||
|
contactDataAnonymous: boolean;
|
||||||
|
parent: Thirdparty | null;
|
||||||
|
profession: string;
|
||||||
|
firstname: string;
|
||||||
|
/**
|
||||||
|
* the lastname for "Contact" and "Child", the name
|
||||||
|
*/
|
||||||
|
name: string;
|
||||||
|
comment: string | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Type guard to distinguish a ThirdpartyChild
|
||||||
|
export function isThirdpartyChild(
|
||||||
|
t: BaseThirdParty
|
||||||
|
): t is ThirdpartyChild {
|
||||||
|
return (
|
||||||
|
t.type === "thirdparty" &&
|
||||||
|
t.kind === "child"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ThirdpartyContact extends BaseThirdParty {
|
||||||
|
kind: "contact";
|
||||||
|
civility: Civility | null;
|
||||||
|
categories: ThirdpartyCategory[];
|
||||||
|
thirdPartyTypes: ThirdpartyType[] | null;
|
||||||
|
profession: string;
|
||||||
|
firstname: string;
|
||||||
|
/**
|
||||||
|
* the lastname for "Contact" and "Child", the name
|
||||||
|
*/
|
||||||
|
name: string;
|
||||||
|
address: Address | null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Type guard to distinguish a ThirdpartyContact
|
||||||
|
export function isThirdpartyContact(
|
||||||
|
t: BaseThirdParty
|
||||||
|
): t is ThirdpartyContact {
|
||||||
|
return (
|
||||||
|
t.type === "thirdparty" &&
|
||||||
|
t.kind === "contact"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export type Thirdparty = ThirdpartyCompany | ThirdpartyContact | ThirdpartyChild;
|
||||||
|
|
||||||
interface ThirdpartyType {
|
interface ThirdpartyType {
|
||||||
key: string;
|
key: string;
|
||||||
value: string;
|
value: string;
|
||||||
@@ -47,3 +108,22 @@ export interface ThirdpartyCategory {
|
|||||||
fr: string;
|
fr: string;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ThirdPartyWrite {
|
||||||
|
readonly type: "thirdparty";
|
||||||
|
kind: ThirdPartyKind;
|
||||||
|
civility: Civility | null;
|
||||||
|
profession: string;
|
||||||
|
firstname: string;
|
||||||
|
/**
|
||||||
|
* the lastname
|
||||||
|
*/
|
||||||
|
name: string;
|
||||||
|
email: string;
|
||||||
|
telephone: string;
|
||||||
|
telephone2: string;
|
||||||
|
address: null|{
|
||||||
|
address_id: number;
|
||||||
|
}
|
||||||
|
comment: string;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,52 +0,0 @@
|
|||||||
/*
|
|
||||||
* GET a thirdparty by id
|
|
||||||
*/
|
|
||||||
const getThirdparty = (id) => {
|
|
||||||
const url = `/api/1.0/thirdparty/thirdparty/${id}.json`;
|
|
||||||
return fetch(url).then((response) => {
|
|
||||||
if (response.ok) {
|
|
||||||
return response.json();
|
|
||||||
}
|
|
||||||
throw Error("Error with request resource response");
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* POST a new thirdparty
|
|
||||||
*/
|
|
||||||
const postThirdparty = (body) => {
|
|
||||||
const url = `/api/1.0/thirdparty/thirdparty.json`;
|
|
||||||
return fetch(url, {
|
|
||||||
method: "POST",
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json;charset=utf-8",
|
|
||||||
},
|
|
||||||
body: JSON.stringify(body),
|
|
||||||
}).then((response) => {
|
|
||||||
if (response.ok) {
|
|
||||||
return response.json();
|
|
||||||
}
|
|
||||||
throw Error("Error with request resource response");
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* PATCH an existing thirdparty
|
|
||||||
*/
|
|
||||||
const patchThirdparty = (id, body) => {
|
|
||||||
const url = `/api/1.0/thirdparty/thirdparty/${id}.json`;
|
|
||||||
return fetch(url, {
|
|
||||||
method: "PATCH",
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json;charset=utf-8",
|
|
||||||
},
|
|
||||||
body: JSON.stringify(body),
|
|
||||||
}).then((response) => {
|
|
||||||
if (response.ok) {
|
|
||||||
return response.json();
|
|
||||||
}
|
|
||||||
throw Error("Error with request resource response");
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
export { getThirdparty, postThirdparty, patchThirdparty };
|
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
* GET a thirdparty by id
|
||||||
|
*/
|
||||||
|
import {Thirdparty, ThirdPartyWrite} from '../../types';
|
||||||
|
import {makeFetch} from "ChillMainAssets/lib/api/apiMethods";
|
||||||
|
|
||||||
|
export const getThirdparty = async (id: number) : Promise<Thirdparty> => {
|
||||||
|
const url = `/api/1.0/thirdparty/thirdparty/${id}.json`;
|
||||||
|
return fetch(url).then((response) => {
|
||||||
|
if (response.ok) {
|
||||||
|
return response.json();
|
||||||
|
}
|
||||||
|
throw Error("Error with request resource response");
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* POST a new thirdparty
|
||||||
|
*/
|
||||||
|
export const createThirdParty = async (body: ThirdPartyWrite) => {
|
||||||
|
const url = `/api/1.0/thirdparty/thirdparty.json`;
|
||||||
|
|
||||||
|
return makeFetch<ThirdPartyWrite, Thirdparty>('POST', url, body);
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* PATCH an existing thirdparty
|
||||||
|
*/
|
||||||
|
export const patchThirdparty = async (id: number, body: ThirdPartyWrite) => {
|
||||||
|
const url = `/api/1.0/thirdparty/thirdparty/${id}.json`;
|
||||||
|
return makeFetch('PATCH', url, body);
|
||||||
|
};
|
||||||
@@ -24,401 +24,35 @@
|
|||||||
action === 'edit' || action === 'create' || action === 'addContact'
|
action === 'edit' || action === 'create' || action === 'addContact'
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
<div v-if="parent">
|
<ThirdPartyEdit :id="id" :type="type" :action="action" :query="query" :parent="parent" />
|
||||||
<div class="parent-info">
|
|
||||||
<i class="fa fa-li fa-hand-o-right" />
|
|
||||||
<b class="me-2">{{ trans(THIRDPARTY_MESSAGES_CHILD_OF) }}</b>
|
|
||||||
<span class="chill-entity badge-thirdparty">{{ parent.text }}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-floating mb-3" v-else-if="kind.value !== 'child'">
|
|
||||||
<div class="form-check">
|
|
||||||
<input
|
|
||||||
class="form-check-input mt-0"
|
|
||||||
type="radio"
|
|
||||||
v-model="kind.value"
|
|
||||||
value="company"
|
|
||||||
id="tpartyKindInstitution"
|
|
||||||
/>
|
|
||||||
<label for="tpartyKindInstitution" class="required">
|
|
||||||
<badge-entity
|
|
||||||
:entity="{ type: 'thirdparty', kind: 'company' }"
|
|
||||||
:options="{ displayLong: true }"
|
|
||||||
/>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="form-check">
|
|
||||||
<input
|
|
||||||
class="form-check-input mt-0"
|
|
||||||
type="radio"
|
|
||||||
v-model="kind.value"
|
|
||||||
value="contact"
|
|
||||||
id="tpartyKindContact"
|
|
||||||
/>
|
|
||||||
<label for="tpartyKindContact" class="required">
|
|
||||||
<badge-entity
|
|
||||||
:entity="{ type: 'thirdparty', kind: 'contact' }"
|
|
||||||
:options="{ displayLong: true }"
|
|
||||||
/>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div v-else>
|
|
||||||
<p>Contact de :</p>
|
|
||||||
<third-party-render-box
|
|
||||||
:thirdparty="thirdparty.parent"
|
|
||||||
:options="{
|
|
||||||
addInfo: true,
|
|
||||||
addEntity: false,
|
|
||||||
addAltNames: true,
|
|
||||||
addId: false,
|
|
||||||
addLink: false,
|
|
||||||
addAge: false,
|
|
||||||
hLevel: 4,
|
|
||||||
addCenter: false,
|
|
||||||
addNoData: true,
|
|
||||||
isMultiline: false,
|
|
||||||
}"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div v-if="thirdparty.kind === 'child' || thirdparty.kind === 'contact'">
|
|
||||||
<div class="child-info">
|
|
||||||
<div class="input-group mb-3 input-section">
|
|
||||||
<select
|
|
||||||
class="form-select form-select-lg"
|
|
||||||
id="civility"
|
|
||||||
v-model="thirdparty.civility"
|
|
||||||
>
|
|
||||||
<option selected disabled :value="null">
|
|
||||||
{{ trans(THIRDPARTY_MESSAGES_THIRDPARTY_CIVILITY) }}
|
|
||||||
</option>
|
|
||||||
<option
|
|
||||||
v-for="civility in civilities"
|
|
||||||
:key="civility.id"
|
|
||||||
:value="civility"
|
|
||||||
>
|
|
||||||
{{ localizeString(civility.name) }}
|
|
||||||
</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<div class="input-group mb-3 input-section">
|
|
||||||
<input
|
|
||||||
class="form-control form-control-lg"
|
|
||||||
v-model="thirdparty.profession"
|
|
||||||
:placeholder="trans(THIRDPARTY_MESSAGES_THIRDPARTY_PROFESSION)"
|
|
||||||
:aria-label="trans(THIRDPARTY_MESSAGES_THIRDPARTY_PROFESSION)"
|
|
||||||
aria-describedby="profession"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="child-info">
|
|
||||||
<div class="input-section">
|
|
||||||
<div class="form-floating mb-3">
|
|
||||||
<input
|
|
||||||
class="form-control form-control-lg"
|
|
||||||
id="firstname"
|
|
||||||
v-model="thirdparty.firstname"
|
|
||||||
:placeholder="trans(THIRDPARTY_MESSAGES_THIRDPARTY_FIRSTNAME)"
|
|
||||||
/>
|
|
||||||
<label for="firstname">{{
|
|
||||||
trans(THIRDPARTY_MESSAGES_THIRDPARTY_FIRSTNAME)
|
|
||||||
}}</label>
|
|
||||||
</div>
|
|
||||||
<div v-if="queryItems">
|
|
||||||
<ul class="list-suggest add-items inline">
|
|
||||||
<li
|
|
||||||
v-for="(qi, i) in queryItems"
|
|
||||||
:key="i"
|
|
||||||
@click="addQueryItem('firstName', qi)"
|
|
||||||
>
|
|
||||||
<span class="person-text">{{ qi }}</span>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="input-section">
|
|
||||||
<div class="form-floating mb-3">
|
|
||||||
<input
|
|
||||||
class="form-control form-control-lg"
|
|
||||||
id="name"
|
|
||||||
v-model="thirdparty.name"
|
|
||||||
:placeholder="trans(THIRDPARTY_MESSAGES_THIRDPARTY_LASTNAME)"
|
|
||||||
/>
|
|
||||||
<label for="name">{{
|
|
||||||
trans(THIRDPARTY_MESSAGES_THIRDPARTY_LASTNAME)
|
|
||||||
}}</label>
|
|
||||||
</div>
|
|
||||||
<div v-if="queryItems">
|
|
||||||
<ul class="list-suggest add-items inline">
|
|
||||||
<li
|
|
||||||
v-for="(qi, i) in queryItems"
|
|
||||||
:key="i"
|
|
||||||
@click="addQueryItem('name', qi)"
|
|
||||||
>
|
|
||||||
<span class="person-text">{{ qi }}</span>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div v-if="thirdparty.kind === 'company'">
|
|
||||||
<div class="form-floating mb-3">
|
|
||||||
<input
|
|
||||||
class="form-control form-control-lg"
|
|
||||||
id="name"
|
|
||||||
v-model="thirdparty.name"
|
|
||||||
:placeholder="trans(THIRDPARTY_MESSAGES_THIRDPARTY_NAME)"
|
|
||||||
/>
|
|
||||||
<label for="name">{{
|
|
||||||
trans(THIRDPARTY_MESSAGES_THIRDPARTY_NAME)
|
|
||||||
}}</label>
|
|
||||||
</div>
|
|
||||||
<div v-if="query">
|
|
||||||
<ul class="list-suggest add-items inline">
|
|
||||||
<li @click="addQuery(query)">
|
|
||||||
<span class="person-text">{{ query }}</span>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<template v-if="thirdparty.kind !== 'child'">
|
|
||||||
<AddAddress
|
|
||||||
key="thirdparty"
|
|
||||||
:context="context"
|
|
||||||
:options="addAddress.options"
|
|
||||||
:address-changed-callback="submitAddress"
|
|
||||||
ref="addAddress"
|
|
||||||
/>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<div class="input-group mb-3">
|
|
||||||
<span class="input-group-text" id="email"
|
|
||||||
><i class="fa fa-fw fa-envelope"
|
|
||||||
/></span>
|
|
||||||
<input
|
|
||||||
class="form-control form-control-lg"
|
|
||||||
v-model="thirdparty.email"
|
|
||||||
:placeholder="trans(THIRDPARTY_MESSAGES_THIRDPARTY_EMAIL)"
|
|
||||||
:aria-label="trans(THIRDPARTY_MESSAGES_THIRDPARTY_EMAIL)"
|
|
||||||
aria-describedby="email"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="input-group mb-3">
|
|
||||||
<span class="input-group-text" id="phonenumber"
|
|
||||||
><i class="fa fa-fw fa-phone"
|
|
||||||
/></span>
|
|
||||||
<input
|
|
||||||
class="form-control form-control-lg"
|
|
||||||
v-model="thirdparty.telephone"
|
|
||||||
:placeholder="trans(THIRDPARTY_MESSAGES_THIRDPARTY_PHONENUMBER)"
|
|
||||||
:aria-label="trans(THIRDPARTY_MESSAGES_THIRDPARTY_PHONENUMBER)"
|
|
||||||
aria-describedby="phonenumber"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="input-group mb-3">
|
|
||||||
<span class="input-group-text" id="phonenumber2"
|
|
||||||
><i class="fa fa-fw fa-phone"
|
|
||||||
/></span>
|
|
||||||
<input
|
|
||||||
class="form-control form-control-lg"
|
|
||||||
v-model="thirdparty.telephone2"
|
|
||||||
:placeholder="trans(THIRDPARTY_MESSAGES_THIRDPARTY_PHONENUMBER2)"
|
|
||||||
:aria-label="trans(THIRDPARTY_MESSAGES_THIRDPARTY_PHONENUMBER2)"
|
|
||||||
aria-describedby="phonenumber2"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div v-if="parent">
|
|
||||||
<div class="input-group mb-3">
|
|
||||||
<span class="input-group-text" id="comment"
|
|
||||||
><i class="fa fa-fw fa-pencil"
|
|
||||||
/></span>
|
|
||||||
<textarea
|
|
||||||
class="form-control form-control-lg"
|
|
||||||
:placeholder="trans(THIRDPARTY_MESSAGES_THIRDPARTY_COMMENT)"
|
|
||||||
v-model="thirdparty.comment"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, reactive, computed, onMounted, getCurrentInstance } from "vue";
|
import { reactive, onMounted } from 'vue'
|
||||||
import ThirdPartyRenderBox from "../Entity/ThirdPartyRenderBox.vue";
|
import ThirdPartyRenderBox from '../Entity/ThirdPartyRenderBox.vue'
|
||||||
import AddAddress from "ChillMainAssets/vuejs/Address/components/AddAddress";
|
import ThirdPartyEdit from './ThirdPartyEdit.vue'
|
||||||
import { getThirdparty } from "../../_api/OnTheFly";
|
import { getThirdparty } from '../../_api/OnTheFly'
|
||||||
import BadgeEntity from "ChillMainAssets/vuejs/_components/BadgeEntity.vue";
|
|
||||||
import { makeFetch } from "ChillMainAssets/lib/api/apiMethods";
|
|
||||||
import { localizeString as _localizeString } from "ChillMainAssets/lib/localizationHelper/localizationHelper";
|
|
||||||
import {
|
|
||||||
trans,
|
|
||||||
THIRDPARTY_MESSAGES_THIRDPARTY_FIRSTNAME,
|
|
||||||
THIRDPARTY_MESSAGES_THIRDPARTY_LASTNAME,
|
|
||||||
THIRDPARTY_MESSAGES_THIRDPARTY_NAME,
|
|
||||||
THIRDPARTY_MESSAGES_THIRDPARTY_EMAIL,
|
|
||||||
THIRDPARTY_MESSAGES_THIRDPARTY_PHONENUMBER,
|
|
||||||
THIRDPARTY_MESSAGES_THIRDPARTY_PHONENUMBER2,
|
|
||||||
THIRDPARTY_MESSAGES_THIRDPARTY_COMMENT,
|
|
||||||
THIRDPARTY_MESSAGES_THIRDPARTY_PROFESSION,
|
|
||||||
THIRDPARTY_MESSAGES_THIRDPARTY_CIVILITY,
|
|
||||||
THIRDPARTY_MESSAGES_CHILD_OF,
|
|
||||||
} from "translator";
|
|
||||||
// Props
|
|
||||||
const props = defineProps(["id", "type", "action", "query", "parent"]);
|
|
||||||
|
|
||||||
// Instance for $t and $toast
|
const props = defineProps(['id', 'type', 'action', 'query', 'parent'])
|
||||||
const { proxy } = getCurrentInstance();
|
|
||||||
|
|
||||||
// State
|
|
||||||
const thirdparty = reactive({
|
const thirdparty = reactive({
|
||||||
type: "thirdparty",
|
type: 'thirdparty',
|
||||||
address: null,
|
})
|
||||||
kind: "company",
|
|
||||||
firstname: "",
|
|
||||||
name: "",
|
|
||||||
telephone: "",
|
|
||||||
telephone2: "",
|
|
||||||
civility: null,
|
|
||||||
profession: "",
|
|
||||||
comment: "",
|
|
||||||
parent: props.parent ? props.parent : undefined,
|
|
||||||
});
|
|
||||||
const civilities = ref([]);
|
|
||||||
const addAddress = reactive({
|
|
||||||
options: {
|
|
||||||
openPanesInModal: true,
|
|
||||||
onlyButton: false,
|
|
||||||
button: {
|
|
||||||
size: "btn-sm",
|
|
||||||
},
|
|
||||||
title: {
|
|
||||||
create: "add_an_address_title",
|
|
||||||
edit: "edit_address",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
const addAddressRef = ref(null);
|
|
||||||
|
|
||||||
// Kind as computed ref
|
|
||||||
const kind = computed({
|
|
||||||
get() {
|
|
||||||
return thirdparty.kind !== undefined ? thirdparty.kind : "company";
|
|
||||||
},
|
|
||||||
set(v) {
|
|
||||||
thirdparty.kind = v;
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// Context as computed
|
|
||||||
const context = computed(() => {
|
|
||||||
let ctx = {
|
|
||||||
target: {
|
|
||||||
name: props.type,
|
|
||||||
id: props.id,
|
|
||||||
},
|
|
||||||
edit: false,
|
|
||||||
addressId: null,
|
|
||||||
defaults: window.addaddress,
|
|
||||||
};
|
|
||||||
if (
|
|
||||||
!(thirdparty.address === undefined || thirdparty.address === null) &&
|
|
||||||
thirdparty.address.address_id !== null
|
|
||||||
) {
|
|
||||||
ctx.addressId = thirdparty.address.address_id;
|
|
||||||
ctx.edit = true;
|
|
||||||
}
|
|
||||||
return ctx;
|
|
||||||
});
|
|
||||||
|
|
||||||
// Query items
|
|
||||||
const queryItems = computed(() =>
|
|
||||||
props.query ? props.query.split(" ") : null,
|
|
||||||
);
|
|
||||||
|
|
||||||
// Methods
|
|
||||||
function localizeString(str) {
|
|
||||||
return _localizeString(str);
|
|
||||||
}
|
|
||||||
|
|
||||||
function loadData() {
|
function loadData() {
|
||||||
return getThirdparty(props.id).then(
|
if (!props.id) return Promise.resolve()
|
||||||
(tp) =>
|
return getThirdparty(props.id).then((tp) => {
|
||||||
new Promise((resolve) => {
|
Object.assign(thirdparty, tp)
|
||||||
Object.assign(thirdparty, tp);
|
})
|
||||||
thirdparty.kind = tp.kind;
|
|
||||||
if (props.action !== "show") {
|
|
||||||
if (tp.address !== null && addAddressRef.value) {
|
|
||||||
addAddressRef.value.getInitialAddress(tp.address.address_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
resolve();
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function loadCivilities() {
|
|
||||||
const url = `/api/1.0/main/civility.json`;
|
|
||||||
return makeFetch("GET", url)
|
|
||||||
.then((response) => {
|
|
||||||
civilities.value = response.results;
|
|
||||||
return Promise.resolve();
|
|
||||||
})
|
|
||||||
.catch((error) => {
|
|
||||||
console.log(error);
|
|
||||||
proxy.$toast.open({ message: error.body });
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function submitAddress(payload) {
|
|
||||||
if (typeof payload.addressId !== "undefined") {
|
|
||||||
context.value.edit = true;
|
|
||||||
context.value.addressId = payload.addressId;
|
|
||||||
thirdparty.address = payload.address;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function addQueryItem(field, queryItem) {
|
|
||||||
switch (field) {
|
|
||||||
case "name":
|
|
||||||
if (thirdparty.name) {
|
|
||||||
thirdparty.name += ` ${queryItem}`;
|
|
||||||
} else {
|
|
||||||
thirdparty.name = queryItem;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case "firstName":
|
|
||||||
thirdparty.firstname = queryItem;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function addQuery(query) {
|
|
||||||
thirdparty.name = query;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Lifecycle
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
let dependencies = [];
|
if (props.action === 'show' && props.id) {
|
||||||
dependencies.push(loadCivilities());
|
loadData()
|
||||||
if (props.action !== "create") {
|
|
||||||
if (props.id) {
|
|
||||||
dependencies.push(loadData());
|
|
||||||
}
|
|
||||||
if (props.action === "addContact") {
|
|
||||||
thirdparty.kind = "child";
|
|
||||||
thirdparty.address = null;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
thirdparty.kind = "company";
|
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|||||||
@@ -0,0 +1,415 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<div v-if="parent">
|
||||||
|
<div class="parent-info">
|
||||||
|
<i class="fa fa-li fa-hand-o-right" />
|
||||||
|
<b class="me-2">{{ trans(THIRDPARTY_MESSAGES_CHILD_OF) }}</b>
|
||||||
|
<span class="chill-entity badge-thirdparty">{{ parent.text }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-floating mb-3" v-else-if="kind !== 'child'">
|
||||||
|
<div class="form-check">
|
||||||
|
<input
|
||||||
|
class="form-check-input mt-0"
|
||||||
|
type="radio"
|
||||||
|
v-model="kind"
|
||||||
|
value="company"
|
||||||
|
id="tpartyKindInstitution"
|
||||||
|
/>
|
||||||
|
<label for="tpartyKindInstitution" class="required">
|
||||||
|
<badge-entity
|
||||||
|
:entity="{ type: 'thirdparty', kind: 'company' }"
|
||||||
|
:options="{ displayLong: true }"
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="form-check">
|
||||||
|
<input
|
||||||
|
class="form-check-input mt-0"
|
||||||
|
type="radio"
|
||||||
|
v-model="kind"
|
||||||
|
value="contact"
|
||||||
|
id="tpartyKindContact"
|
||||||
|
/>
|
||||||
|
<label for="tpartyKindContact" class="required">
|
||||||
|
<badge-entity
|
||||||
|
:entity="{ type: 'thirdparty', kind: 'contact' }"
|
||||||
|
:options="{ displayLong: true }"
|
||||||
|
/>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-else>
|
||||||
|
<p>Contact de :</p>
|
||||||
|
<third-party-render-box
|
||||||
|
:thirdparty="props.parent"
|
||||||
|
:options="{
|
||||||
|
addInfo: true,
|
||||||
|
addEntity: false,
|
||||||
|
addAltNames: true,
|
||||||
|
addId: false,
|
||||||
|
addLink: false,
|
||||||
|
addAge: false,
|
||||||
|
hLevel: 4,
|
||||||
|
addCenter: false,
|
||||||
|
addNoData: true,
|
||||||
|
isMultiline: false,
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-if="thirdParty.kind === 'child' || thirdParty.kind === 'contact'">
|
||||||
|
<div class="child-info">
|
||||||
|
<div class="input-group mb-3 input-section">
|
||||||
|
<select
|
||||||
|
class="form-select form-select-lg"
|
||||||
|
id="civility"
|
||||||
|
v-model="thirdParty.civility"
|
||||||
|
>
|
||||||
|
<option selected disabled :value="null">
|
||||||
|
{{ trans(THIRDPARTY_MESSAGES_THIRDPARTY_CIVILITY) }}
|
||||||
|
</option>
|
||||||
|
<option
|
||||||
|
v-for="civility in civilities"
|
||||||
|
:key="civility.id"
|
||||||
|
:value="civility"
|
||||||
|
>
|
||||||
|
{{ localizeString(civility.name) }}
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="input-group mb-3 input-section">
|
||||||
|
<input
|
||||||
|
class="form-control form-control-lg"
|
||||||
|
v-model="thirdParty.profession"
|
||||||
|
:placeholder="trans(THIRDPARTY_MESSAGES_THIRDPARTY_PROFESSION)"
|
||||||
|
:aria-label="trans(THIRDPARTY_MESSAGES_THIRDPARTY_PROFESSION)"
|
||||||
|
aria-describedby="profession"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="child-info">
|
||||||
|
<div class="input-section">
|
||||||
|
<div class="form-floating mb-3">
|
||||||
|
<input
|
||||||
|
class="form-control form-control-lg"
|
||||||
|
id="firstname"
|
||||||
|
v-model="thirdParty.firstname"
|
||||||
|
:placeholder="trans(THIRDPARTY_MESSAGES_THIRDPARTY_FIRSTNAME)"
|
||||||
|
/>
|
||||||
|
<label for="firstname">{{
|
||||||
|
trans(THIRDPARTY_MESSAGES_THIRDPARTY_FIRSTNAME)
|
||||||
|
}}</label>
|
||||||
|
</div>
|
||||||
|
<div v-if="queryItems">
|
||||||
|
<ul class="list-suggest add-items inline">
|
||||||
|
<li
|
||||||
|
v-for="(qi, i) in queryItems"
|
||||||
|
:key="i"
|
||||||
|
@click="addQueryItem('firstName', qi)"
|
||||||
|
>
|
||||||
|
<span class="person-text">{{ qi }}</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="input-section">
|
||||||
|
<div class="form-floating mb-3">
|
||||||
|
<input
|
||||||
|
class="form-control form-control-lg"
|
||||||
|
id="name"
|
||||||
|
v-model="thirdParty.name"
|
||||||
|
:placeholder="trans(THIRDPARTY_MESSAGES_THIRDPARTY_LASTNAME)"
|
||||||
|
/>
|
||||||
|
<label for="name">{{
|
||||||
|
trans(THIRDPARTY_MESSAGES_THIRDPARTY_LASTNAME)
|
||||||
|
}}</label>
|
||||||
|
</div>
|
||||||
|
<div v-if="queryItems">
|
||||||
|
<ul class="list-suggest add-items inline">
|
||||||
|
<li
|
||||||
|
v-for="(qi, i) in queryItems"
|
||||||
|
:key="i"
|
||||||
|
@click="addQueryItem('name', qi)"
|
||||||
|
>
|
||||||
|
<span class="person-text">{{ qi }}</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-if="thirdParty.kind === 'company'">
|
||||||
|
<div class="form-floating mb-3">
|
||||||
|
<input
|
||||||
|
class="form-control form-control-lg"
|
||||||
|
id="name"
|
||||||
|
v-model="thirdParty.name"
|
||||||
|
:placeholder="trans(THIRDPARTY_MESSAGES_THIRDPARTY_NAME)"
|
||||||
|
/>
|
||||||
|
<label for="name">{{
|
||||||
|
trans(THIRDPARTY_MESSAGES_THIRDPARTY_NAME)
|
||||||
|
}}</label>
|
||||||
|
</div>
|
||||||
|
<div v-if="query">
|
||||||
|
<ul class="list-suggest add-items inline">
|
||||||
|
<li @click="addQuery(query)">
|
||||||
|
<span class="person-text">{{ query }}</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<template v-if="thirdParty.kind !== 'child'">
|
||||||
|
<AddAddress
|
||||||
|
key="thirdparty"
|
||||||
|
:context="context"
|
||||||
|
:options="addAddress.options"
|
||||||
|
:address-changed-callback="submitAddress"
|
||||||
|
ref="addAddressRef"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<div class="input-group mb-3">
|
||||||
|
<span class="input-group-text" id="email"
|
||||||
|
><i class="fa fa-fw fa-envelope"
|
||||||
|
/></span>
|
||||||
|
<input
|
||||||
|
class="form-control form-control-lg"
|
||||||
|
v-model="thirdParty.email"
|
||||||
|
:placeholder="trans(THIRDPARTY_MESSAGES_THIRDPARTY_EMAIL)"
|
||||||
|
:aria-label="trans(THIRDPARTY_MESSAGES_THIRDPARTY_EMAIL)"
|
||||||
|
aria-describedby="email"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="input-group mb-3">
|
||||||
|
<span class="input-group-text" id="phonenumber"
|
||||||
|
><i class="fa fa-fw fa-phone"
|
||||||
|
/></span>
|
||||||
|
<input
|
||||||
|
class="form-control form-control-lg"
|
||||||
|
v-model="thirdParty.telephone"
|
||||||
|
:placeholder="trans(THIRDPARTY_MESSAGES_THIRDPARTY_PHONENUMBER)"
|
||||||
|
:aria-label="trans(THIRDPARTY_MESSAGES_THIRDPARTY_PHONENUMBER)"
|
||||||
|
aria-describedby="phonenumber"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="input-group mb-3">
|
||||||
|
<span class="input-group-text" id="phonenumber2"
|
||||||
|
><i class="fa fa-fw fa-phone"
|
||||||
|
/></span>
|
||||||
|
<input
|
||||||
|
class="form-control form-control-lg"
|
||||||
|
v-model="thirdParty.telephone2"
|
||||||
|
:placeholder="trans(THIRDPARTY_MESSAGES_THIRDPARTY_PHONENUMBER2)"
|
||||||
|
:aria-label="trans(THIRDPARTY_MESSAGES_THIRDPARTY_PHONENUMBER2)"
|
||||||
|
aria-describedby="phonenumber2"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div v-if="parent">
|
||||||
|
<div class="input-group mb-3">
|
||||||
|
<span class="input-group-text" id="comment"
|
||||||
|
><i class="fa fa-fw fa-pencil"
|
||||||
|
/></span>
|
||||||
|
<textarea
|
||||||
|
class="form-control form-control-lg"
|
||||||
|
:placeholder="trans(THIRDPARTY_MESSAGES_THIRDPARTY_COMMENT)"
|
||||||
|
v-model="thirdParty.comment"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, reactive, computed, onMounted, getCurrentInstance } from 'vue'
|
||||||
|
import ThirdPartyRenderBox from '../Entity/ThirdPartyRenderBox.vue'
|
||||||
|
import AddAddress from "ChillMainAssets/vuejs/Address/components/AddAddress.vue";
|
||||||
|
import {createThirdParty, getThirdparty} from '../../_api/OnTheFly'
|
||||||
|
import BadgeEntity from 'ChillMainAssets/vuejs/_components/BadgeEntity.vue'
|
||||||
|
import { localizeString as _localizeString } from 'ChillMainAssets/lib/localizationHelper/localizationHelper'
|
||||||
|
import {
|
||||||
|
trans,
|
||||||
|
THIRDPARTY_MESSAGES_THIRDPARTY_FIRSTNAME,
|
||||||
|
THIRDPARTY_MESSAGES_THIRDPARTY_LASTNAME,
|
||||||
|
THIRDPARTY_MESSAGES_THIRDPARTY_NAME,
|
||||||
|
THIRDPARTY_MESSAGES_THIRDPARTY_EMAIL,
|
||||||
|
THIRDPARTY_MESSAGES_THIRDPARTY_PHONENUMBER,
|
||||||
|
THIRDPARTY_MESSAGES_THIRDPARTY_PHONENUMBER2,
|
||||||
|
THIRDPARTY_MESSAGES_THIRDPARTY_COMMENT,
|
||||||
|
THIRDPARTY_MESSAGES_THIRDPARTY_PROFESSION,
|
||||||
|
THIRDPARTY_MESSAGES_THIRDPARTY_CIVILITY,
|
||||||
|
THIRDPARTY_MESSAGES_CHILD_OF, PERSON_EDIT_ERROR_WHILE_SAVING,
|
||||||
|
} from 'translator'
|
||||||
|
import {
|
||||||
|
createPerson,
|
||||||
|
getCivilities, WritePersonViolationMap,
|
||||||
|
} from "ChillPersonAssets/vuejs/_api/OnTheFly";
|
||||||
|
import {Thirdparty, ThirdPartyKind, ThirdPartyWrite} from "../../../types";
|
||||||
|
import {Civility} from "ChillMainAssets/types";
|
||||||
|
import {isValidationException} from "ChillMainAssets/lib/api/apiMethods";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
interface ThirdPartyEditProps {
|
||||||
|
id?: number;
|
||||||
|
type?: string|null;
|
||||||
|
action: 'edit' | 'create' | 'addContact';
|
||||||
|
query?: string|null;
|
||||||
|
parent?: Thirdparty|null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const props = withDefaults(defineProps<ThirdPartyEditProps>(), {type: null, query: null, parent: null});
|
||||||
|
|
||||||
|
const emit =
|
||||||
|
defineEmits<(e: "onThirdPartyCreated", payload: { thirdParty: Thirdparty }) => void>();
|
||||||
|
|
||||||
|
defineExpose({ postThirdParty });
|
||||||
|
|
||||||
|
const thirdParty = ref<ThirdPartyWrite>({
|
||||||
|
type: "thirdparty",
|
||||||
|
kind: 'company',
|
||||||
|
address: null,
|
||||||
|
civility: null,
|
||||||
|
email: "",
|
||||||
|
firstname: "",
|
||||||
|
name: "",
|
||||||
|
profession: "",
|
||||||
|
telephone: "",
|
||||||
|
telephone2: "",
|
||||||
|
comment: "",
|
||||||
|
});
|
||||||
|
|
||||||
|
const civilities = ref<Civility[]>([])
|
||||||
|
|
||||||
|
const addAddress = reactive({
|
||||||
|
options: {
|
||||||
|
openPanesInModal: true,
|
||||||
|
onlyButton: false,
|
||||||
|
button: { size: 'btn-sm' },
|
||||||
|
title: { create: 'add_an_address_title', edit: 'edit_address' },
|
||||||
|
},
|
||||||
|
})
|
||||||
|
const addAddressRef = ref<any>(null)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* We need a specific computed for the kind
|
||||||
|
*/
|
||||||
|
const kind = computed<ThirdPartyKind>({
|
||||||
|
get() {
|
||||||
|
return thirdParty.value.kind;
|
||||||
|
},
|
||||||
|
set(v) {
|
||||||
|
thirdParty.value.kind = v
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const context = computed(() => {
|
||||||
|
const ctx: any = {
|
||||||
|
target: { name: props.type, id: props.id },
|
||||||
|
edit: false,
|
||||||
|
addressId: null as number | null,
|
||||||
|
defaults: (window as any).addaddress,
|
||||||
|
}
|
||||||
|
if (thirdParty.value.address) {
|
||||||
|
ctx.addressId = thirdParty.value.address.address_id
|
||||||
|
ctx.edit = true
|
||||||
|
}
|
||||||
|
return ctx
|
||||||
|
})
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find the query items to display for suggestion
|
||||||
|
*/
|
||||||
|
const queryItems = computed(() => {
|
||||||
|
const words: null | string[] = props.query ? props.query.split(" ") : null;
|
||||||
|
|
||||||
|
if (null === words) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const firstNameWords = (thirdParty.value.firstname || "")
|
||||||
|
.trim()
|
||||||
|
.toLowerCase()
|
||||||
|
.split(" ");
|
||||||
|
const lastNameWords = (thirdParty.value.name || "").trim().toLowerCase().split(" ");
|
||||||
|
|
||||||
|
return words
|
||||||
|
.filter((word) => !firstNameWords.includes(word.toLowerCase()))
|
||||||
|
.filter((word) => !lastNameWords.includes(word.toLowerCase()));
|
||||||
|
});
|
||||||
|
|
||||||
|
function localizeString(str: any) {
|
||||||
|
return _localizeString(str)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
getCivilities().then((cv) => {
|
||||||
|
civilities.value = cv;
|
||||||
|
});
|
||||||
|
if (props.action !== "create") {
|
||||||
|
loadData();
|
||||||
|
}
|
||||||
|
if (props.action === 'addContact') {
|
||||||
|
thirdParty.value.kind = 'child'
|
||||||
|
thirdParty.value.address = null
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
async function loadData(): Promise<void> {
|
||||||
|
if (!props.id) return Promise.resolve()
|
||||||
|
}
|
||||||
|
|
||||||
|
function submitAddress(payload: { address_id: number }) {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
function addQueryItem(field: 'name' | 'firstName', queryItem: string) {
|
||||||
|
switch (field) {
|
||||||
|
case 'name':
|
||||||
|
if (thirdParty.value.name) {
|
||||||
|
thirdParty.value.name += ` ${queryItem}`
|
||||||
|
} else {
|
||||||
|
thirdParty.value.name = queryItem
|
||||||
|
}
|
||||||
|
break
|
||||||
|
case 'firstName':
|
||||||
|
thirdParty.value.firstname = queryItem
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function addQuery(query: string) {
|
||||||
|
thirdParty.value.name = query
|
||||||
|
}
|
||||||
|
|
||||||
|
async function postThirdParty(): Promise<void> {
|
||||||
|
try {
|
||||||
|
const tp = await createThirdParty(thirdParty.value);
|
||||||
|
|
||||||
|
emit('onThirdPartyCreated', { thirdParty: tp });
|
||||||
|
} catch (e: unknown) {
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.parent-info {
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.child-info {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
.input-section {
|
||||||
|
width: 49%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -68,6 +68,10 @@ Remove a contact: Supprimer
|
|||||||
Contacts: Contacts
|
Contacts: Contacts
|
||||||
No contacts associated: Aucun contact
|
No contacts associated: Aucun contact
|
||||||
|
|
||||||
|
thirdparty:
|
||||||
|
addcontact: Ajouter un contact
|
||||||
|
addcontact_title: Ajouter un contact
|
||||||
|
|
||||||
No nameCompany given: Aucune raison sociale renseignée
|
No nameCompany given: Aucune raison sociale renseignée
|
||||||
No acronym given: Aucun sigle renseigné
|
No acronym given: Aucun sigle renseigné
|
||||||
No phone given: Aucun téléphone renseigné
|
No phone given: Aucun téléphone renseigné
|
||||||
|
|||||||
Reference in New Issue
Block a user