Refactor third-party type imports and update related components

- Changed import path for ThirdParty type in TypeThirdParty.vue and updated its usage.
- Refactored PersonText.vue to import Person and AltName types from ChillPersonAssets.
- Updated types.ts in ChillThirdPartyBundle to include a new 'type' field in the Thirdparty interface.
- Modified TicketBundle types to accommodate Thirdparty type in CallerState.
- Adjusted AddresseeSelectorComponent.vue to use 'thirdparty' instead of 'third_party'.
- Refined BannerComponent.vue to improve readability and maintainability.
- Updated CallerSelectorComponent.vue to reflect changes in entity types.
- Enhanced TicketHistoryListComponent.vue to handle both Person and Thirdparty types.
- Refactored TicketHistoryPersonComponent.vue to accept both Person and Thirdparty entities.
This commit is contained in:
borisw
2025-07-07 16:35:31 +02:00
parent dbf363a9e8
commit 6eeb717b1a
14 changed files with 1333 additions and 1397 deletions

View File

@@ -1,287 +1,269 @@
import { GenericDoc } from "ChillDocStoreAssets/types/generic_doc";
export interface DateTime {
datetime: string;
datetime8601: string;
datetime: string;
datetime8601: string;
}
export interface Civility {
id: number;
// TODO
id: number;
// TODO
}
export interface Household {
type: "household";
id: number;
type: "household";
id: number;
}
export interface Job {
id: number;
type: "user_job";
label: {
fr: string; // could have other key. How to do that in ts ?
};
id: number;
type: "user_job";
label: {
fr: string; // could have other key. How to do that in ts ?
};
}
export interface Center {
id: number;
type: "center";
name: string;
id: number;
type: "center";
name: string;
}
export interface Scope {
id: number;
type: "scope";
name: {
fr: string;
};
id: number;
type: "scope";
name: {
fr: string;
};
}
export interface ResultItem<T> {
result: T;
relevance: number;
result: T;
relevance: number;
}
export interface User {
type: "user";
id: number;
username: string;
text: string;
text_without_absence: string;
email: string;
user_job: Job;
label: string;
// todo: mainCenter; mainJob; etc..
}
export interface ThirdParty {
type: "thirdparty";
id: number;
text: string;
firstname: string;
name: string;
email: string;
telephone: string;
telephone2: string;
address: {
address_id: number;
text: string;
postcode: {
name: string;
};
id: number;
};
type: "user";
id: number;
username: string;
text: string;
text_without_absence: string;
email: string;
user_job: Job;
label: string;
// todo: mainCenter; mainJob; etc..
}
export interface UserGroup {
type: "user_group";
id: number;
label: TranslatableString;
backgroundColor: string;
foregroundColor: string;
excludeKey: string;
text: string;
type: "user_group";
id: number;
label: TranslatableString;
backgroundColor: string;
foregroundColor: string;
excludeKey: string;
text: string;
}
export type UserGroupOrUser = User | UserGroup;
export interface UserAssociatedInterface {
type: "user";
id: number;
type: "user";
id: number;
}
export type TranslatableString = Record<string, string>;
export interface Postcode {
id: number;
name: string;
code: string;
center: Point;
id: number;
name: string;
code: string;
center: Point;
}
export interface Point {
type: "Point";
coordinates: [lat: number, lon: number];
type: "Point";
coordinates: [lat: number, lon: number];
}
export interface Country {
id: number;
name: TranslatableString;
code: string;
id: number;
name: TranslatableString;
code: string;
}
export type AddressRefStatus = "match" | "to_review" | "reviewed";
export interface Address {
type: "address";
address_id: number;
text: string;
street: string;
streetNumber: string;
postcode: Postcode;
country: Country;
floor: string | null;
corridor: string | null;
steps: string | null;
flat: string | null;
buildingName: string | null;
distribution: string | null;
extra: string | null;
confidential: boolean;
lines: string[];
addressReference: AddressReference | null;
validFrom: DateTime;
validTo: DateTime | null;
point: Point | null;
refStatus: AddressRefStatus;
isNoAddress: boolean;
type: "address";
address_id: number;
text: string;
street: string;
streetNumber: string;
postcode: Postcode;
country: Country;
floor: string | null;
corridor: string | null;
steps: string | null;
flat: string | null;
buildingName: string | null;
distribution: string | null;
extra: string | null;
confidential: boolean;
lines: string[];
addressReference: AddressReference | null;
validFrom: DateTime;
validTo: DateTime | null;
point: Point | null;
refStatus: AddressRefStatus;
isNoAddress: boolean;
}
export interface AddressWithPoint extends Address {
point: Point;
point: Point;
}
export interface AddressReference {
id: number;
createdAt: DateTime | null;
deletedAt: DateTime | null;
municipalityCode: string;
point: Point;
postcode: Postcode;
refId: string;
source: string;
street: string;
streetNumber: string;
updatedAt: DateTime | null;
id: number;
createdAt: DateTime | null;
deletedAt: DateTime | null;
municipalityCode: string;
point: Point;
postcode: Postcode;
refId: string;
source: string;
street: string;
streetNumber: string;
updatedAt: DateTime | null;
}
export interface SimpleGeographicalUnit {
id: number;
layerId: number;
unitName: string;
unitRefId: string;
id: number;
layerId: number;
unitName: string;
unitRefId: string;
}
export interface GeographicalUnitLayer {
id: number;
name: TranslatableString;
refId: string;
id: number;
name: TranslatableString;
refId: string;
}
export interface Location {
type: "location";
id: number;
active: boolean;
address: Address | null;
availableForUsers: boolean;
createdAt: DateTime | null;
createdBy: User | null;
updatedAt: DateTime | null;
updatedBy: User | null;
email: string | null;
name: string;
phonenumber1: string | null;
phonenumber2: string | null;
locationType: LocationType;
type: "location";
id: number;
active: boolean;
address: Address | null;
availableForUsers: boolean;
createdAt: DateTime | null;
createdBy: User | null;
updatedAt: DateTime | null;
updatedBy: User | null;
email: string | null;
name: string;
phonenumber1: string | null;
phonenumber2: string | null;
locationType: LocationType;
}
export interface LocationAssociated {
type: "location";
id: number;
type: "location";
id: number;
}
export interface LocationType {
type: "location-type";
id: number;
active: boolean;
addressRequired: "optional" | "required";
availableForUsers: boolean;
editableByUsers: boolean;
contactData: "optional" | "required";
title: TranslatableString;
type: "location-type";
id: number;
active: boolean;
addressRequired: "optional" | "required";
availableForUsers: boolean;
editableByUsers: boolean;
contactData: "optional" | "required";
title: TranslatableString;
}
export interface NewsItemType {
id: number;
title: string;
content: string;
startDate: DateTime;
endDate: DateTime | null;
id: number;
title: string;
content: string;
startDate: DateTime;
endDate: DateTime | null;
}
export interface WorkflowAvailable {
name: string;
text: string;
name: string;
text: string;
}
export interface WorkflowAttachment {
id: number;
relatedGenericDocKey: string;
relatedGenericDocIdentifiers: object;
createdAt: DateTime | null;
createdBy: User | null;
updatedAt: DateTime | null;
updatedBy: User | null;
genericDoc: null | GenericDoc;
id: number;
relatedGenericDocKey: string;
relatedGenericDocIdentifiers: object;
createdAt: DateTime | null;
createdBy: User | null;
updatedAt: DateTime | null;
updatedBy: User | null;
genericDoc: null | GenericDoc;
}
export interface PrivateCommentEmbeddable {
comments: Record<number, string>;
comments: Record<number, string>;
}
// API Exception types
export interface TransportExceptionInterface {
name: string;
name: string;
}
export interface ValidationExceptionInterface
extends TransportExceptionInterface {
name: "ValidationException";
error: object;
violations: string[];
titles: string[];
propertyPaths: string[];
extends TransportExceptionInterface {
name: "ValidationException";
error: object;
violations: string[];
titles: string[];
propertyPaths: string[];
}
export interface AccessExceptionInterface extends TransportExceptionInterface {
name: "AccessException";
violations: string[];
name: "AccessException";
violations: string[];
}
export interface NotFoundExceptionInterface
extends TransportExceptionInterface {
name: "NotFoundException";
extends TransportExceptionInterface {
name: "NotFoundException";
}
export interface ServerExceptionInterface extends TransportExceptionInterface {
name: "ServerException";
message: string;
code: number;
body: string;
name: "ServerException";
message: string;
code: number;
body: string;
}
export interface ConflictHttpExceptionInterface
extends TransportExceptionInterface {
name: "ConflictHttpException";
violations: string[];
extends TransportExceptionInterface {
name: "ConflictHttpException";
violations: string[];
}
export type ApiException =
| ValidationExceptionInterface
| AccessExceptionInterface
| NotFoundExceptionInterface
| ServerExceptionInterface
| ConflictHttpExceptionInterface;
| ValidationExceptionInterface
| AccessExceptionInterface
| NotFoundExceptionInterface
| ServerExceptionInterface
| ConflictHttpExceptionInterface;
export interface Modal {
showModal: boolean;
modalDialogClass: string;
showModal: boolean;
modalDialogClass: string;
}
export interface Selected {
result: UserGroupOrUser;
result: UserGroupOrUser;
}
export interface addNewEntities {
selected: Selected[];
modal: Modal;
selected: Selected[];
modal: Modal;
}

View File

@@ -1,97 +1,97 @@
<template>
<a v-if="isDisplayBadge" @click="openModal">
<span class="chill-entity" :class="badgeType">
{{ buttonText }}<span v-if="isDead"> ()</span>
</span>
</a>
<a
v-else
class="btn btn-sm"
target="_blank"
:class="classAction"
:title="trans(titleAction)"
@click="openModal"
<a v-if="isDisplayBadge" @click="openModal">
<span class="chill-entity" :class="badgeType">
{{ buttonText }}<span v-if="isDead"> ()</span>
</span>
</a>
<a
v-else
class="btn btn-sm"
target="_blank"
:class="classAction"
:title="trans(titleAction)"
@click="openModal"
>
{{ buttonText }}<span v-if="isDead"> ()</span>
</a>
<teleport to="body">
<modal
v-if="modal.showModal"
:modal-dialog-class="modal.modalDialogClass"
@close="modal.showModal = false"
>
{{ buttonText }}<span v-if="isDead"> ()</span>
</a>
<template #header>
<h3 v-if="parent" class="modal-title">
{{ trans(titleModal, { q: parent.text }) }}
</h3>
<h3 v-else class="modal-title">
{{ trans(titleModal) }}
</h3>
</template>
<teleport to="body">
<modal
v-if="modal.showModal"
:modal-dialog-class="modal.modalDialogClass"
@close="modal.showModal = false"
>
<template #header>
<h3 v-if="parent" class="modal-title">
{{ trans(titleModal, { q: parent.text }) }}
</h3>
<h3 v-else class="modal-title">
{{ trans(titleModal) }}
</h3>
</template>
<template #body v-if="type === 'person'">
<on-the-fly-person
:id="id"
:type="type"
:action="action"
ref="castPerson"
/>
<div v-if="hasResourceComment">
<h3>{{ trans(ONTHEFLY_RESOURCE_COMMENT_TITLE) }}</h3>
<blockquote class="chill-user-quote">
{{ parent.comment }}
</blockquote>
</div>
</template>
<template #body v-if="type === 'person'">
<on-the-fly-person
:id="id"
:type="type"
:action="action"
ref="castPerson"
/>
<div v-if="hasResourceComment">
<h3>{{ trans(ONTHEFLY_RESOURCE_COMMENT_TITLE) }}</h3>
<blockquote class="chill-user-quote">
{{ parent.comment }}
</blockquote>
</div>
</template>
<template #body v-else-if="type === 'thirdparty'">
<on-the-fly-thirdparty
:id="id"
:type="type"
:action="action"
ref="castThirdparty"
/>
<div v-if="hasResourceComment">
<h3>{{ trans(ONTHEFLY_RESOURCE_COMMENT_TITLE) }}</h3>
<blockquote class="chill-user-quote">
{{ parent.comment }}
</blockquote>
</div>
</template>
<template #body v-else-if="type === 'thirdparty'">
<on-the-fly-thirdparty
:id="id"
:type="type"
:action="action"
ref="castThirdparty"
/>
<div v-if="hasResourceComment">
<h3>{{ trans(ONTHEFLY_RESOURCE_COMMENT_TITLE) }}</h3>
<blockquote class="chill-user-quote">
{{ parent.comment }}
</blockquote>
</div>
</template>
<template #body v-else-if="parent">
<on-the-fly-thirdparty
:parent="parent"
:action="action"
type="thirdparty"
ref="castThirdparty"
/>
</template>
<template #body v-else-if="parent">
<on-the-fly-thirdparty
:parent="parent"
:action="action"
type="thirdparty"
ref="castThirdparty"
/>
</template>
<template #body v-else>
<on-the-fly-create
:action="action"
:allowed-types="allowedTypes"
:query="query"
ref="castNew"
/>
</template>
<template #body v-else>
<on-the-fly-create
:action="action"
:allowed-types="allowedTypes"
:query="query"
ref="castNew"
/>
</template>
<template #footer>
<a
v-if="action === 'show'"
:href="buildLocation(id, type)"
:title="trans(titleMessage)"
class="btn btn-show"
>{{ trans(buttonMessage) }}
</a>
<a v-else class="btn btn-save" @click="saveAction">
{{ trans(ACTION_SAVE) }}
</a>
</template>
</modal>
</teleport>
<template #footer>
<a
v-if="action === 'show'"
:href="buildLocation(id, type)"
:title="trans(titleMessage)"
class="btn btn-show"
>{{ trans(buttonMessage) }}
</a>
<a v-else class="btn btn-save" @click="saveAction">
{{ trans(ACTION_SAVE) }}
</a>
</template>
</modal>
</teleport>
</template>
<script setup>
import { ref, computed, defineEmits, defineProps } from "vue";
@@ -100,45 +100,45 @@ import OnTheFlyCreate from "./Create.vue";
import OnTheFlyPerson from "ChillPersonAssets/vuejs/_components/OnTheFly/Person.vue";
import OnTheFlyThirdparty from "ChillThirdPartyAssets/vuejs/_components/OnTheFly/ThirdParty.vue";
import {
trans,
ACTION_SHOW,
ACTION_EDIT,
ACTION_CREATE,
ACTION_ADDCONTACT,
ONTHEFLY_CREATE_TITLE_DEFAULT,
ONTHEFLY_CREATE_TITLE_PERSON,
ONTHEFLY_CREATE_TITLE_THIRDPARTY,
ONTHEFLY_SHOW_PERSON,
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,
trans,
ACTION_SHOW,
ACTION_EDIT,
ACTION_CREATE,
ACTION_ADDCONTACT,
ONTHEFLY_CREATE_TITLE_DEFAULT,
ONTHEFLY_CREATE_TITLE_PERSON,
ONTHEFLY_CREATE_TITLE_THIRDPARTY,
ONTHEFLY_SHOW_PERSON,
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,
} from "translator";
const props = defineProps({
type: String,
id: [String, Number],
action: String,
buttonText: String,
displayBadge: Boolean,
isDead: Boolean,
parent: Object,
allowedTypes: Array,
query: String,
type: String,
id: [String, Number],
action: String,
buttonText: String,
displayBadge: Boolean,
isDead: Boolean,
parent: Object,
allowedTypes: Array,
query: String,
});
const emit = defineEmits(["saveFormOnTheFly"]);
const modal = ref({
showModal: false,
modalDialogClass: "modal-dialog-scrollable modal-xl",
showModal: false,
modalDialogClass: "modal-dialog-scrollable modal-xl",
});
const castPerson = ref();
@@ -146,214 +146,209 @@ const castThirdparty = ref();
const castNew = ref();
const hasResourceComment = computed(() => {
return (
typeof props.parent !== "undefined" &&
props.parent !== null &&
props.action === "show" &&
props.parent.type === "accompanying_period_resource" &&
props.parent.comment !== null &&
props.parent.comment !== ""
);
return (
typeof props.parent !== "undefined" &&
props.parent !== null &&
props.action === "show" &&
props.parent.type === "accompanying_period_resource" &&
props.parent.comment !== null &&
props.parent.comment !== ""
);
});
const classAction = computed(() => {
switch (props.action) {
case "show":
return "btn-show";
case "edit":
return "btn-update";
case "create":
return "btn-create";
case "addContact":
return "btn-tpchild";
default:
return "";
}
switch (props.action) {
case "show":
return "btn-show";
case "edit":
return "btn-update";
case "create":
return "btn-create";
case "addContact":
return "btn-tpchild";
default:
return "";
}
});
const titleAction = computed(() => {
switch (props.action) {
case "show":
return ACTION_SHOW;
case "edit":
return ACTION_EDIT;
case "create":
return ACTION_CREATE;
case "addContact":
return ACTION_ADDCONTACT;
default:
return "";
}
switch (props.action) {
case "show":
return ACTION_SHOW;
case "edit":
return ACTION_EDIT;
case "create":
return ACTION_CREATE;
case "addContact":
return ACTION_ADDCONTACT;
default:
return "";
}
});
const titleCreate = computed(() => {
if (typeof props.allowedTypes === "undefined") {
return 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;
if (typeof props.allowedTypes === "undefined") {
return 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;
});
const titleModal = computed(() => {
switch (props.action) {
case "show":
if (props.type == "person") {
return ONTHEFLY_SHOW_PERSON;
} else if (props.type == "thirdparty") {
return ONTHEFLY_SHOW_THIRDPARTY;
}
break;
case "edit":
if (props.type == "person") {
return ONTHEFLY_EDIT_PERSON;
} else if (props.type == "thirdparty") {
return ONTHEFLY_EDIT_THIRDPARTY;
}
break;
case "create":
return titleCreate.value;
case "addContact":
return ONTHEFLY_ADDCONTACT_TITLE;
default:
break;
}
return "";
switch (props.action) {
case "show":
if (props.type == "person") {
return ONTHEFLY_SHOW_PERSON;
} else if (props.type == "thirdparty") {
return ONTHEFLY_SHOW_THIRDPARTY;
}
break;
case "edit":
if (props.type == "person") {
return ONTHEFLY_EDIT_PERSON;
} else if (props.type == "thirdparty") {
return ONTHEFLY_EDIT_THIRDPARTY;
}
break;
case "create":
return titleCreate.value;
case "addContact":
return ONTHEFLY_ADDCONTACT_TITLE;
default:
break;
}
return "";
});
const titleMessage = computed(() => {
switch (props.type) {
case "person":
return ACTION_REDIRECT_PERSON;
case "thirdparty":
return ACTION_REDIRECT_THIRDPARTY;
default:
return "";
}
switch (props.type) {
case "person":
return ACTION_REDIRECT_PERSON;
case "thirdparty":
return ACTION_REDIRECT_THIRDPARTY;
default:
return "";
}
});
const buttonMessage = computed(() => {
switch (props.type) {
case "person":
return ONTHEFLY_SHOW_FILE_PERSON;
case "thirdparty":
return ONTHEFLY_SHOW_FILE_THIRDPARTY;
default:
return ONTHEFLY_SHOW_FILE_DEFAULT;
}
switch (props.type) {
case "person":
return ONTHEFLY_SHOW_FILE_PERSON;
case "thirdparty":
return ONTHEFLY_SHOW_FILE_THIRDPARTY;
default:
return ONTHEFLY_SHOW_FILE_DEFAULT;
}
});
const isDisplayBadge = computed(() => {
return props.displayBadge === true && props.buttonText !== null;
return props.displayBadge === true && props.buttonText !== null;
});
const badgeType = computed(() => {
return "entity-" + props.type + " badge-" + props.type;
return "entity-" + props.type + " badge-" + props.type;
});
const getReturnPath = computed(() => {
return `?returnPath=${window.location.pathname}${window.location.search}${window.location.hash}`;
return `?returnPath=${window.location.pathname}${window.location.search}${window.location.hash}`;
});
function closeModal() {
modal.value.showModal = false;
modal.value.showModal = false;
}
function openModal() {
modal.value.showModal = true;
modal.value.showModal = true;
}
function changeActionTo(action) {
console.log(action);
// Not reactive in setup, but you can emit or use a ref if needed
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 : "";
}
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,
}
} else {
throw "error with object type";
}
}
emit("saveFormOnTheFly", { type: type, data: data });
: 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") {
return encodeURI(`/fr/person/${id}/general${getReturnPath.value}`);
} else if (type === "thirdparty") {
return encodeURI(`/fr/3party/3party/${id}/view${getReturnPath.value}`);
}
if (type === "person") {
return encodeURI(`/fr/person/${id}/general${getReturnPath.value}`);
} else if (type === "thirdparty") {
return encodeURI(`/fr/3party/3party/${id}/view${getReturnPath.value}`);
}
}
defineExpose({
openModal,
closeModal,
changeActionTo,
saveAction,
castPerson,
castThirdparty,
castNew,
hasResourceComment,
modal,
isDisplayBadge,
Modal,
openModal,
closeModal,
changeActionTo,
saveAction,
castPerson,
castThirdparty,
castNew,
hasResourceComment,
modal,
isDisplayBadge,
Modal,
});
</script>
<style lang="css" scoped>
a {
cursor: pointer;
cursor: pointer;
}
/* .btn-add-contact {

View File

@@ -1,41 +1,37 @@
<template>
<div class="grey-card">
<ul :class="listClasses" v-if="picked.length && displayPicked">
<li
v-for="p in picked"
@click="removeEntity(p)"
:key="p.type + p.id"
>
<span
:class="getBadgeClass(p)"
class="chill_denomination"
:style="getBadgeStyle(p)"
>
{{ p.text }}
</span>
</li>
</ul>
<ul class="record_actions">
<li class="add-persons">
<add-persons
:options="addPersonsOptions"
:key="uniqid"
:buttonTitle="translatedListOfTypes"
:modalTitle="translatedListOfTypes"
@addNewPersons="addNewEntity"
>
</add-persons>
</li>
</ul>
<div class="grey-card">
<ul :class="listClasses" v-if="picked.length && displayPicked">
<li v-for="p in picked" @click="removeEntity(p)" :key="p.type + p.id">
<span
:class="getBadgeClass(p)"
class="chill_denomination"
:style="getBadgeStyle(p)"
>
{{ p.text }}
</span>
</li>
</ul>
<ul class="record_actions">
<li class="add-persons">
<add-persons
:options="addPersonsOptions"
:key="uniqid"
:buttonTitle="translatedListOfTypes"
:modalTitle="translatedListOfTypes"
@addNewPersons="addNewEntity"
>
</add-persons>
</li>
</ul>
<ul class="badge-suggest add-items inline" style="float: right">
<li v-for="s in suggested" :key="s.id" @click="addNewSuggested(s)">
<span :class="getBadgeClass(s)" :style="getBadgeStyle(s)">
{{ s.text }}
</span>
</li>
</ul>
</div>
<ul class="badge-suggest add-items inline" style="float: right">
<li v-for="s in suggested" :key="s.id" @click="addNewSuggested(s)">
<span :class="getBadgeClass(s)" :style="getBadgeStyle(s)">
{{ s.text }}
</span>
</li>
</ul>
</div>
</template>
<script lang="ts" setup>
@@ -43,135 +39,135 @@ import { ref, computed, defineProps, defineEmits, defineComponent } from "vue";
import AddPersons from "ChillPersonAssets/vuejs/_components/AddPersons.vue";
import { Entities, EntityType, SearchOptions } from "ChillPersonAssets/types";
import {
PICK_ENTITY_MODAL_TITLE,
PICK_ENTITY_USER,
PICK_ENTITY_USER_GROUP,
PICK_ENTITY_PERSON,
PICK_ENTITY_THIRDPARTY,
trans,
PICK_ENTITY_MODAL_TITLE,
PICK_ENTITY_USER,
PICK_ENTITY_USER_GROUP,
PICK_ENTITY_PERSON,
PICK_ENTITY_THIRDPARTY,
trans,
} from "translator";
import { addNewEntities } from "ChillMainAssets/types";
defineComponent({
components: {
AddPersons,
},
components: {
AddPersons,
},
});
const props = defineProps<{
multiple: boolean;
types: EntityType[];
picked: Entities[];
uniqid: string;
removableIfSet?: boolean;
displayPicked?: boolean;
suggested?: Entities[];
label?: string;
multiple: boolean;
types: EntityType[];
picked: Entities[];
uniqid: string;
removableIfSet?: boolean;
displayPicked?: boolean;
suggested?: Entities[];
label?: string;
}>();
const emits = defineEmits<{
(e: "addNewEntity", payload: { entity: Entities }): void;
(e: "removeEntity", payload: { entity: Entities }): void;
(e: "addNewEntityProcessEnded"): void;
(e: "addNewEntity", payload: { entity: Entities }): void;
(e: "removeEntity", payload: { entity: Entities }): void;
(e: "addNewEntityProcessEnded"): void;
}>();
const addPersons = ref();
const addPersonsOptions = computed(
() =>
({
uniq: !props.multiple,
type: props.types,
priority: null,
button: {
size: "btn-sm",
class: "btn-submit",
},
}) as SearchOptions,
() =>
({
uniq: !props.multiple,
type: props.types,
priority: null,
button: {
size: "btn-sm",
class: "btn-submit",
},
}) as SearchOptions,
);
const translatedListOfTypes = computed(() => {
if (props.label !== undefined && props.label !== "") {
return props.label;
if (props.label !== undefined && props.label !== "") {
return props.label;
}
const translatedTypes = props.types.map((type: EntityType) => {
switch (type) {
case "user":
return trans(PICK_ENTITY_USER, {
count: props.multiple ? 2 : 1,
});
case "person":
return trans(PICK_ENTITY_PERSON, {
count: props.multiple ? 2 : 1,
});
case "thirdparty":
return trans(PICK_ENTITY_THIRDPARTY, {
count: props.multiple ? 2 : 1,
});
case "user_group":
return trans(PICK_ENTITY_USER_GROUP, {
count: props.multiple ? 2 : 1,
});
}
});
const translatedTypes = props.types.map((type: EntityType) => {
switch (type) {
case "user":
return trans(PICK_ENTITY_USER, {
count: props.multiple ? 2 : 1,
});
case "person":
return trans(PICK_ENTITY_PERSON, {
count: props.multiple ? 2 : 1,
});
case "third_party":
return trans(PICK_ENTITY_THIRDPARTY, {
count: props.multiple ? 2 : 1,
});
case "user_group":
return trans(PICK_ENTITY_USER_GROUP, {
count: props.multiple ? 2 : 1,
});
}
});
return `${trans(PICK_ENTITY_MODAL_TITLE, {
count: props.multiple ? 2 : 1,
})} ${translatedTypes.join(", ")}`;
return `${trans(PICK_ENTITY_MODAL_TITLE, {
count: props.multiple ? 2 : 1,
})} ${translatedTypes.join(", ")}`;
});
const listClasses = computed(() => ({
"badge-suggest": true,
"remove-items": props.removableIfSet !== false,
inline: true,
"badge-suggest": true,
"remove-items": props.removableIfSet !== false,
inline: true,
}));
function addNewSuggested(entity: Entities) {
emits("addNewEntity", { entity });
emits("addNewEntity", { entity });
}
function addNewEntity({ selected }: addNewEntities) {
Object.values(selected).forEach((item) => {
emits("addNewEntity", { entity: item.result });
});
addPersons.value?.resetSearch();
Object.values(selected).forEach((item) => {
emits("addNewEntity", { entity: item.result });
});
addPersons.value?.resetSearch();
emits("addNewEntityProcessEnded");
emits("addNewEntityProcessEnded");
}
function removeEntity(entity: Entities) {
if (props.removableIfSet === false) {
return;
}
emits("removeEntity", { entity });
if (props.removableIfSet === false) {
return;
}
emits("removeEntity", { entity });
}
function getBadgeClass(entities: Entities) {
if (entities.type !== "user_group") {
return entities.type;
}
return "";
if (entities.type !== "user_group") {
return entities.type;
}
return "";
}
function getBadgeStyle(entities: Entities) {
if (entities.type === "user_group") {
return [
`ul.badge-suggest li > span {
if (entities.type === "user_group") {
return [
`ul.badge-suggest li > span {
color: ${entities.foregroundColor}!important;
border-bottom-color: ${entities.backgroundColor};
}`,
];
}
return [];
];
}
return [];
}
</script>
<style lang="scss" scoped>
.grey-card {
background: #f8f9fa;
border-radius: 8px;
padding: 1.5rem;
min-height: 160px;
background: #f8f9fa;
border-radius: 8px;
padding: 1.5rem;
min-height: 160px;
}
.btn-check:checked + .btn,
@@ -179,94 +175,94 @@ function getBadgeStyle(entities: Entities) {
.btn:first-child:active,
.btn.active,
.btn.show {
color: white;
box-shadow: 0 0 0 0.2rem var(--bs-chill-green);
outline: 0;
color: white;
box-shadow: 0 0 0 0.2rem var(--bs-chill-green);
outline: 0;
}
.as-user-group {
display: inline-block;
display: inline-block;
}
ul.badge-suggest {
list-style-type: none;
padding-left: 0;
margin-bottom: 0px;
list-style-type: none;
padding-left: 0;
margin-bottom: 0px;
}
ul.badge-suggest li > span {
white-space: normal;
text-align: start;
margin-bottom: 3px;
white-space: normal;
text-align: start;
margin-bottom: 3px;
}
ul.badge-suggest.inline li {
display: inline-block;
margin-right: 0.2em;
display: inline-block;
margin-right: 0.2em;
}
ul.badge-suggest.add-items li {
position: relative;
position: relative;
}
ul.badge-suggest.add-items li span {
cursor: pointer;
padding-left: 2rem;
cursor: pointer;
padding-left: 2rem;
}
ul.badge-suggest.add-items li span:hover {
color: #ced4da;
color: #ced4da;
}
ul.badge-suggest.add-items li > span:before {
font: normal normal normal 13px ForkAwesome;
margin-right: 1.8em;
content: "\f067";
color: var(--bs-success);
position: absolute;
display: block;
top: 50%;
left: 0.75rem;
-webkit-transform: translateY(-50%);
-moz-transform: translateY(-50%);
-ms-transform: translateY(-50%);
transform: translateY(-50%);
font: normal normal normal 13px ForkAwesome;
margin-right: 1.8em;
content: "\f067";
color: var(--bs-success);
position: absolute;
display: block;
top: 50%;
left: 0.75rem;
-webkit-transform: translateY(-50%);
-moz-transform: translateY(-50%);
-ms-transform: translateY(-50%);
transform: translateY(-50%);
}
ul.badge-suggest.remove-items li {
position: relative;
position: relative;
}
ul.badge-suggest.remove-items li span {
cursor: pointer;
padding-left: 2rem;
cursor: pointer;
padding-left: 2rem;
}
ul.badge-suggest.remove-items li span:hover {
color: #ced4da;
color: #ced4da;
}
ul.badge-suggest.remove-items li > span:before {
font: normal normal normal 13px ForkAwesome;
margin-right: 1.8em;
content: "\f1f8";
color: var(--bs-danger);
position: absolute;
display: block;
top: 50%;
left: 0.75rem;
-webkit-transform: translateY(-50%);
-moz-transform: translateY(-50%);
-ms-transform: translateY(-50%);
transform: translateY(-50%);
font: normal normal normal 13px ForkAwesome;
margin-right: 1.8em;
content: "\f1f8";
color: var(--bs-danger);
position: absolute;
display: block;
top: 50%;
left: 0.75rem;
-webkit-transform: translateY(-50%);
-moz-transform: translateY(-50%);
-ms-transform: translateY(-50%);
transform: translateY(-50%);
}
ul.badge-suggest li > span {
margin: 0.2rem 0.1rem;
display: inline-block;
padding: 0 1em 0 2.2em !important;
background-color: #fff;
border: 1px solid #dee2e6;
border-bottom-width: 3px;
border-bottom-style: solid;
border-radius: 6px;
font-size: 0.75em;
font-weight: 700;
margin: 0.2rem 0.1rem;
display: inline-block;
padding: 0 1em 0 2.2em !important;
background-color: #fff;
border: 1px solid #dee2e6;
border-bottom-width: 3px;
border-bottom-style: solid;
border-radius: 6px;
font-size: 0.75em;
font-weight: 700;
}
ul.badge-suggest li > span.person {
border-bottom-color: #43b29d;
border-bottom-color: #43b29d;
}
ul.badge-suggest li > span.thirdparty {
border-bottom-color: rgb(198.9, 72, 98.1);
border-bottom-color: rgb(198.9, 72, 98.1);
}
</style>