From 8c5ec09614e8c421ddccd203e8e2f3d3044b9d75 Mon Sep 17 00:00:00 2001 From: Xinecraft Date: Sun, 24 Dec 2023 18:02:20 +0530 Subject: [PATCH] Custom Form Create and Update --- app/Enums/CustomFormStatus.php | 24 + .../Admin/CustomFormController.php | 64 ++- app/Http/Requests/CreateCustomFormRequest.php | 48 ++ app/Http/Requests/UpdateCustomFormRequest.php | 52 ++ app/Models/CustomForm.php | 4 + config/constants.php | 20 + ...12_23_062302_create_custom_forms_table.php | 6 +- database/seeders/PermissionSeeder.php | 1 + resources/js/Composables/useFormKit.js | 30 ++ resources/js/Jetstream/DialogModal.vue | 36 +- .../Admin/CustomForm/CreateCustomForm.vue | 371 ++++++++----- .../Pages/Admin/CustomForm/EditCustomForm.vue | 499 ++++++++++++++++++ .../Pages/Admin/CustomForm/EditCustomPage.vue | 286 ---------- .../Admin/CustomForm/IndexCustomForm.vue | 45 +- 14 files changed, 994 insertions(+), 492 deletions(-) create mode 100644 app/Enums/CustomFormStatus.php create mode 100644 app/Http/Requests/CreateCustomFormRequest.php create mode 100644 app/Http/Requests/UpdateCustomFormRequest.php create mode 100644 resources/js/Composables/useFormKit.js create mode 100644 resources/js/Pages/Admin/CustomForm/EditCustomForm.vue delete mode 100644 resources/js/Pages/Admin/CustomForm/EditCustomPage.vue diff --git a/app/Enums/CustomFormStatus.php b/app/Enums/CustomFormStatus.php new file mode 100644 index 000000000..ddb75df01 --- /dev/null +++ b/app/Enums/CustomFormStatus.php @@ -0,0 +1,24 @@ + $this->key, + 'value' => $this->value, + ]; + } +} diff --git a/app/Http/Controllers/Admin/CustomFormController.php b/app/Http/Controllers/Admin/CustomFormController.php index f78a4db30..ed308d3a1 100644 --- a/app/Http/Controllers/Admin/CustomFormController.php +++ b/app/Http/Controllers/Admin/CustomFormController.php @@ -3,9 +3,10 @@ namespace App\Http\Controllers\Admin; use App\Http\Controllers\Controller; +use App\Http\Requests\CreateCustomFormRequest; +use App\Http\Requests\UpdateCustomFormRequest; use App\Models\CustomForm; use App\Queries\Filters\FilterMultipleFields; -use Illuminate\Http\Request; use Inertia\Inertia; use Spatie\QueryBuilder\AllowedFilter; use Spatie\QueryBuilder\QueryBuilder; @@ -27,14 +28,14 @@ public function index() 'title', 'slug', 'status', - 'is_only_auth', - 'is_only_staff', + 'can_create_submission', + 'require_restricted_permission_to_view_submission', 'is_notify_staff_on_submission', 'created_at', 'created_by', AllowedFilter::custom('q', new FilterMultipleFields(['id', 'title', 'slug', 'description'])), ]) - ->allowedSorts(['id', 'title', 'slug', 'status', 'is_only_auth', 'is_only_staff', 'is_notify_staff_on_submission', 'created_at']) + ->allowedSorts(['id', 'title', 'slug', 'status', 'can_create_submission', 'require_restricted_permission_to_view_submission', 'is_notify_staff_on_submission', 'created_at']) ->defaultSort('-id') ->paginate($perPage) ->withQueryString(); @@ -52,28 +53,59 @@ public function create() return Inertia::render('Admin/CustomForm/CreateCustomForm'); } - public function store(Request $request) + public function store(CreateCustomFormRequest $request) { - // - } + CustomForm::create([ + 'title' => $request->title, + 'slug' => $request->slug, + 'description' => $request->description, + 'status' => $request->status, + 'can_create_submission' => $request->can_create_submission, + 'require_restricted_permission_to_view_submission' => $request->require_restricted_permission_to_view_submission, + 'is_notify_staff_on_submission' => $request->is_notify_staff_on_submission, + 'fields' => $request->fields, + 'created_by' => $request->user()->id, + ]); - public function show(string $id) - { - // + return redirect()->route('admin.custom-form.index') + ->with(['toast' => ['type' => 'success', 'title' => __('Created Successfully'), 'body' => __('Custom Form is created successfully')]]); } - public function edit(string $id) + public function edit(CustomForm $customForm) { - // + $this->authorize('update', $customForm); + + return Inertia::render('Admin/CustomForm/EditCustomForm', [ + 'customForm' => $customForm, + ]); } - public function update(Request $request, string $id) + public function update(UpdateCustomFormRequest $request, CustomForm $customForm) { - // + $this->authorize('update', $customForm); + + $customForm->title = $request->title; + $customForm->slug = $request->slug; + $customForm->description = $request->description; + $customForm->status = $request->status; + $customForm->can_create_submission = $request->can_create_submission; + $customForm->require_restricted_permission_to_view_submission = $request->require_restricted_permission_to_view_submission; + $customForm->is_notify_staff_on_submission = $request->is_notify_staff_on_submission; + $customForm->fields = $request->fields; + $customForm->updated_by = $request->user()->id; + $customForm->save(); + + return redirect()->back() + ->with(['toast' => ['type' => 'success', 'title' => __('Updated Successfully'), 'body' => __('Custom Form updated successfully')]]); } - public function destroy(string $id) + public function destroy(CustomForm $customForm) { - // + $this->authorize('delete', $customForm); + + $customForm->delete(); + + return redirect()->route('admin.custom-form.index') + ->with(['toast' => ['type' => 'success', 'title' => __('Deleted Successfully'), 'body' => __('Custom Form has been deleted permanently')]]); } } diff --git a/app/Http/Requests/CreateCustomFormRequest.php b/app/Http/Requests/CreateCustomFormRequest.php new file mode 100644 index 000000000..7a51b4b0a --- /dev/null +++ b/app/Http/Requests/CreateCustomFormRequest.php @@ -0,0 +1,48 @@ +|string> + */ + public function rules(): array + { + $inputTypes = config('constants.custom_form_input_types'); + + return [ + 'title' => 'required|string|max:255', + 'slug' => 'required|alpha_dash|max:255|unique:custom_forms,slug', + 'description' => 'nullable|string|max:50000', + 'status' => ['required', new EnumValue(CustomFormStatus::class)], + 'can_create_submission' => 'required|string|in:anyone,auth,staff', + 'require_restricted_permission_to_view_submission' => 'required|boolean', + 'is_notify_staff_on_submission' => 'required|boolean', + 'fields' => 'required|array', + 'fields.*.type' => 'required|string|in:'.implode(',', $inputTypes), + 'fields.*.label' => 'required|string|max:255', + 'fields.*.name' => 'required|string|alpha_dash|max:100|distinct:ignore_case', + 'fields.*.placeholder' => 'sometimes|nullable|string|max:255', + 'fields.*.help' => 'sometimes|nullable|string|max:255', + 'fields.*.validation' => 'sometimes|nullable|string|max:255', + 'fields.*.options' => 'sometimes|nullable|string', + ]; + } +} diff --git a/app/Http/Requests/UpdateCustomFormRequest.php b/app/Http/Requests/UpdateCustomFormRequest.php new file mode 100644 index 000000000..8f25987d9 --- /dev/null +++ b/app/Http/Requests/UpdateCustomFormRequest.php @@ -0,0 +1,52 @@ +|string> + */ + public function rules(): array + { + $inputTypes = config('constants.custom_form_input_types'); + + return [ + 'title' => 'required|string|max:255', + 'slug' => [ + 'required', + 'alpha_dash', + 'max:255', + Rule::unique('custom_forms')->ignore($this->route('customForm')), + ], + 'description' => 'nullable|string|max:50000', + 'status' => ['required', new EnumValue(CustomFormStatus::class)], + 'can_create_submission' => 'required|string|in:anyone,auth,staff', + 'require_restricted_permission_to_view_submission' => 'required|boolean', + 'is_notify_staff_on_submission' => 'required|boolean', + 'fields' => 'required|array', + 'fields.*.type' => 'required|string|in:'.implode(',', $inputTypes), + 'fields.*.label' => 'required|string|max:255', + 'fields.*.name' => 'required|string|alpha_dash|max:100|distinct:ignore_case', + 'fields.*.placeholder' => 'sometimes|nullable|string|max:255', + 'fields.*.help' => 'sometimes|nullable|string|max:255', + 'fields.*.validation' => 'sometimes|nullable|string|max:255', + 'fields.*.options' => 'sometimes|nullable|string', + ]; + } +} diff --git a/app/Models/CustomForm.php b/app/Models/CustomForm.php index 0cdd34ca0..cba3485ac 100644 --- a/app/Models/CustomForm.php +++ b/app/Models/CustomForm.php @@ -2,6 +2,7 @@ namespace App\Models; +use App\Enums\CustomFormStatus; use Illuminate\Database\Eloquent\Factories\HasFactory; class CustomForm extends BaseModel @@ -10,5 +11,8 @@ class CustomForm extends BaseModel protected $casts = [ 'fields' => 'array', + 'status' => CustomFormStatus::class, + 'require_restricted_permission_to_view_submission' => 'boolean', + 'is_notify_staff_on_submission' => 'boolean', ]; } diff --git a/config/constants.php b/config/constants.php index 676b16311..6e3af7442 100644 --- a/config/constants.php +++ b/config/constants.php @@ -177,4 +177,24 @@ // Total Money if there is Vault '$total_money__server_{id}' => 'The total amount of money the player has (in Vault), on server with id {id}. Eg: $total_money__server_1', ], + + // Available input types for custom form + 'custom_form_input_types' => [ + 'text', + 'textarea', + 'select', + 'multiselect', + 'radio', + 'checkbox', + 'email', + 'number', + 'password', + 'tel', + 'url', + 'week', + 'month', + 'time', + 'date', + 'datetime-local', + ], ]; diff --git a/database/migrations/2023_12_23_062302_create_custom_forms_table.php b/database/migrations/2023_12_23_062302_create_custom_forms_table.php index b0be44f5b..4f50886f6 100644 --- a/database/migrations/2023_12_23_062302_create_custom_forms_table.php +++ b/database/migrations/2023_12_23_062302_create_custom_forms_table.php @@ -13,13 +13,13 @@ public function up(): void { Schema::create('custom_forms', function (Blueprint $table) { $table->id(); - $table->string('title')->unique(); + $table->string('title'); $table->string('slug')->unique(); $table->longText('description')->nullable(); $table->string('status')->default('active'); // draft, active, disabled, archived - $table->boolean('is_only_auth')->default(false); // only authenticated user can view & submit. - $table->boolean('is_only_staff')->default(false); // only staff can view & submit. + $table->string('can_create_submission')->default('anyone'); // anyone -> anyone, "auth" -> only authenticated users, "staff" -> only staff + $table->boolean('require_restricted_permission_to_view_submission')->default(false); // Only staff with view restricted_custom_form_submission permission can view submission for this form. $table->boolean('is_notify_staff_on_submission')->default(false); // notify staff (with view access) when new submission is made. $table->json('fields')->nullable(); diff --git a/database/seeders/PermissionSeeder.php b/database/seeders/PermissionSeeder.php index d82e2e321..d5d84231d 100644 --- a/database/seeders/PermissionSeeder.php +++ b/database/seeders/PermissionSeeder.php @@ -98,6 +98,7 @@ public function run() Permission::findOrCreate('update custom_forms'); Permission::findOrCreate('delete custom_forms'); Permission::findOrCreate('read custom_form_submissions'); + Permission::findOrCreate('read restricted_custom_form_submissions'); Permission::findOrCreate('delete custom_form_submissions'); Permission::findOrCreate('view pulse_admin_dashboard'); diff --git a/resources/js/Composables/useFormKit.js b/resources/js/Composables/useFormKit.js new file mode 100644 index 000000000..5f5ad9706 --- /dev/null +++ b/resources/js/Composables/useFormKit.js @@ -0,0 +1,30 @@ +export function useFormKit() { + const generateSchemaFromFieldsArray = (fields) => { + const generated = fields.map((field) => { + let f = { + $formkit: field.type == 'multiselect' ? 'select' : field.type, + label: field.label, + name: + field.name ?? field.label.toLowerCase().replace(/ /g, '_'), + help: field.help ?? undefined, + validation: field.validation ?? undefined, + placeholder: field.placeholder ?? undefined, + multiple: field.type == 'multiselect' ? true : undefined, + }; + + if ( + field.type === 'select' || + field.type === 'multiselect' || + field.type === 'radio' + ) { + f.options = field.options?.split(',') ?? []; + } + return f; + }); + return generated; + }; + + return { + generateSchemaFromFieldsArray, + }; +} diff --git a/resources/js/Jetstream/DialogModal.vue b/resources/js/Jetstream/DialogModal.vue index 80ebb3d8e..42248d122 100644 --- a/resources/js/Jetstream/DialogModal.vue +++ b/resources/js/Jetstream/DialogModal.vue @@ -24,24 +24,24 @@ const close = () => { diff --git a/resources/js/Pages/Admin/CustomForm/CreateCustomForm.vue b/resources/js/Pages/Admin/CustomForm/CreateCustomForm.vue index ec0f66785..0af957fa0 100644 --- a/resources/js/Pages/Admin/CustomForm/CreateCustomForm.vue +++ b/resources/js/Pages/Admin/CustomForm/CreateCustomForm.vue @@ -18,7 +18,7 @@
-
+
@@ -26,7 +26,8 @@
-
+
- -
+