Kaynağa Gözat

Merge branch 'master' into release/2.6.1

Olivier Massot 3 ay önce
ebeveyn
işleme
0ba5b1195f

+ 2 - 0
.gitignore

@@ -34,3 +34,5 @@ coverage/
 models/models.ts
 
 .maintenance
+
+config/abilities/config-precompiled.ts

+ 1 - 1
components/Layout/Header/Menu.vue

@@ -93,7 +93,7 @@ header principal (configuration, paramètres du compte...)
 <script setup lang="ts">
 import { computed, ref } from 'vue'
 import { useMenu } from '~/composables/layout/useMenu'
-import {IMAGE_SIZE} from "~/types/enum/enums";
+import { IMAGE_SIZE } from '~/types/enum/enums'
 
 const props = defineProps({
   name: {

+ 1 - 1
components/Ui/EventList.vue

@@ -93,7 +93,7 @@ import type { Collection } from 'pinia-orm'
 import type Event from '~/models/Freemium/Event'
 import type { Pagination } from '~/types/data'
 import { useDate } from 'vuetify'
-import {IMAGE_SIZE} from "~/types/enum/enums";
+import { IMAGE_SIZE } from '~/types/enum/enums'
 
 const props = defineProps<{
   events: Collection<Event>

+ 0 - 2
config/abilities/config.yaml

@@ -1,2 +0,0 @@
-abilities: !!import/shallow
-  - pages/

+ 1 - 1
i18n/lang/fr/general.json

@@ -831,7 +831,7 @@
   "placeListMenuKey": "Lieu",
   "information": "Information",
   "refresh_needed": "Actualisation requise",
-  "refresh_needed_message": "La page a besoin d'être actualisée pour afficher les dernières modifications.",
+  "refresh_needed_message": "Le profil de l’utilisateur a été modifié, un rechargement de la page est requis.",
   "refresh_page": "Actualiser la page",
   "helloasso_presentation": "HelloAsso aide les associations à collecter des paiements en ligne et propose ses services gratuitement. Elle prend à sa charge tous les frais de transaction pour que vous puissiez bénéficier de la totalité des sommes versées par vos publics, sans frais. Les contributions volontaires laissées par ces derniers sont leur unique source de revenus.",
   "connect_to_helloasso": "Connecter à HelloAsso",

+ 88 - 0
prepare/compileAbilitiesConfig.ts

@@ -0,0 +1,88 @@
+/**
+ * Precompile the abilities config from Yaml to TS
+ */
+
+import * as fs from 'fs'
+import * as path from 'path'
+import * as yaml from 'js-yaml'
+
+interface AbilityCondition {
+  function: string
+  parameters?: unknown[]
+  expectedResult?: boolean
+}
+
+interface AbilityConfig {
+  action: string
+  conditions: AbilityCondition[]
+}
+
+interface CompiledAbilities {
+  [key: string]: AbilityConfig
+}
+
+function loadYamlFile(filePath: string): unknown {
+  try {
+    const fileContents = fs.readFileSync(filePath, 'utf8')
+    return yaml.load(fileContents)
+  } catch (error) {
+    console.error(`Error loading YAML file ${filePath}:`, error)
+    return {}
+  }
+}
+
+function compileAbilitiesConfig(): void {
+  const configDir = path.join(process.cwd(), 'config/abilities/pages')
+  const outputPath = path.join(
+    process.cwd(),
+    'config/abilities/config-precompiled.ts',
+  )
+
+  console.log('Starting abilities config compilation...')
+
+  // Read all YAML files from the pages directory
+  const yamlFiles = fs
+    .readdirSync(configDir)
+    .filter((file) => file.endsWith('.yaml'))
+  const compiledAbilities: CompiledAbilities = {}
+
+  yamlFiles.forEach((file) => {
+    const filePath = path.join(configDir, file)
+    console.log(`Processing ${file}...`)
+
+    const config = loadYamlFile(filePath)
+
+    // Merge all abilities from this file into the compiled config
+    Object.assign(compiledAbilities, config)
+  })
+
+  // Generate TypeScript content
+  const header = `/**
+ * AUTO-GENERATED FILE - DO NOT MODIFY MANUALLY
+ *
+ * This file is automatically generated from YAML configuration files
+ * in config/abilities/pages/ directory.
+ *
+ * To make changes, edit the source YAML files and run the compilation script :
+ *     yarn prepare
+ *
+ * Generated on: ${new Date().toISOString()}
+ */
+
+`
+
+  const tsContent = `${header}export default ${JSON.stringify(compiledAbilities, null, 2)} as const
+`
+
+  // Write the compiled TypeScript file
+  fs.writeFileSync(outputPath, tsContent, 'utf8')
+
+  console.log(`✓ Abilities config compiled successfully to ${outputPath}`)
+  console.log(`✓ Processed ${yamlFiles.length} YAML files`)
+  console.log(
+    `✓ Generated ${Object.keys(compiledAbilities).length} ability definitions`,
+  )
+}
+
+// Run the compilation
+compileAbilitiesConfig()

+ 3 - 1
services/layout/menuBuilder/websiteListMenuBuilder.ts

@@ -10,6 +10,8 @@ import type { BaseOrganizationProfile } from '~/types/interfaces'
 export default class WebsiteListMenuBuilder extends AbstractMenuBuilder {
   static override readonly menuName = 'WebsiteList'
 
+  static OPENTALENT_MANAGER_ID = 93931
+
   /**
    * Construit le menu Site internet, ou null si aucune page accessible
    */
@@ -36,7 +38,7 @@ export default class WebsiteListMenuBuilder extends AbstractMenuBuilder {
           parent.id &&
           parent.name &&
           parent.website &&
-          parent.id !== this.runtimeConfig.OPENTALENT_MANAGER_ID
+          parent.id !== WebsiteListMenuBuilder.OPENTALENT_MANAGER_ID
         ) {
           children.push(
             this.createItem(

+ 2 - 7
services/rights/abilityBuilder.ts

@@ -1,10 +1,10 @@
-import * as yaml from 'yaml-import'
 import * as _ from 'lodash-es'
 import type { MongoAbility } from '@casl/ability/dist/types/Ability'
 import RoleUtils from '~/services/rights/roleUtils'
 import type { AbilitiesType, AccessProfile } from '~/types/interfaces'
 import type { ABILITIES } from '~/types/enum/enums'
 import type OrganizationProfile from '~/models/Organization/OrganizationProfile'
+import abilitiesConfig from '~/config/abilities/config-precompiled'
 
 interface ConditionParameters {
   action: string
@@ -25,8 +25,6 @@ class AbilityBuilder {
   private readonly accessProfile: AccessProfile
   private readonly organizationProfile: OrganizationProfile
 
-  private readonly configFile = './config/abilities/config.yaml'
-
   private abilities: Array<AbilitiesType> = []
 
   /**
@@ -73,11 +71,8 @@ class AbilityBuilder {
   buildAbilitiesFromConfig() {
     const abilitiesByConfig: Array<AbilitiesType> = []
 
-    const doc = yaml.read(this.configFile)
-    const fromConfig = doc.abilities
-
     _.each(
-      fromConfig,
+      abilitiesConfig,
       (
         ability: { action: ABILITIES; conditions: Array<Condition> },
         subject: string,

+ 1 - 1
tests/units/services/layout/menuBuilder/websiteListMenuBuilder.test.ts

@@ -117,7 +117,7 @@ describe('build', () => {
       { id: 3, name: 'parent3', website: 'https://parent3.net' },
     ]
 
-    runtimeConfig.OPENTALENT_MANAGER_ID = 3
+    WebsiteListMenuBuilder.OPENTALENT_MANAGER_ID = 3
 
     const result = menuBuilder.build() as MenuGroup