Skip to content

Commit 910ac40

Browse files
authored
Merge pull request #12 from Libertech-FR/extensions
Extensions
2 parents 590bf14 + 69a5c4c commit 910ac40

File tree

12 files changed

+279
-153
lines changed

12 files changed

+279
-153
lines changed

a faire.md

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
cycle de vie enum dynamique,
2+
en dur ACTIVE devient OFFICIAL, INACTIF, MANUEL
3+
les autres sont par defaut
4+
5+
ficher default cycle de vie:
6+
En Attente = supannRessourceEtat : {COMPTE} A SupannAnticipe
7+
OFFI = supannRessourceEtat : {COMPTE} A SupannActif
8+
PROV = supannResourceEtat : {COMTE} A SupannSursis et supannRessourceEtatDate: Date de passage en PROV
9+
INACTIF = supannRessourceEtat : {COMPTE} I SupannInactif
10+
A Détruire = supannRessourceEtat : {COMPTE} I SupannSupprCompte
11+
Vérouillé = supannRessourceEtat : {COMPTE} S SupannVerrouille
12+
13+
trigger devient un nombre positif / dernier etat superieur a x jours
14+
ajouter une clé mutation
15+
16+
17+
voir le diff des modifs

extensions/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
*
2+
!.gitignore

nuxt.config.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import openapiTS from 'openapi-typescript'
55
import { defineNuxtConfig } from 'nuxt/config'
66
import { parse } from 'yaml'
77
import * as consola from 'consola'
8+
import setupApp from './src/server/extension.setup'
89

