11641164 </div >
11651165 <Addons :addons =" addons" :appname =" name" />
11661166
1167+ <!-- ENV VAR OVERLAP DIALOG -->
1168+ <v-dialog v-model =" envOverlapDialog" max-width =" 800px" persistent >
1169+ <v-card >
1170+ <v-card-title class =" headline" >
1171+ {{ $t("app.form.envVarConflicts") }}
1172+ </v-card-title >
1173+ <v-card-text >
1174+ <p class =" mb-4" >
1175+ {{ $t("app.form.envVarConflictsDescription") }}
1176+ </p >
1177+ <v-data-table
1178+ v-model =" selectedOverlaps"
1179+ :headers =" overlapHeaders"
1180+ :items =" envOverlaps"
1181+ item-value =" name"
1182+ show-select
1183+ >
1184+ <template v-slot :item .oldValue =" { item } " >
1185+ <code class =" text-caption" >{{ item.oldValue }}</code >
1186+ </template >
1187+ <template v-slot :item .newValue =" { item } " >
1188+ <code class =" text-caption" >{{ item.newValue }}</code >
1189+ </template >
1190+ </v-data-table >
1191+ </v-card-text >
1192+ <v-card-actions >
1193+ <v-spacer ></v-spacer >
1194+ <v-btn variant =" text" @click =" cancelOverlapDialog" >
1195+ {{ $t("global.cancel") }}
1196+ </v-btn >
1197+ <v-btn color =" primary" @click =" applyOverlapChanges" >
1198+ {{ $t("global.applyChanges") }}
1199+ </v-btn >
1200+ </v-card-actions >
1201+ </v-card >
1202+ </v-dialog >
1203+
11671204 <!-- SUBMIT -->
11681205 <v-row class =" pt-5" >
11691206 <v-col cols =" 12" md =" 4" >
@@ -1194,8 +1231,8 @@ import axios from "axios";
11941231import Addons from " ./addons.vue" ;
11951232import { defineComponent } from " vue" ;
11961233import { useKuberoStore } from " ../../stores/kubero" ;
1197- import { mapState } from " pinia" ;
11981234import Breadcrumbs from " ../breadcrumbs.vue" ;
1235+ import Swal from " sweetalert2" ;
11991236
12001237type App = {
12011238 name: string ;
@@ -1668,6 +1705,11 @@ export default defineComponent({
16681705 timeoutSeconds: 3 ,
16691706 periodSeconds: 10 ,
16701707 },
1708+ // Environment variable overlap dialog state
1709+ envOverlapDialog: false ,
1710+ envOverlaps: [] as { name: string ; oldValue: string ; newValue: string }[],
1711+ selectedOverlaps: [] as string [],
1712+ pendingEnvVars: [] as EnvVar [],
16711713 nameRules: [
16721714 (v : any ) => !! v || " Name is required" ,
16731715 (v : any ) => v .length <= 60 || " Name must be less than 60 characters" ,
@@ -1721,6 +1763,13 @@ export default defineComponent({
17211763 const store = useKuberoStore ();
17221764 return store .kubero ;
17231765 },
1766+ overlapHeaders() {
1767+ return [
1768+ { title: this .$t (' app.form.variableName' ), key: ' name' },
1769+ { title: this .$t (' app.form.currentValue' ), key: ' oldValue' },
1770+ { title: this .$t (' app.form.newValue' ), key: ' newValue' },
1771+ ];
1772+ },
17241773 },
17251774 watch: {
17261775 advanced(newValue ) {
@@ -2555,6 +2604,10 @@ export default defineComponent({
25552604 },
25562605 parseEnvFile(text : any ) {
25572606 const lines = text .split (" \n " );
2607+ const newEnvVars: EnvVar [] = [];
2608+ const overlaps: { name: string ; oldValue: string ; newValue: string }[] =
2609+ [];
2610+
25582611 for (const line of lines ) {
25592612 const trimmedLine = line .trim ();
25602613 // Skip empty lines and comments
@@ -2573,10 +2626,51 @@ export default defineComponent({
25732626 // Remove quotes if present
25742627 const cleanValue = value .replace (/ ^ ["'] | ["'] $ / g , " " );
25752628
2576- if (name && ! this .envVars .some ((envVar ) => envVar .name === name )) {
2577- this .envVars .push ({ name , value: cleanValue });
2629+ if (name ) {
2630+ const existingVar = this .envVars .find (
2631+ (envVar ) => envVar .name === name
2632+ );
2633+ if (existingVar ) {
2634+ // skip if value is the same
2635+ if (existingVar .value === cleanValue ) {
2636+ continue ;
2637+ }
2638+
2639+ // Found overlap - add to overlaps list
2640+ overlaps .push ({
2641+ name ,
2642+ oldValue: existingVar .value ,
2643+ newValue: cleanValue ,
2644+ });
2645+ } else {
2646+ // No overlap - can add directly
2647+ newEnvVars .push ({ name , value: cleanValue });
2648+ }
25782649 }
25792650 }
2651+
2652+ // Add non-overlapping variables immediately
2653+ this .envVars .push (... newEnvVars );
2654+
2655+ // If there are overlaps, show dialog
2656+ if (overlaps .length > 0 ) {
2657+ this .envOverlaps = overlaps ;
2658+ this .selectedOverlaps = overlaps .map ((overlap ) => overlap .name ); // Default all selected
2659+ this .envOverlapDialog = true ;
2660+ } else if (newEnvVars .length === 0 ) {
2661+ // Show notification if no new environment variables were found
2662+ Swal .fire ({
2663+ toast: true ,
2664+ position: ' top-end' ,
2665+ showConfirmButton: false ,
2666+ timer: 3000 ,
2667+ timerProgressBar: true ,
2668+ icon: ' info' ,
2669+ title: this .$t (' app.form.noNewEnvVarsFound' ),
2670+ background: " rgb(var(--v-theme-cardBackground))" ,
2671+ color: " rgba(var(--v-theme-on-background),var(--v-high-emphasis-opacity))" ,
2672+ });
2673+ }
25802674 },
25812675 addVolumeLine() {
25822676 this .extraVolumes .push ({
@@ -2632,6 +2726,30 @@ export default defineComponent({
26322726 });
26332727 return cronjobs ;
26342728 },
2729+ // Environment variable overlap dialog methods
2730+ cancelOverlapDialog() {
2731+ this .envOverlapDialog = false ;
2732+ this .envOverlaps = [];
2733+ this .selectedOverlaps = [];
2734+ },
2735+ applyOverlapChanges() {
2736+ // Update existing environment variables with selected new values
2737+ for (const overlap of this .envOverlaps ) {
2738+ if (this .selectedOverlaps .includes (overlap .name )) {
2739+ const existingVar = this .envVars .find (
2740+ (envVar ) => envVar .name === overlap .name
2741+ );
2742+ if (existingVar ) {
2743+ existingVar .value = overlap .newValue ;
2744+ }
2745+ }
2746+ }
2747+
2748+ // Close dialog and reset state
2749+ this .envOverlapDialog = false ;
2750+ this .envOverlaps = [];
2751+ this .selectedOverlaps = [];
2752+ },
26352753 },
26362754});
26372755 </script >
0 commit comments