diff --git a/app/Livewire/SharedVariables/Environment/Show.php b/app/Livewire/SharedVariables/Environment/Show.php
index bee757a64..6c8342c41 100644
--- a/app/Livewire/SharedVariables/Environment/Show.php
+++ b/app/Livewire/SharedVariables/Environment/Show.php
@@ -19,7 +19,11 @@ class Show extends Component
public array $parameters;
- protected $listeners = ['refreshEnvs' => '$refresh', 'saveKey', 'environmentVariableDeleted' => '$refresh'];
+ public string $view = 'normal';
+
+ public ?string $variables = null;
+
+ protected $listeners = ['refreshEnvs' => 'refreshEnvs', 'saveKey', 'environmentVariableDeleted' => 'refreshEnvs'];
public function saveKey($data)
{
@@ -39,6 +43,7 @@ public function saveKey($data)
'team_id' => currentTeam()->id,
]);
$this->environment->refresh();
+ $this->getDevView();
} catch (\Throwable $e) {
return handleError($e, $this);
}
@@ -49,6 +54,116 @@ public function mount()
$this->parameters = get_route_parameters();
$this->project = Project::ownedByCurrentTeam()->where('uuid', request()->route('project_uuid'))->firstOrFail();
$this->environment = $this->project->environments()->where('uuid', request()->route('environment_uuid'))->firstOrFail();
+ $this->getDevView();
+ }
+
+ public function switch()
+ {
+ $this->view = $this->view === 'normal' ? 'dev' : 'normal';
+ $this->getDevView();
+ }
+
+ public function getDevView()
+ {
+ $this->variables = $this->formatEnvironmentVariables($this->environment->environment_variables->sortBy('key'));
+ }
+
+ private function formatEnvironmentVariables($variables)
+ {
+ return $variables->map(function ($item) {
+ if ($item->is_shown_once) {
+ return "$item->key=(Locked Secret, delete and add again to change)";
+ }
+ if ($item->is_multiline) {
+ return "$item->key=(Multiline environment variable, edit in normal view)";
+ }
+
+ return "$item->key=$item->value";
+ })->join("\n");
+ }
+
+ public function submit()
+ {
+ try {
+ $this->authorize('update', $this->environment);
+ $this->handleBulkSubmit();
+ $this->getDevView();
+ } catch (\Throwable $e) {
+ return handleError($e, $this);
+ } finally {
+ $this->refreshEnvs();
+ }
+ }
+
+ private function handleBulkSubmit()
+ {
+ $variables = parseEnvFormatToArray($this->variables);
+ $changesMade = false;
+
+ // Delete removed variables
+ $deletedCount = $this->deleteRemovedVariables($variables);
+ if ($deletedCount > 0) {
+ $changesMade = true;
+ }
+
+ // Update or create variables
+ $updatedCount = $this->updateOrCreateVariables($variables);
+ if ($updatedCount > 0) {
+ $changesMade = true;
+ }
+
+ if ($changesMade) {
+ $this->dispatch('success', 'Environment variables updated.');
+ }
+ }
+
+ private function deleteRemovedVariables($variables)
+ {
+ $variablesToDelete = $this->environment->environment_variables()->whereNotIn('key', array_keys($variables))->get();
+
+ if ($variablesToDelete->isEmpty()) {
+ return 0;
+ }
+
+ $this->environment->environment_variables()->whereNotIn('key', array_keys($variables))->delete();
+
+ return $variablesToDelete->count();
+ }
+
+ private function updateOrCreateVariables($variables)
+ {
+ $count = 0;
+ foreach ($variables as $key => $value) {
+ $found = $this->environment->environment_variables()->where('key', $key)->first();
+
+ if ($found) {
+ if (! $found->is_shown_once && ! $found->is_multiline) {
+ if ($found->value !== $value) {
+ $found->value = $value;
+ $found->save();
+ $count++;
+ }
+ }
+ } else {
+ $this->environment->environment_variables()->create([
+ 'key' => $key,
+ 'value' => $value,
+ 'is_multiline' => false,
+ 'is_literal' => false,
+ 'type' => 'environment',
+ 'team_id' => currentTeam()->id,
+ ]);
+ $count++;
+ }
+ }
+
+ return $count;
+ }
+
+ public function refreshEnvs()
+ {
+ $this->environment->refresh();
+ $this->getDevView();
}
public function render()
diff --git a/app/Livewire/SharedVariables/Project/Show.php b/app/Livewire/SharedVariables/Project/Show.php
index 712a9960b..a3abe5df2 100644
--- a/app/Livewire/SharedVariables/Project/Show.php
+++ b/app/Livewire/SharedVariables/Project/Show.php
@@ -12,7 +12,11 @@ class Show extends Component
public Project $project;
- protected $listeners = ['refreshEnvs' => '$refresh', 'saveKey' => 'saveKey', 'environmentVariableDeleted' => '$refresh'];
+ public string $view = 'normal';
+
+ public ?string $variables = null;
+
+ protected $listeners = ['refreshEnvs' => 'refreshEnvs', 'saveKey' => 'saveKey', 'environmentVariableDeleted' => 'refreshEnvs'];
public function saveKey($data)
{
@@ -32,6 +36,7 @@ public function saveKey($data)
'team_id' => currentTeam()->id,
]);
$this->project->refresh();
+ $this->getDevView();
} catch (\Throwable $e) {
return handleError($e, $this);
}
@@ -46,6 +51,116 @@ public function mount()
return redirect()->route('dashboard');
}
$this->project = $project;
+ $this->getDevView();
+ }
+
+ public function switch()
+ {
+ $this->view = $this->view === 'normal' ? 'dev' : 'normal';
+ $this->getDevView();
+ }
+
+ public function getDevView()
+ {
+ $this->variables = $this->formatEnvironmentVariables($this->project->environment_variables->sortBy('key'));
+ }
+
+ private function formatEnvironmentVariables($variables)
+ {
+ return $variables->map(function ($item) {
+ if ($item->is_shown_once) {
+ return "$item->key=(Locked Secret, delete and add again to change)";
+ }
+ if ($item->is_multiline) {
+ return "$item->key=(Multiline environment variable, edit in normal view)";
+ }
+
+ return "$item->key=$item->value";
+ })->join("\n");
+ }
+
+ public function submit()
+ {
+ try {
+ $this->authorize('update', $this->project);
+ $this->handleBulkSubmit();
+ $this->getDevView();
+ } catch (\Throwable $e) {
+ return handleError($e, $this);
+ } finally {
+ $this->refreshEnvs();
+ }
+ }
+
+ private function handleBulkSubmit()
+ {
+ $variables = parseEnvFormatToArray($this->variables);
+ $changesMade = false;
+
+ // Delete removed variables
+ $deletedCount = $this->deleteRemovedVariables($variables);
+ if ($deletedCount > 0) {
+ $changesMade = true;
+ }
+
+ // Update or create variables
+ $updatedCount = $this->updateOrCreateVariables($variables);
+ if ($updatedCount > 0) {
+ $changesMade = true;
+ }
+
+ if ($changesMade) {
+ $this->dispatch('success', 'Environment variables updated.');
+ }
+ }
+
+ private function deleteRemovedVariables($variables)
+ {
+ $variablesToDelete = $this->project->environment_variables()->whereNotIn('key', array_keys($variables))->get();
+
+ if ($variablesToDelete->isEmpty()) {
+ return 0;
+ }
+
+ $this->project->environment_variables()->whereNotIn('key', array_keys($variables))->delete();
+
+ return $variablesToDelete->count();
+ }
+
+ private function updateOrCreateVariables($variables)
+ {
+ $count = 0;
+ foreach ($variables as $key => $value) {
+ $found = $this->project->environment_variables()->where('key', $key)->first();
+
+ if ($found) {
+ if (! $found->is_shown_once && ! $found->is_multiline) {
+ if ($found->value !== $value) {
+ $found->value = $value;
+ $found->save();
+ $count++;
+ }
+ }
+ } else {
+ $this->project->environment_variables()->create([
+ 'key' => $key,
+ 'value' => $value,
+ 'is_multiline' => false,
+ 'is_literal' => false,
+ 'type' => 'project',
+ 'team_id' => currentTeam()->id,
+ ]);
+ $count++;
+ }
+ }
+
+ return $count;
+ }
+
+ public function refreshEnvs()
+ {
+ $this->project->refresh();
+ $this->getDevView();
}
public function render()
diff --git a/app/Livewire/SharedVariables/Team/Index.php b/app/Livewire/SharedVariables/Team/Index.php
index 82473528c..6311d9a87 100644
--- a/app/Livewire/SharedVariables/Team/Index.php
+++ b/app/Livewire/SharedVariables/Team/Index.php
@@ -12,7 +12,11 @@ class Index extends Component
public Team $team;
- protected $listeners = ['refreshEnvs' => '$refresh', 'saveKey' => 'saveKey', 'environmentVariableDeleted' => '$refresh'];
+ public string $view = 'normal';
+
+ public ?string $variables = null;
+
+ protected $listeners = ['refreshEnvs' => 'refreshEnvs', 'saveKey' => 'saveKey', 'environmentVariableDeleted' => 'refreshEnvs'];
public function saveKey($data)
{
@@ -32,6 +36,7 @@ public function saveKey($data)
'team_id' => currentTeam()->id,
]);
$this->team->refresh();
+ $this->getDevView();
} catch (\Throwable $e) {
return handleError($e, $this);
}
@@ -40,6 +45,116 @@ public function saveKey($data)
public function mount()
{
$this->team = currentTeam();
+ $this->getDevView();
+ }
+
+ public function switch()
+ {
+ $this->view = $this->view === 'normal' ? 'dev' : 'normal';
+ $this->getDevView();
+ }
+
+ public function getDevView()
+ {
+ $this->variables = $this->formatEnvironmentVariables($this->team->environment_variables->sortBy('key'));
+ }
+
+ private function formatEnvironmentVariables($variables)
+ {
+ return $variables->map(function ($item) {
+ if ($item->is_shown_once) {
+ return "$item->key=(Locked Secret, delete and add again to change)";
+ }
+ if ($item->is_multiline) {
+ return "$item->key=(Multiline environment variable, edit in normal view)";
+ }
+
+ return "$item->key=$item->value";
+ })->join("\n");
+ }
+
+ public function submit()
+ {
+ try {
+ $this->authorize('update', $this->team);
+ $this->handleBulkSubmit();
+ $this->getDevView();
+ } catch (\Throwable $e) {
+ return handleError($e, $this);
+ } finally {
+ $this->refreshEnvs();
+ }
+ }
+
+ private function handleBulkSubmit()
+ {
+ $variables = parseEnvFormatToArray($this->variables);
+ $changesMade = false;
+
+ // Delete removed variables
+ $deletedCount = $this->deleteRemovedVariables($variables);
+ if ($deletedCount > 0) {
+ $changesMade = true;
+ }
+
+ // Update or create variables
+ $updatedCount = $this->updateOrCreateVariables($variables);
+ if ($updatedCount > 0) {
+ $changesMade = true;
+ }
+
+ if ($changesMade) {
+ $this->dispatch('success', 'Environment variables updated.');
+ }
+ }
+
+ private function deleteRemovedVariables($variables)
+ {
+ $variablesToDelete = $this->team->environment_variables()->whereNotIn('key', array_keys($variables))->get();
+
+ if ($variablesToDelete->isEmpty()) {
+ return 0;
+ }
+
+ $this->team->environment_variables()->whereNotIn('key', array_keys($variables))->delete();
+
+ return $variablesToDelete->count();
+ }
+
+ private function updateOrCreateVariables($variables)
+ {
+ $count = 0;
+ foreach ($variables as $key => $value) {
+ $found = $this->team->environment_variables()->where('key', $key)->first();
+
+ if ($found) {
+ if (! $found->is_shown_once && ! $found->is_multiline) {
+ if ($found->value !== $value) {
+ $found->value = $value;
+ $found->save();
+ $count++;
+ }
+ }
+ } else {
+ $this->team->environment_variables()->create([
+ 'key' => $key,
+ 'value' => $value,
+ 'is_multiline' => false,
+ 'is_literal' => false,
+ 'type' => 'team',
+ 'team_id' => currentTeam()->id,
+ ]);
+ $count++;
+ }
+ }
+
+ return $count;
+ }
+
+ public function refreshEnvs()
+ {
+ $this->team->refresh();
+ $this->getDevView();
}
public function render()
diff --git a/resources/views/livewire/shared-variables/environment/show.blade.php b/resources/views/livewire/shared-variables/environment/show.blade.php
index 0799a7422..41c824904 100644
--- a/resources/views/livewire/shared-variables/environment/show.blade.php
+++ b/resources/views/livewire/shared-variables/environment/show.blade.php
@@ -9,17 +9,33 @@