910
const SESAME_APP_API_URL = process.env.SESAME_APP_API_URL || 'http://localhost:4002'
1011
const SESAME_ALLOWED_HOSTS = process.env.SESAME_ALLOWED_HOSTS ? process.env.SESAME_ALLOWED_HOSTS.split(',') : []
@@ -65,6 +66,7 @@ export default defineNuxtConfig({
6566
appConfig: {
6667
baseUrl: SESAME_APP_API_URL,
6768
appManagerVersion: process.env.npm_package_version,
69+
customSlots: {},
6870
},
6971
modules: [
7072
'@nuxt-alt/auth',
@@ -76,6 +78,7 @@ export default defineNuxtConfig({
7678
'dayjs-nuxt',
7779
'@nuxt/devtools',
7880
'nuxt-monaco-editor',
81+
...setupApp(),
7982
],
8083
auth: {
8184
globalMiddleware: true,

package.json

Lines changed: 42 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -14,58 +14,59 @@
1414
"lint:fix": "eslint --ext .ts,.js,.vue --ignore-path .gitignore . --fix"
1515
},
1616
"dependencies": {
17-
"@jsonforms/core": "^3.2.1",
18-
"@jsonforms/vue": "^3.2.1",
19-
"@jsonforms/vue-vanilla": "^3.2.1",
20-
"@nuxt-alt/auth": "^3.1.6",
17+
"@jsonforms/core": "^3.6.0",
18+
"@jsonforms/vue": "^3.6.0",
19+
"@jsonforms/vue-vanilla": "^3.6.0",
20+
"@nuxt-alt/auth": "^3.1.7",
2121
"@nuxt-alt/http": "^1.7.10",
2222
"@nuxt-alt/proxy": "^2.5.8",
23-
"@nyariv/sandboxjs": "^0.8.23",
24-
"@pinia/nuxt": "^0.5.1",
25-
"@quasar/extras": "^1.16.9",
26-
"@vueuse/router": "^10.7.2",
23+
"@nyariv/sandboxjs": "^0.8.25",
24+
"@pinia/nuxt": "^0.11.2",
25+
"@quasar/extras": "^1.17.0",
26+
"@vueuse/router": "^13.9.0",
2727
"ajv": "^8.17.1",
2828
"ajv-errors": "^3.0.0",
2929
"ajv-i18n": "^4.2.0",
30-
"cookie": "^0.6.0",
30+
"cookie": "^1.0.2",
3131
"fast-password-entropy": "^1.1.1",
32-
"hibp": "^14.1.2",
32+
"hibp": "^15.0.1",
3333
"moment": "^2.30.1",
34-
"monaco-editor": "^0.52.2",
35-
"openapi-fetch": "^0.8.2",
36-
"pinia": "^2.1.7",
34+
"monaco-editor": "^0.53.0",
35+
"openapi-fetch": "^0.14.0",
36+
"pinia": "^3.0.3",
3737
"qs": "^6.14.0",
38-
"quasar": "^2.15.4",
39-
"radash": "^12.1.0",
40-
"reconnecting-eventsource": "^1.6.2",
41-
"sass": "^1.70.0",
42-
"vue-eslint-parser": "^9.4.2",
43-
"yaml": "^2.4.2"
38+
"quasar": "^2.18.2",
39+
"radash": "^12.1.1",
40+
"reconnecting-eventsource": "^1.6.4",
41+
"sass": "^1.92.1",
42+
"vue-eslint-parser": "^10.2.0",
43+
"yaml": "^2.8.1"
4444
},
4545
"devDependencies": {
46-
"@nuxt/devtools": "^1.3.9",
47-
"@nuxt/eslint-config": "^0.2.0",
48-
"@types/node": "^18.17.3",
49-
"@typescript-eslint/eslint-plugin": "^6.19.1",
50-
"@typescript-eslint/parser": "^6.19.1",
51-
"@vue/language-plugin-pug": "^1.8.27",
52-
"@vueuse/core": "^10.7.2",
53-
"@vueuse/nuxt": "^10.7.2",
54-
"dayjs-nuxt": "^2.1.9",
55-
"eslint": "^8.56.0",
56-
"memfs": "^4.8.2",
57-
"nuxt": "^3.16.0",
58-
"nuxt-monaco-editor": "^1.3.2",
59-
"nuxt-quasar-ui": "^2.0.7",
60-
"openapi-typescript": "^6.7.4",
61-
"prettier": "^3.2.4",
62-
"typescript": "^5.3.3",
63-
"vite-plugin-pug": "^0.3.2",
64-
"vue": "^3.4.14",
65-
"vue-router": "^4.2.5",
66-
"vue-tsc": "^1.8.27"
46+
"@nuxt/devtools": "^2.6.3",
47+
"@nuxt/eslint-config": "^1.9.0",
48+
"@types/node": "^24.4.0",
49+
"@typescript-eslint/eslint-plugin": "^8.43.0",
50+
"@typescript-eslint/parser": "^8.43.0",
51+
"@vue/language-plugin-pug": "^3.0.7",
52+
"@vueuse/core": "^13.9.0",
53+
"@vueuse/nuxt": "^13.9.0",
54+
"dayjs-nuxt": "^2.1.11",
55+
"eslint": "^9.35.0",
56+
"memfs": "^4.39.0",
57+
"nuxt": "^4.1.2",
58+
"nuxt-monaco-editor": "^1.4.0",
59+
"nuxt-quasar-ui": "^2.1.13",
60+
"openapi-typescript": "^7.9.1",
61+
"prettier": "^3.6.2",
62+
"typescript": "^5.9.2",
63+
"vite-plugin-pug": "^0.4.1",
64+
"vue": "^3.5.21",
65+
"vue-router": "^4.5.1",
66+
"vue-tsc": "^3.0.7"
6767
},
6868
"resolutions": {
6969
"string-width": "^1.0.2 || 2 || 3 || 4"
70-
}
70+
},
71+
"packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"
7172
}

src/components/hook.vue

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<template lang="pug">
2+
div(:id='"tk-hook:" + name')
3+
template(v-for="(customSlot, key) in customSlots")
4+
pre.bg-red.text-white(v-if='debug' v-html="JSON.stringify({name, customSlot, data}, null, 2)")
5+
component(
6+
v-if='customSlot.componentName'
7+
:key='key'
8+
:is="customSlot.componentName"
9+
v-bind="{...customSlot.data, ...data}"
10+
)
11+
</template>
12+
13+
<script lang="ts" setup>
14+
import { useAppConfig } from '#imports'
15+
import { sort } from 'radash'
16+
17+
//TODO: Convert to a sdk repository and publish it on npm for 3rd-party extensions
18+
interface CustomSlotInterface {
19+
componentName: string
20+
priority?: number
21+
data?: Record<string, any>
22+
}
23+
24+
const props = defineProps({
25+
name: {
26+
type: String,
27+
required: true,
28+
},
29+
data: {
30+
type: Object,
31+
default: () => ({}),
32+
},
33+
debug: {
34+
type: Boolean,
35+
default: false,
36+
},
37+
})
38+
39+
const config = useAppConfig()
40+
const customSlots = computed(() => {
41+
if (config.customSlots.hasOwnProperty(props.name)) {
42+
const configCustomSlots = config.customSlots as Record<string, CustomSlotInterface[]>
43+
return sort(configCustomSlots[props.name], (list: CustomSlotInterface) => list.priority || 0, true)
44+
}
45+
})
46+
</script>

src/components/identityForm/actions.vue

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,26 @@ div.flex
5252

5353
q-separator(v-if="props.identity?._id" size='3px' vertical)
5454

55+
div(ref='targetEl' style='display: height: 36px;')
56+
q-tooltip.text-body2(:target="targetEl" anchor="top middle" self="bottom middle") État du cycle de vie : {{ stateName }}
57+
q-btn-dropdown.q-pl-sm.full-height(icon='mdi-clock' color='purple-8' square unelevated dense)
58+
q-list
59+
q-item(
60+
v-for='stateItem in stateList' :key='stateItem.key'
61+
@click="switchLifecycle(stateItem.key)"
62+
:active='stateItem.key === props.identity.lifecycle'
63+
active-class="bg-purple-8 text-white"
64+
clickable v-close-popup
65+
)
66+
q-item-section(avatar)
67+
q-icon(:name="stateItem.icon || 'mdi-help-rhombus-outline'" :color="stateItem.color")
68+
q-item-section
69+
q-item-label
70+
span(v-text='stateItem.label')
71+
| &nbsp;
72+
small(v-text='("(" + stateItem.key + ")")')
73+
q-separator(size='3px' vertical)
74+
5575
q-btn-dropdown.text-white(v-if="props.identity?._id" dropdown-icon="mdi-dots-vertical" style='background-color: rgba(0, 0, 0, .6)' padding='5px 10px' dense no-caps)
5676
q-list
5777
a(:href="'/jobs?filters[:concernedTo.id]=' + props.identity?._id" target="_blank" style='text-decoration: none; color: inherit' @click.prevent="dialogLog = true")
@@ -128,6 +148,7 @@ import InputNewPassword from '~/components/inputNewPassword.vue'
128148
const resetPasswordModal = ref(false)
129149
const forcePasswordModal = ref(false)
130150
151+
const targetEl = ref()
131152
const newpassword = ref('')
132153
type IdentityResponse = operations['IdentitiesController_search']['responses']['200']['content']['application/json']
133154
type Identity = components['schemas']['IdentitiesDto']
@@ -157,6 +178,7 @@ const props = defineProps({
157178
const $q = useQuasar()
158179
const router = useRouter()
159180
const { getStateColor, getStateName } = useIdentityStates()
181+
const { getLifecycleColor, getLifecycleName, getLifecycleIcon, stateList } = await useIdentityLifecycles()
160182
const { handleError } = useErrorHandling()
161183
162184
const emits = defineEmits(['submit', 'sync', 'logs', 'create', 'delete'])
@@ -166,6 +188,27 @@ const validationsModal = ref(false)
166188
const dialogLog = ref(false)
167189
const dialogLifecycle = ref(false)
168190
191+
async function switchLifecycle(lifecycle: string) {
192+
const requestOptions = { method: 'POST', body: JSON.stringify({ lifecycle }) }
193+
try {
194+
const data = await $http.patch(`/management/identities/${props.identity._id}/lifecycle`, requestOptions)
195+
$q.notify({
196+
message: 'Le cycle de vie a été mis à jour : ' + data._data?.data?.lifecycle,
197+
color: 'positive',
198+
position: 'top-right',
199+
icon: 'mdi-check-circle-outline',
200+
})
201+
props?.refreshTarget(props.identity)
202+
} catch (error) {
203+
$q.notify({
204+
message: 'Impossible de modifier le cycle de vie : ' + error.response._data.message,
205+
color: 'negative',
206+
position: 'top-right',
207+
icon: 'mdi-alert-circle-outline',
208+
})
209+
}
210+
}
211+
169212
async function doChangePassword() {
170213
const requestOptions = { method: 'POST', body: JSON.stringify({ id: props.identity._id, newPassword: newpassword.value }) }
171214
try {
@@ -346,11 +389,26 @@ const stateName = computed(() => {
346389
return getStateName(state)
347390
})
348391
392+
const lifecycleName = computed(() => {
393+
const lifecycle = props.identity?.lifecycle
394+
return getLifecycleName(lifecycle)
395+
})
396+
349397
const stateColor = computed(() => {
350398
const state = props.identity?.state
351399
return getStateColor(state)
352400
})
353401
402+
const lifecycleColor = computed(() => {
403+
const lifecycle = props.identity?.lifecycle
404+
return getLifecycleColor(lifecycle)
405+
})
406+
407+
const lifecycleIcon = computed(() => {
408+
const lifecycle = props.identity?.lifecycle
409+
return getLifecycleIcon(lifecycle)
410+
})
411+
354412
async function sync() {
355413
emits('sync')
356414
}

src/components/table/state-col.vue

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
<template lang="pug">
22
q-td
33
q-icon(:name="stateInfo.icon" :color="stateInfo.color" :style='{color: stateInfo.color.startsWith("#") ? stateInfo.color : "inherit"}' :class="`q-mr-md`")
4-
q-tooltip.text-body2(slot="trigger") Etat : {{ stateInfo.name }}
5-
q-icon(:name="initStateInfo.icon" :color="initStateInfo.color" :style='{color: initStateInfo.color.startsWith("#") ? initStateInfo.color : "inherit"}' :class="`q-mr-md`")
6-
q-tooltip.text-body2(slot="trigger") Initialisation du compte : {{ initStateInfo.name }}
7-
q-icon(:name="lifecycleInfo.icon" :color="lifecycleInfo.color" :style='{color: lifecycleInfo.color.startsWith("#") ? lifecycleInfo.color : "inherit"}' :class="`q-mr-md`")
8-
q-tooltip.text-body2(slot="trigger") Cycle de vie : {{ lifecycleInfo.name }}
4+
q-tooltip.text-body2(slot="trigger") Etat : {{ stateInfo.name }} ({{ stateInfo.value || '?' }})
5+
q-icon(:name="initStateInfo.icon" :color="initStateInfo.color" :style='{color: initStateInfo.color?.startsWith("#") ? initStateInfo.color : "inherit"}' :class="`q-mr-md`")
6+
q-tooltip.text-body2(slot="trigger") Initialisation du compte : {{ initStateInfo.name }} ({{ initStateInfo.value || '?' }})
7+
q-icon(:name="lifecycleInfo.icon" :color="lifecycleInfo.color" :style='{color: lifecycleInfo.color?.startsWith("#") ? lifecycleInfo.color : "inherit"}' :class="`q-mr-md`")
8+
q-tooltip.text-body2(slot="trigger") Cycle de vie : {{ lifecycleInfo.name }} ({{ lifecycleInfo.value || '?' }})
99
</template>
1010

1111
<script lang="ts" setup>
@@ -16,7 +16,7 @@ import type { PropType } from 'vue'
1616
import { useIdentityStates, useIdentityLifecycles, useIdentityInitStates } from '~/composables'
1717
const { getStateColor, getStateName, getStateInfos } = useIdentityStates()
1818
const { getInitStateColor, getInitStateName, getInitStateInfos } = useIdentityInitStates()
19-
const { getLifecycleColor, getLifecycleName, getLifecycleInfos } = useIdentityLifecycles()
19+
const { getLifecycleColor, getLifecycleName, getLifecycleInfos } = await useIdentityLifecycles()
2020
2121
const props = defineProps({
2222
identity: {

0 commit comments

Comments
 (0)