Browse Source

add phone number formatting

Olivier Massot 4 years ago
parent
commit
70f8be998a
5 changed files with 144 additions and 122 deletions
  1. 1 0
      README.md
  2. 1 0
      package.json
  3. 129 122
      pages/organization/index.vue
  4. 8 0
      services/utils/i18n.ts
  5. 5 0
      yarn.lock

+ 1 - 0
README.md

@@ -13,6 +13,7 @@ A voir:
 * [vuetifyjs.com](https://vuetifyjs.com/en/)
 * [typescriptlang.org](https://www.typescriptlang.org/)
 * [jestjs.io](https://jestjs.io/docs/getting-started)
+* [cypress.io](https://docs.cypress.io/guides/getting-started/installing-cypress)
 
 ### Build Setup
 

+ 1 - 0
package.json

@@ -28,6 +28,7 @@
     "cookieparser": "^0.1",
     "core-js": "^3.17",
     "js-yaml": "^4.0",
+    "libphonenumber-js": "^1.9.39",
     "lodash": "^4.17",
     "marked": "^3.0",
     "nuxt": "^2.15",

+ 129 - 122
pages/organization/index.vue

@@ -4,65 +4,63 @@ Contient toutes les informations sur l'organization courante
 -->
 <template>
   <LayoutContainer>
-
-    <UiForm :model="models.Organization" :id="id" :query="repositories.organizationRepository.query()">
-      <template v-slot:form.input="{entry, updateRepository}">
-
+    <UiForm :id="id" :model="models.Organization" :query="repositories.organizationRepository.query()">
+      <template #form.input="{entry, updateRepository}">
         <v-expansion-panels :value="panel" focusable accordion>
-
           <!-- Description -->
           <UiExpansionPanel id="description" icon="fa-info">
             <v-container fluid class="container">
               <v-row>
                 <v-col cols="12" sm="6">
-                  <UiInputText field="name" :data="entry['name']"  v-on:update="updateRepository"/>
+                  <UiInputText field="name" :data="entry['name']" @update="updateRepository" />
                 </v-col>
 
                 <v-col cols="12" sm="6">
-                  <UiInputText field="acronym" :data="entry['acronym']"  v-on:update="updateRepository"/>
+                  <UiInputText field="acronym" :data="entry['acronym']" @update="updateRepository" />
                 </v-col>
 
                 <v-col cols="12" sm="6">
-                  <UiInputText field="siretNumber"
-                               :data="entry['siretNumber']"
-                               v-on:update="checkSiretHook($event, 'siretNumber', updateRepository)"
-                               :error="siretError"
-                               :errorMessage="siretErrorMessage"
-                               :rules="rules.siretRule"
+                  <UiInputText
+                    field="siretNumber"
+                    :data="entry['siretNumber']"
+                    :error="siretError"
+                    :error-message="siretErrorMessage"
+                    :rules="rules.siretRule"
+                    @update="checkSiretHook($event, 'siretNumber', updateRepository)"
                   />
                 </v-col>
 
                 <v-col cols="12" sm="6">
-                  <UiInputText field="apeNumber" :data="entry['apeNumber']"  v-on:update="updateRepository"/>
+                  <UiInputText field="apeNumber" :data="entry['apeNumber']" @update="updateRepository" />
                 </v-col>
 
-                <v-col cols="12" sm="6" v-if="entry['legalStatus'] === 'ASSOCIATION_LAW_1901'">
-                  <UiInputText field="waldecNumber" :data="entry['waldecNumber']"  v-on:update="updateRepository"/>
+                <v-col v-if="entry['legalStatus'] === 'ASSOCIATION_LAW_1901'" cols="12" sm="6">
+                  <UiInputText field="waldecNumber" :data="entry['waldecNumber']" @update="updateRepository" />
                 </v-col>
 
-                <v-col cols="12" sm="6" v-if="organizationProfile.isInsideNetwork()">
-                  <UiInputText :label="organizationProfile.isCmf() ? 'identifierCmf' : 'identifierFfec'" field="identifier" :data="entry['identifier']"  v-on:update="updateRepository"/>
+                <v-col v-if="organizationProfile.isInsideNetwork()" cols="12" sm="6">
+                  <UiInputText :label="organizationProfile.isCmf() ? 'identifierCmf' : 'identifierFfec'" field="identifier" :data="entry['identifier']" @update="updateRepository" />
                 </v-col>
 
-                <v-col cols="12" sm="6" v-if="organizationProfile.isFfec()">
-                  <UiInputText field="ffecApproval" :data="entry['ffecApproval']"  v-on:update="updateRepository"/>
+                <v-col v-if="organizationProfile.isFfec()" cols="12" sm="6">
+                  <UiInputText field="ffecApproval" :data="entry['ffecApproval']" @update="updateRepository" />
                 </v-col>
 
                 <v-col cols="12" sm="6">
-                  <UiInputText field="description" :data="entry['description']"  v-on:update="updateRepository"/>
+                  <UiInputText field="description" :data="entry['description']" @update="updateRepository" />
                 </v-col>
 
                 <v-col cols="12" sm="6">
-                  <UiInputText field="logo" :data="entry['logo']"  v-on:update="updateRepository"/>
+                  <UiInputText field="logo" :data="entry['logo']" @update="updateRepository" />
                 </v-col>
 
                 <!-- @todo: ajouter les if et transformer en select-->
                 <v-col cols="12" sm="6">
-                  <UiInputText field="typeOfPractices" :data="entry['typeOfPractices']"  v-on:update="updateRepository"/>
+                  <UiInputText field="typeOfPractices" :data="entry['typeOfPractices']" @update="updateRepository" />
                 </v-col>
 
                 <v-col cols="12" sm="6">
-                  <UiInputText field="otherPractice" :data="entry['otherPractice']"  v-on:update="updateRepository"/>
+                  <UiInputText field="otherPractice" :data="entry['otherPractice']" @update="updateRepository" />
                 </v-col>
               </v-row>
             </v-container>
@@ -77,33 +75,35 @@ Contient toutes les informations sur l'organization courante
                     :query="repositories.addressRepository.with('addressPostal', (query) => {
                       query.with('addressCountry')
                     })"
-                    :rootModel="models.Organization"
-                    :rootId="id"
+                    :root-model="models.Organization"
+                    :root-id="id"
                     :model="models.OrganizationAddressPostal"
                   >
-                    <template v-slot:list.item="{items}">
+                    <template #list.item="{items}">
                       <v-container fluid>
                         <v-row dense>
-                            <v-col
-                              v-for="item in items"
-                              :key="item.id"
-                              cols="4"
+                          <v-col
+                            v-for="item in items"
+                            :key="item.id"
+                            cols="4"
+                          >
+                            <UiCard
+                              :id="item.id"
+                              :link="`/organization/address/${item.id}`"
+                              :model="models.OrganizationAddressPostal"
                             >
-                              <UiCard
-                                :link="`/organization/address/${item.id}`"
-                                :model="models.OrganizationAddressPostal"
-                                :id="item.id"
-                              >
-                                <template v-slot:card.title>{{$t(item.type)}}</template>
-                                <template v-slot:card.text>
-                                  {{item.addressPostal.streetAddress}} <br />
-                                  <span v-if="item.addressPostal.streetAddressSecond">{{item.addressPostal.streetAddressSecond}} <br /></span>
-                                  <span v-if="item.addressPostal.streetAddressThird">{{item.addressPostal.streetAddressThird}} <br /></span>
-                                  {{item.addressPostal.postalCode}} {{item.addressPostal.addressCity}}<br />
-                                  <span v-if="item.addressPostal.addressCountry">{{item.addressPostal.addressCountry.name}}</span>
-                                </template>
-                              </UiCard>
-                            </v-col>
+                              <template #card.title>
+                                {{ $t(item.type) }}
+                              </template>
+                              <template #card.text>
+                                {{ item.addressPostal.streetAddress }} <br>
+                                <span v-if="item.addressPostal.streetAddressSecond">{{ item.addressPostal.streetAddressSecond }} <br></span>
+                                <span v-if="item.addressPostal.streetAddressThird">{{ item.addressPostal.streetAddressThird }} <br></span>
+                                {{ item.addressPostal.postalCode }} {{ item.addressPostal.addressCity }}<br>
+                                <span v-if="item.addressPostal.addressCountry">{{ item.addressPostal.addressCountry.name }}</span>
+                              </template>
+                            </UiCard>
+                          </v-col>
                         </v-row>
                       </v-container>
                     </template>
@@ -120,11 +120,11 @@ Contient toutes les informations sur l'organization courante
                 <v-col cols="12" sm="12">
                   <UiSubList
                     :query="repositories.contactPointRepository.query()"
-                    :rootModel="models.Organization"
-                    :rootId="id"
+                    :root-model="models.Organization"
+                    :root-id="id"
                     :model="models.ContactPoint"
                   >
-                    <template v-slot:list.item="{items}">
+                    <template #list.item="{items}">
                       <v-container fluid>
                         <v-row dense>
                           <v-col
@@ -133,18 +133,22 @@ Contient toutes les informations sur l'organization courante
                             cols="4"
                           >
                             <UiCard
+                              :id="item.id"
                               :link="`/organization/contact_points/${item.id}`"
                               :model="models.ContactPoint"
-                              :id="item.id"
                             >
-                              <template v-slot:card.title>{{$t(item.contactType)}}</template>
-                              <template v-slot:card.text>
-                                <span v-if="item.email"><strong>{{$t('email')}}</strong> : {{item.email}} <br /></span>
-                                <span v-if="item.emailInvalid" class="ot_danger--text"><v-icon class="ot_danger--text">mdi-alert</v-icon> <strong>{{$t('emailInvalid')}}</strong> : {{item.emailInvalid}} <br /></span>
-                                <span v-if="item.telphone"><strong>{{$t('telphone')}}</strong> : {{item.telphone}} <br /></span>
-                                <span v-if="item.telphoneInvalid"  class="ot_danger--text"><v-icon class="ot_danger--text">mdi-alert</v-icon> <strong>{{$t('telphoneInvalid')}}</strong> : {{item.telphoneInvalid}} <br /></span>
-                                <span v-if="item.mobilPhone"><strong>{{$t('mobilPhone')}}</strong> : {{item.mobilPhone}} <br /></span>
-                                <span v-if="item.mobilPhoneInvalid" class="ot_danger--text"><v-icon class="ot_danger--text">mdi-alert</v-icon> <strong>{{$t('mobilPhoneInvalid')}}</strong> : {{item.mobilPhoneInvalid}} </span>
+                              <template #card.title>
+                                {{ $t(item.contactType) }}
+                              </template>
+                              <template #card.text>
+                                <span v-if="item.email"><strong>{{ $t('email') }}</strong> : {{ item.email }} <br></span>
+                                <span v-if="item.emailInvalid" class="ot_danger--text"><v-icon class="ot_danger--text">mdi-alert</v-icon> <strong>{{ $t('emailInvalid') }}</strong> : {{ item.emailInvalid }} <br></span>
+
+                                <span v-if="item.telphone"><strong>{{ $t('telphone') }}</strong> : {{ formatPhoneNumber(item.telphone) }} <br></span>
+                                <span v-if="item.telphoneInvalid" class="ot_danger--text"><v-icon class="ot_danger--text">mdi-alert</v-icon> <strong>{{ $t('telphoneInvalid') }}</strong> : {{ item.telphoneInvalid }} <br></span>
+
+                                <span v-if="item.mobilPhone"><strong>{{ $t('mobilPhone') }}</strong> : {{ item.mobilPhone }} <br></span>
+                                <span v-if="item.mobilPhoneInvalid" class="ot_danger--text"><v-icon class="ot_danger--text">mdi-alert</v-icon> <strong>{{ $t('mobilPhoneInvalid') }}</strong> : {{ item.mobilPhoneInvalid }} </span>
                               </template>
                             </UiCard>
                           </v-col>
@@ -162,38 +166,38 @@ Contient toutes les informations sur l'organization courante
             <v-container fluid class="container">
               <v-row>
                 <v-col cols="12" sm="6">
-                  <UiInputDatePicker field="creationDate" :data="entry['creationDate']"  v-on:update="updateRepository"/>
+                  <UiInputDatePicker field="creationDate" :data="entry['creationDate']" @update="updateRepository" />
                 </v-col>
                 <v-col cols="12" sm="6">
-                  <UiInputText field="prefectureName" :data="entry['prefectureName']"  v-on:update="updateRepository"/>
+                  <UiInputText field="prefectureName" :data="entry['prefectureName']" @update="updateRepository" />
                 </v-col>
 
                 <v-col cols="12" sm="6">
-                  <UiInputText field="prefectureNumber" :data="entry['prefectureNumber']"  v-on:update="updateRepository"/>
+                  <UiInputText field="prefectureNumber" :data="entry['prefectureNumber']" @update="updateRepository" />
                 </v-col>
 
                 <v-col cols="12" sm="6">
-                  <UiInputText field="tvaNumber" :data="entry['tvaNumber']"  v-on:update="updateRepository"/>
+                  <UiInputText field="tvaNumber" :data="entry['tvaNumber']" @update="updateRepository" />
                 </v-col>
 
                 <v-col cols="12" sm="6">
-                  <UiInputEnum field="legalStatus" :data="entry['legalStatus']"  enumType="organization_legal" v-on:update="updateRepository"/>
+                  <UiInputEnum field="legalStatus" :data="entry['legalStatus']" enum-type="organization_legal" @update="updateRepository" />
                 </v-col>
 
-                <v-col cols="12" sm="6" v-if="!organizationProfile.isManagerProduct()">
-                  <UiInputEnum field="principalType" :data="entry['principalType']"  enumType="organization_principal_type" v-on:update="updateRepository"/>
+                <v-col v-if="!organizationProfile.isManagerProduct()" cols="12" sm="6">
+                  <UiInputEnum field="principalType" :data="entry['principalType']" enum-type="organization_principal_type" @update="updateRepository" />
                 </v-col>
 
-                <v-col cols="12" sm="6" v-if="!organizationProfile.isFfec() && !organizationProfile.isManagerProduct() && !organizationProfile.isArtist()">
-                  <UiInputEnum field="schoolCategory" :data="entry['schoolCategory']"  enumType="organization_school_cat" v-on:update="updateRepository"/>
+                <v-col v-if="!organizationProfile.isFfec() && !organizationProfile.isManagerProduct() && !organizationProfile.isArtist()" cols="12" sm="6">
+                  <UiInputEnum field="schoolCategory" :data="entry['schoolCategory']" enum-type="organization_school_cat" @update="updateRepository" />
                 </v-col>
 
-                <v-col cols="12" sm="6" v-if="organizationProfile.isFfec()">
-                  <UiInputEnum field="typeEstablishment" :data="entry['typeEstablishment']"  enumType="organization_type_establishment" v-on:update="updateRepository"/>
+                <v-col v-if="organizationProfile.isFfec()" cols="12" sm="6">
+                  <UiInputEnum field="typeEstablishment" :data="entry['typeEstablishment']" enum-type="organization_type_establishment" @update="updateRepository" />
                 </v-col>
 
-                <v-col cols="12" sm="6" v-if="entry.typeEstablishment === 'MULTIPLE'">
-                  <UiInputEnum field="typeEstablishmentDetail" :data="entry['typeEstablishmentDetail']"  enumType="organization_type_establishment_detail" v-on:update="updateRepository"/>
+                <v-col v-if="entry.typeEstablishment === 'MULTIPLE'" cols="12" sm="6">
+                  <UiInputEnum field="typeEstablishmentDetail" :data="entry['typeEstablishmentDetail']" enum-type="organization_type_establishment_detail" @update="updateRepository" />
                 </v-col>
               </v-row>
             </v-container>
@@ -204,15 +208,15 @@ Contient toutes les informations sur l'organization courante
             <v-container class="container">
               <v-row>
                 <v-col cols="12" sm="6">
-                  <UiInputText field="youngApproval" :data="entry['youngApproval']"  v-on:update="updateRepository"/>
+                  <UiInputText field="youngApproval" :data="entry['youngApproval']" @update="updateRepository" />
                 </v-col>
 
                 <v-col cols="12" sm="6">
-                  <UiInputText field="trainingApproval" :data="entry['trainingApproval']"  v-on:update="updateRepository"/>
+                  <UiInputText field="trainingApproval" :data="entry['trainingApproval']" @update="updateRepository" />
                 </v-col>
 
                 <v-col cols="12" sm="6">
-                  <UiInputText field="otherApproval" :data="entry['otherApproval']"  v-on:update="updateRepository"/>
+                  <UiInputText field="otherApproval" :data="entry['otherApproval']" @update="updateRepository" />
                 </v-col>
               </v-row>
             </v-container>
@@ -223,19 +227,19 @@ Contient toutes les informations sur l'organization courante
             <v-container class="container">
               <v-row>
                 <v-col cols="12" sm="6">
-                  <UiInputText field="collectiveAgreement" :data="entry['collectiveAgreement']"  v-on:update="updateRepository"/>
+                  <UiInputText field="collectiveAgreement" :data="entry['collectiveAgreement']" @update="updateRepository" />
                 </v-col>
 
                 <v-col cols="12" sm="6">
-                  <UiInputEnum field="opca" :data="entry['opca']"  enumType="organization_opca" v-on:update="updateRepository"/>
+                  <UiInputEnum field="opca" :data="entry['opca']" enum-type="organization_opca" @update="updateRepository" />
                 </v-col>
 
                 <v-col cols="12" sm="6">
-                  <UiInputText field="icomNumber" :data="entry['icomNumber']"  v-on:update="updateRepository"/>
+                  <UiInputText field="icomNumber" :data="entry['icomNumber']" @update="updateRepository" />
                 </v-col>
 
                 <v-col cols="12" sm="6">
-                  <UiInputText field="urssafNumber" :data="entry['urssafNumber']"  v-on:update="updateRepository"/>
+                  <UiInputText field="urssafNumber" :data="entry['urssafNumber']" @update="updateRepository" />
                 </v-col>
               </v-row>
             </v-container>
@@ -245,16 +249,16 @@ Contient toutes les informations sur l'organization courante
           <UiExpansionPanel v-if="organizationProfile.isInsideNetwork()" id="network" icon="fa-share-alt">
             <v-container class="container">
               <v-row>
-                <v-col cols="12" sm="6" v-if="organizationProfile.isFfec()">
-                  <UiInputText field="budget" :data="entry['budget']"  v-on:update="updateRepository" type="number"/>
+                <v-col v-if="organizationProfile.isFfec()" cols="12" sm="6">
+                  <UiInputText field="budget" :data="entry['budget']" type="number" @update="updateRepository" />
                 </v-col>
 
-                <v-col cols="12" sm="6" v-if="organizationProfile.isFfec()">
-                  <UiInputCheckbox field="isPedagogicIsPrincipalActivity" :data="entry['isPedagogicIsPrincipalActivity']"  v-on:update="updateRepository"/>
+                <v-col v-if="organizationProfile.isFfec()" cols="12" sm="6">
+                  <UiInputCheckbox field="isPedagogicIsPrincipalActivity" :data="entry['isPedagogicIsPrincipalActivity']" @update="updateRepository" />
                 </v-col>
 
-                <v-col cols="12" sm="6" v-if="organizationProfile.isFfec()">
-                  <UiInputText field="pedagogicBudget" :data="entry['pedagogicBudget']"  v-on:update="updateRepository" type="number"/>
+                <v-col v-if="organizationProfile.isFfec()" cols="12" sm="6">
+                  <UiInputText field="pedagogicBudget" :data="entry['pedagogicBudget']" type="number" @update="updateRepository" />
                 </v-col>
               </v-row>
             </v-container>
@@ -265,23 +269,23 @@ Contient toutes les informations sur l'organization courante
             <v-container class="container">
               <v-row>
                 <v-col cols="12" sm="6">
-                  <UiInputText field="twitter" :data="entry['twitter']"  v-on:update="updateRepository"/>
+                  <UiInputText field="twitter" :data="entry['twitter']" @update="updateRepository" />
                 </v-col>
 
                 <v-col cols="12" sm="6">
-                  <UiInputText field="facebook" :data="entry['facebook']"  v-on:update="updateRepository"/>
+                  <UiInputText field="facebook" :data="entry['facebook']" @update="updateRepository" />
                 </v-col>
 
                 <v-col cols="12" sm="6">
-                  <UiInputText field="instagram" :data="entry['instagram']"  v-on:update="updateRepository"/>
+                  <UiInputText field="instagram" :data="entry['instagram']" @update="updateRepository" />
                 </v-col>
 
                 <v-col cols="12" sm="6">
-                  <UiInputCheckbox field="portailVisibility" :data="entry['portailVisibility']"  v-on:update="updateRepository"/>
+                  <UiInputCheckbox field="portailVisibility" :data="entry['portailVisibility']" @update="updateRepository" />
                 </v-col>
 
                 <v-col cols="12" sm="6">
-                  <UiInputText field="image" :data="entry['image']"  v-on:update="updateRepository"/>
+                  <UiInputText field="image" :data="entry['image']" @update="updateRepository" />
                 </v-col>
               </v-row>
             </v-container>
@@ -294,17 +298,15 @@ Contient toutes les informations sur l'organization courante
                 <v-col cols="12" sm="12">
                   <UiDataTable
                     :query="repositories.bankAccountRepository.query()"
-                    :rootModel="models.Organization"
-                    :rootId="id"
+                    :root-model="models.Organization"
+                    :root-id="id"
                     :model="models.BankAccount"
                     :headers="datatableHeaders.headersBankAccount"
-                  >
-                  </UiDataTable>
+                  />
                 </v-col>
               </v-row>
             </v-container>
           </UiExpansionPanel>
-
         </v-expansion-panels>
       </template>
     </UiForm>
@@ -312,22 +314,23 @@ Contient toutes les informations sur l'organization courante
 </template>
 
 <script lang="ts">
-import {defineComponent, useContext} from '@nuxtjs/composition-api'
-import {$organizationProfile} from "~/services/profile/organizationProfile";
-import {Organization} from '@/models/Organization/Organization'
-import {OrganizationAddressPostal} from "~/models/Organization/OrganizationAddressPostal";
-import {ContactPoint} from "~/models/Core/ContactPoint";
-import {BankAccount} from "~/models/Core/BankAccount";
-import {repositoryHelper} from "~/services/store/repository";
-import UseValidator from "~/use/form/useValidator";
-import {UseNavigationHelpers} from "~/use/form/useNavigationHelpers";
+import { defineComponent, useContext } from '@nuxtjs/composition-api'
+import { $organizationProfile } from '~/services/profile/organizationProfile'
+import { Organization } from '@/models/Organization/Organization'
+import { OrganizationAddressPostal } from '~/models/Organization/OrganizationAddressPostal'
+import { ContactPoint } from '~/models/Core/ContactPoint'
+import { BankAccount } from '~/models/Core/BankAccount'
+import { repositoryHelper } from '~/services/store/repository'
+import UseValidator from '~/use/form/useValidator'
+import { UseNavigationHelpers } from '~/use/form/useNavigationHelpers'
+import I18N from '~/services/utils/i18n'
 
 export default defineComponent({
   name: 'OrganizationParent',
-  setup() {
-    const { store, app: {i18n}, $dataProvider } = useContext()
+  setup () {
+    const { store, app: { i18n }, $dataProvider } = useContext()
     const organizationProfile = $organizationProfile(store)
-    const id: number = store.state.profile.organization.id;
+    const id: number = store.state.profile.organization.id
 
     const repositories = getRepositories()
 
@@ -335,8 +338,7 @@ export default defineComponent({
 
     const checkSiretHook = async (siret: string, field: string, updateRepository: any) => {
       await checkSiret(siret)
-      if(!siretError.value)
-        updateRepository(siret, field);
+      if (!siretError.value) { updateRepository(siret, field) }
     }
 
     const { panel } = UseNavigationHelpers.expansionPanels()
@@ -354,9 +356,14 @@ export default defineComponent({
       panel
     }
   },
+  methods: {
+    formatPhoneNumber (number: string): string {
+      return I18N.formatPhoneNumber(number)
+    }
+  }
 })
 
-function getRules(i18n: any) {
+function getRules (i18n: any) {
   return {
     nameRules: [
       (nameValue: string) => !!nameValue || i18n.t('required'),
@@ -368,29 +375,29 @@ function getRules(i18n: any) {
   }
 }
 
-function getDataTablesHeaders(i18n: any) {
+function getDataTablesHeaders (i18n: any) {
   return {
     headersContactPoint: [
-      {text: i18n.t('email'), value: 'email'},
-      {text: i18n.t('telphone'), value: 'telphone'},
-      {text: i18n.t('mobilPhone'), value: 'mobilPhone'},
-      {text: i18n.t('actions'), value: 'actions', sortable: false},
+      { text: i18n.t('email'), value: 'email' },
+      { text: i18n.t('telphone'), value: 'telphone' },
+      { text: i18n.t('mobilPhone'), value: 'mobilPhone' },
+      { text: i18n.t('actions'), value: 'actions', sortable: false }
     ],
     headersBankAccount: [
-      {text: i18n.t('bankName'), value: 'bankName'},
-      {text: i18n.t('iban'), value: 'iban'},
-      {text: i18n.t('bic'), value: 'bic'},
-      {text: i18n.t('actions'), value: 'actions', sortable: false},
+      { text: i18n.t('bankName'), value: 'bankName' },
+      { text: i18n.t('iban'), value: 'iban' },
+      { text: i18n.t('bic'), value: 'bic' },
+      { text: i18n.t('actions'), value: 'actions', sortable: false }
     ],
     headersAddressPostal: [
-      {text: i18n.t('address_postal_type'), value: 'type'},
-      {text: i18n.t('address'), value: 'address'},
-      {text: i18n.t('actions'), value: 'actions', sortable: false},
+      { text: i18n.t('address_postal_type'), value: 'type' },
+      { text: i18n.t('address'), value: 'address' },
+      { text: i18n.t('actions'), value: 'actions', sortable: false }
     ]
   }
 }
 
-function getRepositories() {
+function getRepositories () {
   return {
     organizationRepository: repositoryHelper.getRepository(Organization),
     contactPointRepository: repositoryHelper.getRepository(ContactPoint),

+ 8 - 0
services/utils/i18n.ts

@@ -0,0 +1,8 @@
+import { parsePhoneNumber } from 'libphonenumber-js'
+
+export default class I18N {
+  static formatPhoneNumber (number: string): string {
+    const parsed = parsePhoneNumber(number)
+    return parsed ? parsed.formatNational() : ''
+  }
+}

+ 5 - 0
yarn.lock

@@ -7966,6 +7966,11 @@ levn@~0.3.0:
     prelude-ls "~1.1.2"
     type-check "~0.3.2"
 
+libphonenumber-js@^1.9.39:
+  version "1.9.39"
+  resolved "https://registry.yarnpkg.com/libphonenumber-js/-/libphonenumber-js-1.9.39.tgz#af6407167d5446758da795412d082eeb3e005ba2"
+  integrity sha512-TxYz/Ii7mjkocKGKmFHhsTAvvcxr4AY3yUlZzZ2z7HC4DPRrNlzJ9n32/SMogqsyFOXLMXQPCkCInNRbiVaEPA==
+
 lines-and-columns@^1.1.6:
   version "1.1.6"
   resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00"