diff --git a/app/Domain/EquipmentExport.php b/app/Domain/EquipmentExport.php
new file mode 100644
index 00000000..01966703
--- /dev/null
+++ b/app/Domain/EquipmentExport.php
@@ -0,0 +1,103 @@
+equipmentItems as $equipmentItem) {
+ $row = [
+ $equipmentItem->id_number,
+ $equipmentItem->name,
+ $equipmentItem->labels?->implode(", "),
+ $equipmentItem->is_mobile,
+ $equipmentItem->assignee->profile->full_name ?? "",
+ $equipmentItem->assigned_at ? Date::dateTimeToExcel($equipmentItem->assigned_at) : "",
+ ];
+
+ yield $row;
+ }
+ }
+
+ public function headings(): array
+ {
+ return [
+ __("ID"),
+ __("Name"),
+ __("Labels"),
+ __("Is mobile"),
+ __("Assignee"),
+ __("Assigned at"),
+ ];
+ }
+
+ public function columnFormats(): array
+ {
+ return [
+ "A" => NumberFormat::FORMAT_TEXT,
+ "B" => NumberFormat::FORMAT_TEXT,
+ "C" => NumberFormat::FORMAT_TEXT,
+ "D" => DataType::TYPE_BOOL,
+ "E" => NumberFormat::FORMAT_TEXT,
+ "F" => NumberFormat::FORMAT_DATE_DDMMYYYY,
+ ];
+ }
+
+ public function styles(Worksheet $sheet): void
+ {
+ $lastRow = $sheet->getHighestRow();
+ $lastColumn = $sheet->getHighestColumn();
+
+ $sheet->getStyle("A1:{$lastColumn}1")
+ ->getFont()
+ ->setBold(true);
+
+ $sheet->getStyle("A1:{$lastColumn}1")
+ ->getAlignment()
+ ->setVertical(Alignment::VERTICAL_CENTER);
+
+ $sheet->getStyle("A1:{$lastColumn}1")
+ ->getFill()
+ ->setFillType(Fill::FILL_SOLID)
+ ->getStartColor()
+ ->setRGB("D9D9D9");
+
+ $sheet->getStyle("A2:A{$lastRow}")
+ ->getFont()
+ ->setBold(true);
+
+ $sheet->getStyle("A1:{$lastColumn}{$lastRow}")
+ ->getBorders()
+ ->getAllBorders()
+ ->setBorderStyle(Border::BORDER_THIN)
+ ->getColor()
+ ->setRGB("B7B7B7");
+ }
+}
diff --git a/app/Eloquent/Models/EquipmentItem.php b/app/Eloquent/Models/EquipmentItem.php
new file mode 100644
index 00000000..62abf9a8
--- /dev/null
+++ b/app/Eloquent/Models/EquipmentItem.php
@@ -0,0 +1,94 @@
+ "date",
+ "labels" => AsCollection::class,
+ ];
+ protected $fillable = [
+ "id_number",
+ "name",
+ "is_mobile",
+ "labels",
+ "assignee_id",
+ "assigned_at",
+ ];
+
+ public function scopeSearch(Builder $query, ?string $text): Builder
+ {
+ if ($text === null) {
+ return $query;
+ }
+
+ return $query
+ ->where("id_number", "ILIKE", "%{$text}%")
+ ->orWhere("name", "ILIKE", "%{$text}%")
+ ->orWhere("labels", "ILIKE", "%{$text}%")
+ ->orWhereRelation(
+ "assignee",
+ fn(Builder $query): Builder => $query
+ ->where("email", "ILIKE", "%{$text}%")
+ ->orWhereRelation(
+ "profile",
+ fn(Builder $query): Builder => $query
+ ->where("first_name", "ILIKE", "%{$text}%")
+ ->orWhere("last_name", "ILIKE", "%{$text}%")
+ ->orWhere(DB::raw("CONCAT(first_name, ' ', last_name)"), "ILIKE", "%{$text}%"),
+ ),
+ );
+ }
+
+ public function scopeLabels(Builder $query, ?array $labels): Builder
+ {
+ if ($labels === null) {
+ return $query;
+ }
+
+ $query->where(function (Builder $query) use ($labels): Builder {
+ foreach ($labels as $label) {
+ $query->orWhereJsonContains("labels", $label);
+ }
+
+ return $query;
+ });
+
+ return $query;
+ }
+
+ public function assignee(): BelongsTo
+ {
+ return $this->belongsTo(User::class, "assignee_id");
+ }
+
+ protected static function newFactory(): EquipmentItemFactory
+ {
+ return EquipmentItemFactory::new();
+ }
+}
diff --git a/app/Eloquent/Models/EquipmentLabel.php b/app/Eloquent/Models/EquipmentLabel.php
new file mode 100644
index 00000000..c073daa9
--- /dev/null
+++ b/app/Eloquent/Models/EquipmentLabel.php
@@ -0,0 +1,35 @@
+belongsToMany(EquipmentItem::class, "equipment_items_labels");
+ }
+
+ protected static function newFactory(): EquipmentLabelFactory
+ {
+ return EquipmentLabelFactory::new();
+ }
+}
diff --git a/app/Eloquent/Models/User.php b/app/Eloquent/Models/User.php
index 0d403f30..3a92ff54 100644
--- a/app/Eloquent/Models/User.php
+++ b/app/Eloquent/Models/User.php
@@ -14,6 +14,7 @@
use Illuminate\Notifications\Notifiable;
use Illuminate\Support\Carbon;
use Illuminate\Support\Collection;
+use Illuminate\Support\Facades\DB;
use Spatie\Permission\Traits\HasRoles;
use Toby\Domain\Enums\EmploymentForm;
use Toby\Domain\Enums\Role;
@@ -102,7 +103,8 @@ public function scopeSearch(Builder $query, ?string $text): Builder
"profile",
fn(Builder $query): Builder => $query
->where("first_name", "ILIKE", "%{$text}%")
- ->orWhere("last_name", "ILIKE", "%{$text}%"),
+ ->orWhere("last_name", "ILIKE", "%{$text}%")
+ ->orWhere(DB::raw("CONCAT(first_name, ' ', last_name)"), "ILIKE", "%{$text}%"),
);
}
diff --git a/app/Infrastructure/Http/Controllers/EquipmentController.php b/app/Infrastructure/Http/Controllers/EquipmentController.php
new file mode 100644
index 00000000..9487b4fe
--- /dev/null
+++ b/app/Infrastructure/Http/Controllers/EquipmentController.php
@@ -0,0 +1,183 @@
+user()->cannot("manageEquipment")) {
+ return redirect()->route("equipment-items.indexForEmployee");
+ }
+
+ $searchQuery = $request->query("search");
+
+ $equipmentItems = EquipmentItem::query()
+ ->search($searchQuery)
+ ->when(
+ $request->query("assignee") && $request->query("assignee") !== "unassigned",
+ fn($query) => $query->where("assignee_id", $request->query("assignee")),
+ )
+ ->when(
+ $request->query("assignee") === "unassigned",
+ fn($query) => $query->where("assignee_id", null),
+ )
+ ->labels($request->query("labels"))
+ ->orderBy("id_number")
+ ->paginate()
+ ->withQueryString();
+
+ $users = User::query()
+ ->orderByProfileField("last_name")
+ ->orderByProfileField("first_name")
+ ->get();
+
+ return inertia("Equipment/Index", [
+ "equipmentItems" => EquipmentItemResource::collection($equipmentItems),
+ "labels" => EquipmentLabel::query()->pluck("name"),
+ "users" => SimpleUserResource::collection($users),
+ "filters" => [
+ "search" => $searchQuery,
+ "labels" => $request->query("labels"),
+ "assignee" => $request->query("assignee"),
+ ],
+ ]);
+ }
+
+ /**
+ * @throws AuthorizationException
+ */
+ public function indexForEmployee(Request $request): RedirectResponse|Response
+ {
+ $searchQuery = $request->query("search");
+
+ $equipmentItems = EquipmentItem::query()
+ ->search($searchQuery)
+ ->labels($request->query("labels"))
+ ->where("assignee_id", $request->user()->id)
+ ->orderBy("id_number")
+ ->paginate()
+ ->withQueryString();
+
+ return inertia("Equipment/IndexForEmployee", [
+ "equipmentItems" => EquipmentItemResource::collection($equipmentItems),
+ "labels" => EquipmentLabel::query()->pluck("name"),
+ "filters" => [
+ "search" => $searchQuery,
+ "labels" => $request->query("labels"),
+ ],
+ ]);
+ }
+
+ /**
+ * @throws AuthorizationException
+ */
+ public function create(): Response
+ {
+ $this->authorize("manageEquipment");
+
+ $users = User::query()
+ ->orderByProfileField("last_name")
+ ->orderByProfileField("first_name")
+ ->get();
+
+ return inertia("Equipment/Create", [
+ "users" => SimpleUserResource::collection($users),
+ "labels" => EquipmentLabel::query()->pluck("name"),
+ ]);
+ }
+
+ /**
+ * @throws AuthorizationException
+ */
+ public function store(
+ EquipmentRequest $request,
+ ): RedirectResponse {
+ $this->authorize("manageEquipment");
+
+ EquipmentItem::query()->create($request->data());
+
+ return redirect()
+ ->route("equipment-items.index")
+ ->with("success", __("Equipment item created."));
+ }
+
+ /**
+ * @throws AuthorizationException
+ */
+ public function edit(EquipmentItem $equipmentItem): Response
+ {
+ $this->authorize("manageEquipment");
+
+ $users = User::query()
+ ->orderByProfileField("last_name")
+ ->orderByProfileField("first_name")
+ ->get();
+
+ return inertia("Equipment/Edit", [
+ "equipmentItem" => new EquipmentItemResource($equipmentItem),
+ "users" => SimpleUserResource::collection($users),
+ "labels" => EquipmentLabel::query()->pluck("name"),
+ ]);
+ }
+
+ /**
+ * @throws AuthorizationException
+ */
+ public function update(
+ EquipmentRequest $request,
+ EquipmentItem $equipmentItem,
+ ): RedirectResponse {
+ $this->authorize("manageUsers");
+
+ $equipmentItem->update($request->data());
+
+ return redirect()
+ ->route("equipment-items.index")
+ ->with("success", __("Equipment item updated."));
+ }
+
+ public function destroy(EquipmentItem $equipmentItem): RedirectResponse
+ {
+ $this->authorize("manageEquipment");
+
+ $equipmentItem->delete();
+
+ return redirect()
+ ->route("equipment-items.index")
+ ->with("success", __("Equipment item deleted."));
+ }
+
+ public function downloadExcel(): BinaryFileResponse
+ {
+ $this->authorize("manageEquipment");
+
+ $equipmentItems = EquipmentItem::query()->get();
+
+ $equipmentExport = new EquipmentExport($equipmentItems);
+
+ $name = __("Equipment") . " " . Carbon::now()->translatedFormat("d F Y") . ".xlsx";
+
+ return Excel::download($equipmentExport, $name);
+ }
+}
diff --git a/app/Infrastructure/Http/Controllers/EquipmentLabelController.php b/app/Infrastructure/Http/Controllers/EquipmentLabelController.php
new file mode 100644
index 00000000..1d951501
--- /dev/null
+++ b/app/Infrastructure/Http/Controllers/EquipmentLabelController.php
@@ -0,0 +1,57 @@
+authorize("manageEquipment");
+
+ $labels = EquipmentLabel::query()
+ ->orderBy("name")
+ ->get();
+
+ return inertia("EquipmentLabels", [
+ "labels" => EquipmentLabelResource::collection($labels),
+ ]);
+ }
+
+ /**
+ * @throws AuthorizationException
+ */
+ public function store(EquipmentLabelRequest $request): RedirectResponse
+ {
+ $this->authorize("manageEquipment");
+
+ $label = EquipmentLabel::query()->create($request->data());
+
+ return redirect()
+ ->back()
+ ->with("success", __("Label :name created.", [
+ "name" => $label->name,
+ ]));
+ }
+
+ public function destroy(EquipmentLabel $equipmentLabel): RedirectResponse
+ {
+ $this->authorize("manageEquipment");
+
+ $equipmentLabel->delete();
+
+ return redirect()
+ ->back()
+ ->with("success", __("Label :name deleted.", [
+ "name" => $equipmentLabel->name,
+ ]));
+ }
+}
diff --git a/app/Infrastructure/Http/Requests/EquipmentLabelRequest.php b/app/Infrastructure/Http/Requests/EquipmentLabelRequest.php
new file mode 100644
index 00000000..b1cb4355
--- /dev/null
+++ b/app/Infrastructure/Http/Requests/EquipmentLabelRequest.php
@@ -0,0 +1,29 @@
+ [
+ "required",
+ Rule::unique("equipment_labels", "name")->ignore($this->equipment_label),
+ "max:255",
+ ],
+ ];
+ }
+
+ public function data(): array
+ {
+ return [
+ "name" => $this->get("name"),
+ ];
+ }
+}
diff --git a/app/Infrastructure/Http/Requests/EquipmentRequest.php b/app/Infrastructure/Http/Requests/EquipmentRequest.php
new file mode 100644
index 00000000..c064637f
--- /dev/null
+++ b/app/Infrastructure/Http/Requests/EquipmentRequest.php
@@ -0,0 +1,35 @@
+ ["required", "min:3", "max:80", Rule::unique("equipment_items", "id_number")->ignore($this->equipment_item)],
+ "name" => ["required", "min:3", "max:80"],
+ "isMobile" => ["required", "boolean"],
+ "assignee" => ["required_with:assignedAt", "nullable", "exists:users,id"],
+ "assignedAt" => ["required_with:assignee", "nullable", "date_format:Y-m-d"],
+ "labels" => ["array", "distinct"],
+ ];
+ }
+
+ public function data(): array
+ {
+ return [
+ "id_number" => $this->get("idNumber"),
+ "name" => $this->get("name"),
+ "is_mobile" => $this->get("isMobile"),
+ "assignee_id" => $this->get("assignee"),
+ "assigned_at" => $this->get("assignedAt"),
+ "labels" => $this->get("labels"),
+ ];
+ }
+}
diff --git a/app/Infrastructure/Http/Resources/EquipmentItemResource.php b/app/Infrastructure/Http/Resources/EquipmentItemResource.php
new file mode 100644
index 00000000..2581aa42
--- /dev/null
+++ b/app/Infrastructure/Http/Resources/EquipmentItemResource.php
@@ -0,0 +1,26 @@
+ $this->id,
+ "idNumber" => $this->id_number,
+ "name" => $this->name,
+ "isMobile" => $this->is_mobile,
+ "assignee" => new SimpleUserResource($this->assignee),
+ "labels" => $this->labels,
+ "assignedAt" => $this->assigned_at?->toDateString(),
+ "displayAssignedAt" => $this->assigned_at?->toDisplayString(),
+ ];
+ }
+}
diff --git a/app/Infrastructure/Http/Resources/EquipmentLabelResource.php b/app/Infrastructure/Http/Resources/EquipmentLabelResource.php
new file mode 100644
index 00000000..a160b0c9
--- /dev/null
+++ b/app/Infrastructure/Http/Resources/EquipmentLabelResource.php
@@ -0,0 +1,20 @@
+ $this->id,
+ "name" => $this->name,
+ ];
+ }
+}
diff --git a/config/permission.php b/config/permission.php
index 0420acb2..a3f4faa3 100644
--- a/config/permission.php
+++ b/config/permission.php
@@ -53,6 +53,7 @@
"receiveVacationRequestWaitsForApprovalNotification",
"receiveVacationRequestStatusChangedNotification",
"receiveBenefitsReportCreationNotification",
+ "manageEquipment",
],
"permission_roles" => [
Role::Administrator->value => [
@@ -73,6 +74,7 @@
"receiveVacationRequestsSummaryNotification",
"receiveVacationRequestWaitsForApprovalNotification",
"receiveVacationRequestStatusChangedNotification",
+ "manageEquipment",
],
Role::AdministrativeApprover->value => [
"managePermissions",
@@ -94,6 +96,7 @@
"receiveVacationRequestWaitsForApprovalNotification",
"receiveVacationRequestStatusChangedNotification",
"receiveBenefitsReportCreationNotification",
+ "manageEquipment",
],
Role::TechnicalApprover->value => [
"manageTechnologies",
diff --git a/database/factories/EquipmentItemFactory.php b/database/factories/EquipmentItemFactory.php
new file mode 100644
index 00000000..c8ed4e1d
--- /dev/null
+++ b/database/factories/EquipmentItemFactory.php
@@ -0,0 +1,30 @@
+faker->boolean;
+
+ return [
+ "id_number" => $this->faker->numerify("ABC#########"),
+ "name" => $this->faker->word,
+ "assignee_id" => $isAssigned ? User::factory() : null,
+ "assigned_at" => $isAssigned ? $this->faker->dateTimeBetween("-1 year") : null,
+ "is_mobile" => $this->faker->boolean,
+ "labels" => [
+ $this->faker->word, $this->faker->word, $this->faker->word,
+ ],
+ ];
+ }
+}
diff --git a/database/factories/EquipmentLabelFactory.php b/database/factories/EquipmentLabelFactory.php
new file mode 100644
index 00000000..e90aa8ec
--- /dev/null
+++ b/database/factories/EquipmentLabelFactory.php
@@ -0,0 +1,20 @@
+ $this->faker->word,
+ ];
+ }
+}
diff --git a/database/migrations/2023_09_26_140056_create_equipment_items_table.php b/database/migrations/2023_09_26_140056_create_equipment_items_table.php
new file mode 100644
index 00000000..74119295
--- /dev/null
+++ b/database/migrations/2023_09_26_140056_create_equipment_items_table.php
@@ -0,0 +1,29 @@
+id();
+ $table->string("id_number")->unique();
+ $table->string("name");
+ $table->boolean("is_mobile")->default(false);
+ $table->foreignIdFor(User::class, "assignee_id")->nullable()->constrained("users")->cascadeOnDelete();
+ $table->date("assigned_at")->nullable();
+ $table->json("labels")->nullable();
+ $table->timestamps();
+ });
+ }
+
+ public function down(): void
+ {
+ Schema::dropIfExists("equipment_items");
+ }
+};
diff --git a/database/migrations/2023_09_26_140126_create_equipment_labels_table.php b/database/migrations/2023_09_26_140126_create_equipment_labels_table.php
new file mode 100644
index 00000000..2302ddda
--- /dev/null
+++ b/database/migrations/2023_09_26_140126_create_equipment_labels_table.php
@@ -0,0 +1,23 @@
+id();
+ $table->string("name");
+ $table->timestamps();
+ });
+ }
+
+ public function down(): void
+ {
+ Schema::dropIfExists("equipment_labels");
+ }
+};
diff --git a/database/seeders/DatabaseSeeder.php b/database/seeders/DatabaseSeeder.php
index e59c21b8..f182e303 100644
--- a/database/seeders/DatabaseSeeder.php
+++ b/database/seeders/DatabaseSeeder.php
@@ -10,6 +10,8 @@
use Toby\Domain\WorkDaysCalculator;
use Toby\Eloquent\Models\Benefit;
use Toby\Eloquent\Models\BenefitsReport;
+use Toby\Eloquent\Models\EquipmentItem;
+use Toby\Eloquent\Models\EquipmentLabel;
use Toby\Eloquent\Models\Key;
use Toby\Eloquent\Models\User;
use Toby\Eloquent\Models\VacationLimit;
@@ -106,5 +108,9 @@ public function run(): void
]);
BenefitsReport::factory(3)->create();
+
+ EquipmentLabel::factory(10)->create();
+
+ EquipmentItem::factory(40)->create();
}
}
diff --git a/database/seeders/DemoSeeder.php b/database/seeders/DemoSeeder.php
index d436c66e..fa8fa849 100644
--- a/database/seeders/DemoSeeder.php
+++ b/database/seeders/DemoSeeder.php
@@ -21,6 +21,8 @@
use Toby\Domain\WorkDaysCalculator;
use Toby\Eloquent\Models\Benefit;
use Toby\Eloquent\Models\BenefitsReport;
+use Toby\Eloquent\Models\EquipmentItem;
+use Toby\Eloquent\Models\EquipmentLabel;
use Toby\Eloquent\Models\Key;
use Toby\Eloquent\Models\Resume;
use Toby\Eloquent\Models\Technology;
@@ -395,5 +397,75 @@ public function run(): void
"data" => null,
"committed_at" => null,
]);
+
+ EquipmentLabel::factory()->createMany([
+ ["name" => "Komputery"],
+ ["name" => "Telefony"],
+ ["name" => "Urządzenia peryferyjne"],
+ ["name" => "Monitory"],
+ ["name" => "Telewizory"],
+ ["name" => "Wyposażenie biura"],
+ ["name" => "Inne"],
+ ]);
+
+ User::query()->each(function (User $user): void {
+ /** @var EquipmentItem $computer */
+ $computer = EquipmentItem::factory([
+ "name" => "Laptop Dell Latitude 7400",
+ "assigned_at" => fake()->dateTimeBetween("-1 year"),
+ "is_mobile" => true,
+ "labels" => [
+ "Komputery",
+ ],
+ ])->for($user, "assignee")->create();
+
+ EquipmentItem::factory([
+ "name" => "Monitor Philips 2" . fake()->numberBetween(1, 8) . '"',
+ "assigned_at" => $computer->assigned_at,
+ "is_mobile" => false,
+ "labels" => [
+ "Monitory",
+ "Urządzenia peryferyjne",
+ ],
+ ])->for($user, "assignee")->create();
+
+ EquipmentItem::factory([
+ "name" => "Myszka Logitech MX" . fake()->numerify(),
+ "assigned_at" => $computer->assigned_at,
+ "is_mobile" => true,
+ "labels" => [
+ "Urządzenia peryferyjne",
+ ],
+ ])->for($user, "assignee")->create();
+
+ EquipmentItem::factory([
+ "name" => "Klawiatura Dell " . fake()->numerify("#####"),
+ "assigned_at" => $computer->assigned_at,
+ "is_mobile" => true,
+ "labels" => [
+ "Urządzenia peryferyjne",
+ ],
+ ])->for($user, "assignee")->create();
+
+ EquipmentItem::factory([
+ "name" => "Hub USB",
+ "assigned_at" => $computer->assigned_at,
+ "is_mobile" => true,
+ "labels" => [
+ "Urządzenia peryferyjne",
+ ],
+ ])->for($user, "assignee")->create();
+ });
+
+ EquipmentItem::factory([
+ "name" => 'Telewizor TCN 55" 4K',
+ "is_mobile" => false,
+ "assigned_at" => null,
+ "assignee_id" => null,
+ "labels" => [
+ "Telewizory",
+ "Wyposażenie biura",
+ ],
+ ])->create();
}
}
diff --git a/lang/pl.json b/lang/pl.json
index fe9d788e..d8165892 100644
--- a/lang/pl.json
+++ b/lang/pl.json
@@ -168,5 +168,16 @@
"waiting_for_administrative": "czeka na akceptację od przełożonego administracyjnego",
"You do not have permission to perform this action.": "Nie masz uprawnień, aby wykonać tę akcję.",
"waiting_for_technical": "czeka na akceptację od przełożonego technicznego",
- "You cannot perform this action because the current status of the request :title by user :requester is :status.": "Nie możesz wykonać tej akcji, ponieważ aktualny status wniosku :title użytkownika :requester to :status"
+ "You cannot perform this action because the current status of the request :title by user :requester is :status.": "Nie możesz wykonać tej akcji, ponieważ aktualny status wniosku :title użytkownika :requester to :status",
+ "Equipment item created.": "Sprzęt utworzony.",
+ "Equipment item updated.": "Sprzęt zaktualizowany.",
+ "Equipment item deleted.": "Sprzęt usunięty.",
+ "Label :name created.": "Etykieta :name utworzona.",
+ "Label :name deleted.": "Etykieta :name usunięta.",
+ "Equipment": "Sprzęt",
+ "Name": "Nazwa",
+ "Labels": "Etykiety",
+ "Is mobile": "Czy mobilny",
+ "Assignee": "Przypisany do",
+ "Assigned at": "Przypisany od"
}
diff --git a/lang/pl/validation.php b/lang/pl/validation.php
index e52bfc17..afb575da 100644
--- a/lang/pl/validation.php
+++ b/lang/pl/validation.php
@@ -158,8 +158,18 @@
"projects.*.tasks" => [
"required" => "Zadania w projekcie są wymagane.",
],
+ "idNumber" => [
+ "required" => "ID jest wymagane.",
+ ],
+ "assignee" => [
+ "required_with" => "Przydzielona osoba jest wymagana.",
+ ],
+ "assignedAt" => [
+ "required_with" => "Data przydzielenia jest wymagana.",
+ ],
"name" => [
"unique" => "Taka nazwa już występuje.",
+ "required" => "Nazwa jest wymagana.",
],
"items.*.days" => [
"max" => "Limit dni urlopu nie może być większy niż :max.",
@@ -182,5 +192,9 @@
"date" => "data",
"name" => "nazwa",
"password" => "hasło",
+ "idNumber" => "ID",
+ "isMobile" => "mobilny",
+ "assignee" => "przydzielona osoba",
+ "assignedAt" => "data przydzielenia",
],
];
diff --git a/resources/js/Composables/permissionInfo.js b/resources/js/Composables/permissionInfo.js
index a02c0921..ca0f1a21 100644
--- a/resources/js/Composables/permissionInfo.js
+++ b/resources/js/Composables/permissionInfo.js
@@ -19,6 +19,11 @@ const permissionsInfo = [
'value': 'manageKeys',
'section': 'Biuro',
},
+ {
+ 'name': 'Zarządzanie sprzętem',
+ 'value': 'manageEquipment',
+ 'section': 'Biuro',
+ },
{
'name': 'Zarządzanie technologiami',
'value': 'manageTechnologies',
diff --git a/resources/js/Pages/Equipment/Create.vue b/resources/js/Pages/Equipment/Create.vue
new file mode 100644
index 00000000..587fcc07
--- /dev/null
+++ b/resources/js/Pages/Equipment/Create.vue
@@ -0,0 +1,272 @@
+
+
+
+
+ {{ item.assignee.name }}
+
+ {{ item.assignee.email }}
+
+ Dodaj sprzęt
+
+
+ Edytuj sprzęt
+
+
+ Sprzęt
+
+
+
+
+
+
+
+
+
+ ID
+
+
+ Nazwa
+
+
+ Etykiety
+
+
+ Czy mobilny?
+
+
+ Przydzielony dla
+
+
+ Od kiedy
+
+
+
+
+
+ {{ item.idNumber }}
+
+
+ {{ item.name }}
+
+
+
+
+ {{ label }}
+
+
+ -
+
+
+
+
+
+
+ {{ item.displayAssignedAt || '-' }}
+
+
+
+
+
+
+
+
+
+
+ Sprzęt
+
+
+
+
+
+
+
+
+
+ ID
+
+
+ Nazwa
+
+
+ Etykiety
+
+
+ Czy mobilny?
+
+
+ Od kiedy
+
+
+
+
+ {{ item.idNumber }}
+
+
+ {{ item.name }}
+
+
+
+
+ {{ label }}
+
+
+ -
+
+
+
+
+ {{ item.displayAssignedAt || '-' }}
+
+
+
+
+
+
+
+ Etykiety sprzętu
+
+
+
+
+
+
+
+
+
+ Etykieta
+
+
+
+
+
+ {{ label.name }}
+
+
+
+
+
+
+
+
+
+
- {{ form.errors.type }} + {{ form.errors.user }}
diff --git a/resources/js/Shared/Forms/MultipleCombobox.vue b/resources/js/Shared/Forms/MultipleCombobox.vue index f683dce1..d69c71a7 100644 --- a/resources/js/Shared/Forms/MultipleCombobox.vue +++ b/resources/js/Shared/Forms/MultipleCombobox.vue @@ -13,6 +13,8 @@ const props = defineProps({ items: Array, modelValue: Array, id: String, + placeholder: String, + showChips: Boolean, }) const emit = defineEmits(['update:modelValue']) @@ -41,7 +43,10 @@ const filteredItems = computed(() => nullable multiple > -