Add workspace update functionality (#699)
* Add workspace update functionality * Refactor workspace settings header layout and edit button styling * Update workspace route and API endpoint to use root path --------- Co-authored-by: Julien Nahum <julien@nahum.net>
This commit is contained in:
parent
1f9a1f835f
commit
aae28d09cc
|
|
@ -66,7 +66,7 @@ class WorkspaceController extends Controller
|
||||||
|
|
||||||
public function create(Request $request)
|
public function create(Request $request)
|
||||||
{
|
{
|
||||||
$user = $request->user();
|
$user = $request->user();
|
||||||
|
|
||||||
$this->validate($request, [
|
$this->validate($request, [
|
||||||
'name' => 'required',
|
'name' => 'required',
|
||||||
|
|
@ -91,4 +91,24 @@ class WorkspaceController extends Controller
|
||||||
'workspace' => new WorkspaceResource($workspace),
|
'workspace' => new WorkspaceResource($workspace),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function update(Request $request, $id)
|
||||||
|
{
|
||||||
|
$workspace = Auth::user()->workspaces()->findOrFail($id);
|
||||||
|
$this->authorize('update', $workspace);
|
||||||
|
|
||||||
|
$this->validate($request, [
|
||||||
|
'name' => 'required',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$workspace->update([
|
||||||
|
'name' => $request->name,
|
||||||
|
'icon' => $request->emoji ?? '',
|
||||||
|
]);
|
||||||
|
|
||||||
|
return $this->success([
|
||||||
|
'message' => 'Workspace updated.',
|
||||||
|
'workspace' => new WorkspaceResource($workspace),
|
||||||
|
]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@ class WorkspacePolicy
|
||||||
*/
|
*/
|
||||||
public function update(User $user, Workspace $workspace)
|
public function update(User $user, Workspace $workspace)
|
||||||
{
|
{
|
||||||
return false;
|
return $user->ownsWorkspace($workspace);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -143,6 +143,7 @@ Route::group(['middleware' => 'auth:api'], function () {
|
||||||
)->name('forms.index');
|
)->name('forms.index');
|
||||||
Route::put('/custom-domains', [WorkspaceController::class, 'saveCustomDomain'])->name('save-custom-domains');
|
Route::put('/custom-domains', [WorkspaceController::class, 'saveCustomDomain'])->name('save-custom-domains');
|
||||||
Route::put('/email-settings', [WorkspaceController::class, 'saveEmailSettings'])->name('save-email-settings');
|
Route::put('/email-settings', [WorkspaceController::class, 'saveEmailSettings'])->name('save-email-settings');
|
||||||
|
Route::put('/', [WorkspaceController::class, 'update'])->name('update');
|
||||||
Route::delete('/', [WorkspaceController::class, 'delete'])->name('delete');
|
Route::delete('/', [WorkspaceController::class, 'delete'])->name('delete');
|
||||||
|
|
||||||
Route::middleware('pro-form')->group(function () {
|
Route::middleware('pro-form')->group(function () {
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ it('can create and delete Workspace', function () {
|
||||||
|
|
||||||
for ($i = 1; $i <= 3; $i++) {
|
for ($i = 1; $i <= 3; $i++) {
|
||||||
$this->postJson(route('open.workspaces.create'), [
|
$this->postJson(route('open.workspaces.create'), [
|
||||||
'name' => 'Workspace Test - '.$i,
|
'name' => 'Workspace Test - ' . $i,
|
||||||
'icon' => '🧪',
|
'icon' => '🧪',
|
||||||
])
|
])
|
||||||
->assertSuccessful()
|
->assertSuccessful()
|
||||||
|
|
@ -34,3 +34,30 @@ it('can create and delete Workspace', function () {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('can update workspace', function () {
|
||||||
|
$user = $this->actingAsUser();
|
||||||
|
|
||||||
|
$this->postJson(route('open.workspaces.create'), [
|
||||||
|
'name' => 'Workspace Test',
|
||||||
|
'icon' => '🧪',
|
||||||
|
])
|
||||||
|
->assertSuccessful()
|
||||||
|
->assertJson([
|
||||||
|
'type' => 'success',
|
||||||
|
'message' => 'Workspace created.',
|
||||||
|
]);
|
||||||
|
|
||||||
|
expect($user->workspaces()->count())->toBe(1);
|
||||||
|
|
||||||
|
$workspace = $user->workspaces()->first();
|
||||||
|
$this->putJson(route('open.workspaces.update', $workspace->id), [
|
||||||
|
'name' => 'Workspace Test Updated',
|
||||||
|
'icon' => '🔬',
|
||||||
|
])
|
||||||
|
->assertSuccessful()
|
||||||
|
->assertJson([
|
||||||
|
'type' => 'success',
|
||||||
|
'message' => 'Workspace updated.',
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
|
||||||
|
|
@ -2,9 +2,20 @@
|
||||||
<div>
|
<div>
|
||||||
<div class="flex flex-wrap items-center gap-y-4">
|
<div class="flex flex-wrap items-center gap-y-4">
|
||||||
<div class="flex-grow">
|
<div class="flex-grow">
|
||||||
<h3 class="font-semibold text-2xl text-gray-900">
|
<div class="flex items-center gap-2">
|
||||||
Workspace settings
|
<h3 class="font-semibold text-2xl text-gray-900">
|
||||||
</h3>
|
Workspace settings
|
||||||
|
</h3>
|
||||||
|
<UTooltip text="Edit workspace">
|
||||||
|
<UButton
|
||||||
|
v-if="!workspace.is_readonly"
|
||||||
|
size="xs"
|
||||||
|
color="white"
|
||||||
|
icon="i-heroicons-pencil-square"
|
||||||
|
@click="editCurrentWorkspace"
|
||||||
|
/>
|
||||||
|
</UTooltip>
|
||||||
|
</div>
|
||||||
<small class="text-gray-500">You're currently editing the settings for the workspace "{{ workspace.name }}".
|
<small class="text-gray-500">You're currently editing the settings for the workspace "{{ workspace.name }}".
|
||||||
You can switch to another workspace in top left corner of the page.</small>
|
You can switch to another workspace in top left corner of the page.</small>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -39,30 +50,21 @@
|
||||||
<modal
|
<modal
|
||||||
:show="workspaceModal"
|
:show="workspaceModal"
|
||||||
max-width="lg"
|
max-width="lg"
|
||||||
|
:compact-header="true"
|
||||||
@close="workspaceModal = false"
|
@close="workspaceModal = false"
|
||||||
>
|
>
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<svg
|
<Icon
|
||||||
|
:name="isEditing ? 'heroicons:pencil-square' : 'heroicons:plus-circle'"
|
||||||
class="w-8 h-8"
|
class="w-8 h-8"
|
||||||
viewBox="0 0 24 24"
|
/>
|
||||||
fill="none"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
d="M12 8V16M8 12H16M22 12C22 17.5228 17.5228 22 12 22C6.47715 22 2 17.5228 2 12C2 6.47715 6.47715 2 12 2C17.5228 2 22 6.47715 22 12Z"
|
|
||||||
stroke="currentColor"
|
|
||||||
stroke-width="2"
|
|
||||||
stroke-linecap="round"
|
|
||||||
stroke-linejoin="round"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</template>
|
</template>
|
||||||
<template #title>
|
<template #title>
|
||||||
Create Workspace
|
{{ isEditing ? 'Edit' : 'Create' }} Workspace
|
||||||
</template>
|
</template>
|
||||||
<div class="px-4">
|
<div class="px-4">
|
||||||
<form
|
<form
|
||||||
@submit.prevent="createWorkspace"
|
@submit.prevent="isEditing ? updateWorkspace() : createWorkspace()"
|
||||||
@keydown="form.onKeydown($event)"
|
@keydown="form.onKeydown($event)"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
|
|
@ -115,11 +117,28 @@ const form = useForm({
|
||||||
emoji: "",
|
emoji: "",
|
||||||
})
|
})
|
||||||
const workspaceModal = ref(false)
|
const workspaceModal = ref(false)
|
||||||
|
const isEditing = ref(false)
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
fetchAllWorkspaces()
|
fetchAllWorkspaces()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const editCurrentWorkspace = () => {
|
||||||
|
isEditing.value = true
|
||||||
|
form.name = workspace.value.name
|
||||||
|
form.emoji = workspace.value.icon || ''
|
||||||
|
workspaceModal.value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
const updateWorkspace = () => {
|
||||||
|
form.put(`/open/workspaces/${workspace.value.id}/`).then((data) => {
|
||||||
|
workspacesStore.save(data.workspace)
|
||||||
|
workspaceModal.value = false
|
||||||
|
isEditing.value = false
|
||||||
|
useAlert().success('Workspace successfully updated!')
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
const createWorkspace = () => {
|
const createWorkspace = () => {
|
||||||
form.post("/open/workspaces/create").then((data) => {
|
form.post("/open/workspaces/create").then((data) => {
|
||||||
workspacesStore.save(data.workspace)
|
workspacesStore.save(data.workspace)
|
||||||
|
|
@ -130,4 +149,11 @@ const createWorkspace = () => {
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
watch(workspaceModal, (newValue) => {
|
||||||
|
if (!newValue) {
|
||||||
|
isEditing.value = false
|
||||||
|
form.reset()
|
||||||
|
}
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue