* #44 - ui for summary * #44 - vacation monthly usage * #44 - fix * #44 - fix Co-authored-by: EwelinaLasowy <ewelina.lasowy@blumilk.pl>
This commit is contained in:
parent
dcda8c6255
commit
957b07b3eb
@ -31,5 +31,6 @@ class AuthServiceProvider extends ServiceProvider
|
||||
Gate::define("manageHolidays", fn(User $user) => $user->role === Role::AdministrativeApprover);
|
||||
Gate::define("manageVacationLimits", fn(User $user) => $user->role === Role::AdministrativeApprover);
|
||||
Gate::define("generateTimesheet", fn(User $user) => $user->role === Role::AdministrativeApprover);
|
||||
Gate::define("listMonthlyUsage", fn(User $user) => $user->role === Role::AdministrativeApprover);
|
||||
}
|
||||
}
|
||||
|
@ -5,9 +5,10 @@ declare(strict_types=1);
|
||||
namespace Toby\Domain;
|
||||
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use Illuminate\Support\Collection;
|
||||
use Toby\Domain\Enums\VacationType;
|
||||
use Toby\Eloquent\Models\User;
|
||||
use Toby\Eloquent\Models\Vacation;
|
||||
use Toby\Eloquent\Models\YearPeriod;
|
||||
|
||||
class UserVacationStatsRetriever
|
||||
@ -30,6 +31,21 @@ class UserVacationStatsRetriever
|
||||
->count();
|
||||
}
|
||||
|
||||
public function getUsedVacationDaysByMonth(User $user, YearPeriod $yearPeriod): Collection
|
||||
{
|
||||
return $user->vacations()
|
||||
->whereRelation(
|
||||
"vacationRequest",
|
||||
fn(Builder $query) => $query
|
||||
->where("year_period_id", $yearPeriod->id)
|
||||
->whereIn("type", $this->getLimitableVacationTypes())
|
||||
->states(VacationRequestStatesRetriever::successStates()),
|
||||
)
|
||||
->get()
|
||||
->groupBy(fn(Vacation $vacation) => strtolower($vacation->date->englishMonth))
|
||||
->map(fn(Collection $items) => $items->count());
|
||||
}
|
||||
|
||||
public function getPendingVacationDays(User $user, YearPeriod $yearPeriod): int
|
||||
{
|
||||
return $user
|
||||
|
@ -100,6 +100,14 @@ class User extends Authenticatable
|
||||
return $this->role === $role;
|
||||
}
|
||||
|
||||
public function hasVacationLimit(YearPeriod $yearPeriod): bool
|
||||
{
|
||||
return $this->vacationLimits()
|
||||
->where("year_period_id", $yearPeriod->id)
|
||||
->whereNotNull("days")
|
||||
->exists();
|
||||
}
|
||||
|
||||
protected function getAvatarName(): string
|
||||
{
|
||||
return mb_substr($this->first_name, 0, 1) . mb_substr($this->last_name, 0, 1);
|
||||
|
@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Toby\Infrastructure\Http\Controllers;
|
||||
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Http\Request;
|
||||
use Inertia\Response;
|
||||
use Toby\Domain\Enums\Month;
|
||||
use Toby\Domain\UserVacationStatsRetriever;
|
||||
use Toby\Eloquent\Helpers\YearPeriodRetriever;
|
||||
use Toby\Eloquent\Models\User;
|
||||
use Toby\Infrastructure\Http\Resources\UserResource;
|
||||
|
||||
class MonthlyUsageController extends Controller
|
||||
{
|
||||
public function __invoke(
|
||||
Request $request,
|
||||
YearPeriodRetriever $yearPeriodRetriever,
|
||||
UserVacationStatsRetriever $statsRetriever,
|
||||
): Response {
|
||||
$this->authorize("listMonthlyUsage");
|
||||
|
||||
$currentYearPeriod = $yearPeriodRetriever->selected();
|
||||
$currentUser = $request->user();
|
||||
|
||||
$users = User::query()
|
||||
->whereRelation(
|
||||
"vacationlimits",
|
||||
fn(Builder $query) => $query->where("year_period_id", $currentYearPeriod->id)->whereNotNull("days"),
|
||||
)
|
||||
->where("id", "!=", $currentUser->id)
|
||||
->orderBy("last_name")
|
||||
->orderBy("first_name")
|
||||
->get();
|
||||
|
||||
if ($currentUser->hasVacationLimit($currentYearPeriod)) {
|
||||
$users->prepend($currentUser);
|
||||
}
|
||||
|
||||
$monthlyUsage = [];
|
||||
|
||||
foreach ($users as $user) {
|
||||
$vacationsByMonth = $statsRetriever->getUsedVacationDaysByMonth($user, $currentYearPeriod);
|
||||
$limit = $statsRetriever->getVacationDaysLimit($user, $currentYearPeriod);
|
||||
$used = $statsRetriever->getUsedVacationDays($user, $currentYearPeriod);
|
||||
$pending = $statsRetriever->getPendingVacationDays($user, $currentYearPeriod);
|
||||
$remaining = $limit - $used - $pending;
|
||||
|
||||
$monthlyUsage[] = [
|
||||
"user" => new UserResource($user),
|
||||
"months" => $vacationsByMonth,
|
||||
"stats" => [
|
||||
"used" => $used,
|
||||
"pending" => $pending,
|
||||
"remaining" => $remaining,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
return inertia("MonthlyUsage", [
|
||||
"monthlyUsage" => $monthlyUsage,
|
||||
"currentMonth" => Month::current(),
|
||||
"can" => [
|
||||
"listMonthlyUsage" => $request->user()->can("listMonthlyUsage"),
|
||||
],
|
||||
]);
|
||||
}
|
||||
}
|
@ -17,6 +17,6 @@ class SelectYearPeriodController extends Controller
|
||||
|
||||
return redirect()
|
||||
->back()
|
||||
->with("success", __("Selected year period has been changed."));
|
||||
->with("info", __("Selected year period has been changed."));
|
||||
}
|
||||
}
|
||||
|
@ -27,11 +27,13 @@ class HandleInertiaRequests extends Middleware
|
||||
"manageVacationLimits" => $user ? $user->can("manageVacationLimits") : false,
|
||||
"manageUsers" => $user ? $user->can("manageUsers") : false,
|
||||
"listAllVacationRequests" => $user ? $user->can("listAll", VacationRequest::class) : false,
|
||||
"listMonthlyUsage" => $user ? $user->can("listMonthlyUsage") : false,
|
||||
],
|
||||
],
|
||||
"flash" => fn() => [
|
||||
"success" => $request->session()->get("success"),
|
||||
"error" => $request->session()->get("error"),
|
||||
"info" => $request->session()->get("info"),
|
||||
],
|
||||
"years" => fn() => $user ? $this->yearPeriodRetriever->links() : [],
|
||||
]);
|
||||
|
869
composer.lock
generated
869
composer.lock
generated
File diff suppressed because it is too large
Load Diff
296
package-lock.json
generated
296
package-lock.json
generated
@ -4,24 +4,25 @@
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"hasInstallScript": true,
|
||||
"dependencies": {
|
||||
"@headlessui/vue": "^1.5.0",
|
||||
"@heroicons/vue": "^1.0.5",
|
||||
"@heroicons/vue": "^1.0.6",
|
||||
"@inertiajs/inertia": "^0.11.0",
|
||||
"@inertiajs/inertia-vue3": "^0.6.0",
|
||||
"@inertiajs/progress": "^0.2.7",
|
||||
"@tailwindcss/forms": "^0.4.0",
|
||||
"@tailwindcss/forms": "^0.5.0",
|
||||
"@tailwindcss/line-clamp": "^0.3.1",
|
||||
"@tailwindcss/typography": "^0.5.2",
|
||||
"@vue/compiler-sfc": "^3.2.31",
|
||||
"autoprefixer": "^10.4.2",
|
||||
"axios": "^0.26.0",
|
||||
"echarts": "^5.3.0",
|
||||
"autoprefixer": "^10.4.4",
|
||||
"axios": "^0.26.1",
|
||||
"echarts": "^5.3.1",
|
||||
"eslit": "^6.0.0",
|
||||
"flatpickr": "^4.6.9",
|
||||
"flatpickr": "^4.6.11",
|
||||
"laravel-mix": "^6.0.43",
|
||||
"lodash": "^4.17.21",
|
||||
"postcss": "^8.4.7",
|
||||
"postcss": "^8.4.12",
|
||||
"tailwindcss": "^3.0.23",
|
||||
"vue": "^3.2.31",
|
||||
"vue-echarts": "^6.0.2",
|
||||
@ -32,7 +33,7 @@
|
||||
"vue3-popper": "^1.4.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"eslint": "^8.10.0",
|
||||
"eslint": "^8.11.0",
|
||||
"eslint-plugin-vue": "^8.5.0"
|
||||
}
|
||||
},
|
||||
@ -1659,16 +1660,16 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@eslint/eslintrc": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.0.tgz",
|
||||
"integrity": "sha512-igm9SjJHNEJRiUnecP/1R5T3wKLEJ7pL6e2P+GUSfCd0dGjPYYZve08uzw8L2J8foVHFz+NGu12JxRcU2gGo6w==",
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.1.tgz",
|
||||
"integrity": "sha512-bxvbYnBPN1Gibwyp6NrpnFzA3YtRL3BBAyEAFVIpNTm2Rn4Vy87GA5M4aSn3InRrlsbX5N0GW7XIx+U4SAEKdQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"ajv": "^6.12.4",
|
||||
"debug": "^4.3.2",
|
||||
"espree": "^9.3.1",
|
||||
"globals": "^13.9.0",
|
||||
"ignore": "^4.0.6",
|
||||
"ignore": "^5.2.0",
|
||||
"import-fresh": "^3.2.1",
|
||||
"js-yaml": "^4.1.0",
|
||||
"minimatch": "^3.0.4",
|
||||
@ -1678,15 +1679,6 @@
|
||||
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@eslint/eslintrc/node_modules/ignore": {
|
||||
"version": "4.0.6",
|
||||
"resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
|
||||
"integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 4"
|
||||
}
|
||||
},
|
||||
"node_modules/@headlessui/vue": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@headlessui/vue/-/vue-1.5.0.tgz",
|
||||
@ -1699,9 +1691,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@heroicons/vue": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@heroicons/vue/-/vue-1.0.5.tgz",
|
||||
"integrity": "sha512-idWtp20Fjr7mqnD7EdGDUDi83oWHnx3SwyuQY6GZyF33OApzpBOLxz7xa4t6rPOddGz9tI5RGnndLk+ake7ijQ==",
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@heroicons/vue/-/vue-1.0.6.tgz",
|
||||
"integrity": "sha512-ng2YcCQrdoQWEFpw+ipFl2rZo8mZ56v0T5+MyfQQvNqfKChwgP6DMloZLW+rl17GEcHkE3H82UTAMKBKZr4+WA==",
|
||||
"peerDependencies": {
|
||||
"vue": ">= 3"
|
||||
}
|
||||
@ -1832,9 +1824,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@tailwindcss/forms": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@tailwindcss/forms/-/forms-0.4.0.tgz",
|
||||
"integrity": "sha512-DeaQBx6EgEeuZPQACvC+mKneJsD8am1uiJugjgQK1+/Vt+Ai0GpFBC2T2fqnUad71WgOxyrZPE6BG1VaI6YqfQ==",
|
||||
"version": "0.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@tailwindcss/forms/-/forms-0.5.0.tgz",
|
||||
"integrity": "sha512-KzWugryEBFkmoaYcBE18rs6gthWCFHHO7cAZm2/hv3hwD67AzwP7udSCa22E7R1+CEJL/FfhYsJWrc0b1aeSzw==",
|
||||
"dependencies": {
|
||||
"mini-svg-data-uri": "^1.2.3"
|
||||
},
|
||||
@ -2663,13 +2655,23 @@
|
||||
}
|
||||
},
|
||||
"node_modules/autoprefixer": {
|
||||
"version": "10.4.2",
|
||||
"resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.2.tgz",
|
||||
"integrity": "sha512-9fOPpHKuDW1w/0EKfRmVnxTDt8166MAnLI3mgZ1JCnhNtYWxcJ6Ud5CO/AVOZi/AvFa8DY9RTy3h3+tFBlrrdQ==",
|
||||
"version": "10.4.4",
|
||||
"resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.4.tgz",
|
||||
"integrity": "sha512-Tm8JxsB286VweiZ5F0anmbyGiNI3v3wGv3mz9W+cxEDYB/6jbnj6GM9H9mK3wIL8ftgl+C07Lcwb8PG5PCCPzA==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/postcss/"
|
||||
},
|
||||
{
|
||||
"type": "tidelift",
|
||||
"url": "https://tidelift.com/funding/github/npm/autoprefixer"
|
||||
}
|
||||
],
|
||||
"dependencies": {
|
||||
"browserslist": "^4.19.1",
|
||||
"caniuse-lite": "^1.0.30001297",
|
||||
"fraction.js": "^4.1.2",
|
||||
"browserslist": "^4.20.2",
|
||||
"caniuse-lite": "^1.0.30001317",
|
||||
"fraction.js": "^4.2.0",
|
||||
"normalize-range": "^0.1.2",
|
||||
"picocolors": "^1.0.0",
|
||||
"postcss-value-parser": "^4.2.0"
|
||||
@ -2680,18 +2682,14 @@
|
||||
"engines": {
|
||||
"node": "^10 || ^12 || >=14"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/postcss/"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"postcss": "^8.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/axios": {
|
||||
"version": "0.26.0",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-0.26.0.tgz",
|
||||
"integrity": "sha512-lKoGLMYtHvFrPVt3r+RBMp9nh34N0M8zEfCWqdWZx6phynIEhQqAdydpyBAAG211zlhX9Rgu08cOamy6XjE5Og==",
|
||||
"version": "0.26.1",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-0.26.1.tgz",
|
||||
"integrity": "sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==",
|
||||
"dependencies": {
|
||||
"follow-redirects": "^1.14.8"
|
||||
}
|
||||
@ -3011,12 +3009,22 @@
|
||||
}
|
||||
},
|
||||
"node_modules/browserslist": {
|
||||
"version": "4.19.3",
|
||||
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.19.3.tgz",
|
||||
"integrity": "sha512-XK3X4xtKJ+Txj8G5c30B4gsm71s69lqXlkYui4s6EkKxuv49qjYlY6oVd+IFJ73d4YymtM3+djvvt/R/iJwwDg==",
|
||||
"version": "4.20.2",
|
||||
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.20.2.tgz",
|
||||
"integrity": "sha512-CQOBCqp/9pDvDbx3xfMi+86pr4KXIf2FDkTTdeuYw8OxS9t898LA1Khq57gtufFILXpfgsSx5woNgsBgvGjpsA==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/browserslist"
|
||||
},
|
||||
{
|
||||
"type": "tidelift",
|
||||
"url": "https://tidelift.com/funding/github/npm/browserslist"
|
||||
}
|
||||
],
|
||||
"dependencies": {
|
||||
"caniuse-lite": "^1.0.30001312",
|
||||
"electron-to-chromium": "^1.4.71",
|
||||
"caniuse-lite": "^1.0.30001317",
|
||||
"electron-to-chromium": "^1.4.84",
|
||||
"escalade": "^3.1.1",
|
||||
"node-releases": "^2.0.2",
|
||||
"picocolors": "^1.0.0"
|
||||
@ -3026,10 +3034,6 @@
|
||||
},
|
||||
"engines": {
|
||||
"node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/browserslist"
|
||||
}
|
||||
},
|
||||
"node_modules/buffer": {
|
||||
@ -3119,13 +3123,19 @@
|
||||
}
|
||||
},
|
||||
"node_modules/caniuse-lite": {
|
||||
"version": "1.0.30001312",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001312.tgz",
|
||||
"integrity": "sha512-Wiz1Psk2MEK0pX3rUzWaunLTZzqS2JYZFzNKqAiJGiuxIjRPLgV6+VDPOg6lQOUxmDwhTlh198JsTTi8Hzw6aQ==",
|
||||
"funding": {
|
||||
"version": "1.0.30001320",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001320.tgz",
|
||||
"integrity": "sha512-MWPzG54AGdo3nWx7zHZTefseM5Y1ccM7hlQKHRqJkPozUaw3hNbBTMmLn16GG2FUzjR13Cr3NPfhIieX5PzXDA==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/browserslist"
|
||||
},
|
||||
{
|
||||
"type": "tidelift",
|
||||
"url": "https://tidelift.com/funding/github/npm/caniuse-lite"
|
||||
}
|
||||
]
|
||||
},
|
||||
"node_modules/chalk": {
|
||||
"version": "4.1.2",
|
||||
@ -4155,12 +4165,12 @@
|
||||
"integrity": "sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA=="
|
||||
},
|
||||
"node_modules/echarts": {
|
||||
"version": "5.3.0",
|
||||
"resolved": "https://registry.npmjs.org/echarts/-/echarts-5.3.0.tgz",
|
||||
"integrity": "sha512-zENufmwFE6WjM+24tW3xQq4ICqQtI0CGj4bDVDNd3BK3LtaA/5wBp+64ykIyKy3QElz0cieKqSYP4FX9Lv9MwQ==",
|
||||
"version": "5.3.1",
|
||||
"resolved": "https://registry.npmjs.org/echarts/-/echarts-5.3.1.tgz",
|
||||
"integrity": "sha512-nWdlbgX3OVY0hpqncSvp0gDt1FRSKWn7lsWEH+PHmfCuvE0QmSw17pczQvm8AvawnLEkmf1Cts7YwQJZNC0AEQ==",
|
||||
"dependencies": {
|
||||
"tslib": "2.3.0",
|
||||
"zrender": "5.3.0"
|
||||
"zrender": "5.3.1"
|
||||
}
|
||||
},
|
||||
"node_modules/ee-first": {
|
||||
@ -4169,9 +4179,9 @@
|
||||
"integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
|
||||
},
|
||||
"node_modules/electron-to-chromium": {
|
||||
"version": "1.4.75",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.75.tgz",
|
||||
"integrity": "sha512-LxgUNeu3BVU7sXaKjUDD9xivocQLxFtq6wgERrutdY/yIOps3ODOZExK1jg8DTEg4U8TUCb5MLGeWFOYuxjF3Q=="
|
||||
"version": "1.4.92",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.92.tgz",
|
||||
"integrity": "sha512-YAVbvQIcDE/IJ/vzDMjD484/hsRbFPW2qXJPaYTfOhtligmfYEYOep+5QojpaEU9kq6bMvNeC2aG7arYvTHYsA=="
|
||||
},
|
||||
"node_modules/elliptic": {
|
||||
"version": "6.5.4",
|
||||
@ -4283,12 +4293,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/eslint": {
|
||||
"version": "8.10.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.10.0.tgz",
|
||||
"integrity": "sha512-tcI1D9lfVec+R4LE1mNDnzoJ/f71Kl/9Cv4nG47jOueCMBrCCKYXr4AUVS7go6mWYGFD4+EoN6+eXSrEbRzXVw==",
|
||||
"version": "8.11.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.11.0.tgz",
|
||||
"integrity": "sha512-/KRpd9mIRg2raGxHRGwW9ZywYNAClZrHjdueHcrVDuO3a6bj83eoTirCCk0M0yPwOjWYKHwRVRid+xK4F/GHgA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@eslint/eslintrc": "^1.2.0",
|
||||
"@eslint/eslintrc": "^1.2.1",
|
||||
"@humanwhocodes/config-array": "^0.9.2",
|
||||
"ajv": "^6.10.0",
|
||||
"chalk": "^4.0.0",
|
||||
@ -4830,9 +4840,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/flatpickr": {
|
||||
"version": "4.6.9",
|
||||
"resolved": "https://registry.npmjs.org/flatpickr/-/flatpickr-4.6.9.tgz",
|
||||
"integrity": "sha512-F0azNNi8foVWKSF+8X+ZJzz8r9sE1G4hl06RyceIaLvyltKvDl6vqk9Lm/6AUUCi5HWaIjiUbk7UpeE/fOXOpw=="
|
||||
"version": "4.6.11",
|
||||
"resolved": "https://registry.npmjs.org/flatpickr/-/flatpickr-4.6.11.tgz",
|
||||
"integrity": "sha512-/rnbE/hu5I5zndLEyYfYvqE4vPDvI5At0lFcQA5eOPfjquZLcQ0HMKTL7rv5/+DvbPM3/vJcXpXjB/DjBh+1jw=="
|
||||
},
|
||||
"node_modules/flatted": {
|
||||
"version": "3.2.5",
|
||||
@ -4868,9 +4878,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/fraction.js": {
|
||||
"version": "4.1.3",
|
||||
"resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.1.3.tgz",
|
||||
"integrity": "sha512-pUHWWt6vHzZZiQJcM6S/0PXfS+g6FM4BF5rj9wZyreivhQPdsh5PpE25VtSNxq80wHS5RfY51Ii+8Z0Zl/pmzg==",
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz",
|
||||
"integrity": "sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==",
|
||||
"engines": {
|
||||
"node": "*"
|
||||
},
|
||||
@ -5010,9 +5020,9 @@
|
||||
"integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw=="
|
||||
},
|
||||
"node_modules/globals": {
|
||||
"version": "13.12.1",
|
||||
"resolved": "https://registry.npmjs.org/globals/-/globals-13.12.1.tgz",
|
||||
"integrity": "sha512-317dFlgY2pdJZ9rspXDks7073GpDmXdfbM3vYYp0HAMKGDh1FfWPleI2ljVNLQX5M5lXcAslTcPTrOrMEFOjyw==",
|
||||
"version": "13.13.0",
|
||||
"resolved": "https://registry.npmjs.org/globals/-/globals-13.13.0.tgz",
|
||||
"integrity": "sha512-EQ7Q18AJlPwp3vUDL4mKA0KXrXyNIQyWon6T6XQiBQF0XHvRsiCSrWmmeATpUzdJN2HhWZU6Pdl0a9zdep5p6A==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"type-fest": "^0.20.2"
|
||||
@ -6923,9 +6933,19 @@
|
||||
}
|
||||
},
|
||||
"node_modules/postcss": {
|
||||
"version": "8.4.7",
|
||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.7.tgz",
|
||||
"integrity": "sha512-L9Ye3r6hkkCeOETQX6iOaWZgjp3LL6Lpqm6EtgbKrgqGGteRMNb9vzBfRL96YOSu8o7x3MfIH9Mo5cPJFGrW6A==",
|
||||
"version": "8.4.12",
|
||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.12.tgz",
|
||||
"integrity": "sha512-lg6eITwYe9v6Hr5CncVbK70SoioNQIq81nsaG86ev5hAidQvmOeETBqs7jm43K2F5/Ley3ytDtriImV6TpNiSg==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/postcss/"
|
||||
},
|
||||
{
|
||||
"type": "tidelift",
|
||||
"url": "https://tidelift.com/funding/github/npm/postcss"
|
||||
}
|
||||
],
|
||||
"dependencies": {
|
||||
"nanoid": "^3.3.1",
|
||||
"picocolors": "^1.0.0",
|
||||
@ -6933,10 +6953,6 @@
|
||||
},
|
||||
"engines": {
|
||||
"node": "^10 || ^12 || >=14"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/postcss/"
|
||||
}
|
||||
},
|
||||
"node_modules/postcss-calc": {
|
||||
@ -9575,9 +9591,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/zrender": {
|
||||
"version": "5.3.0",
|
||||
"resolved": "https://registry.npmjs.org/zrender/-/zrender-5.3.0.tgz",
|
||||
"integrity": "sha512-Ln2QB5uqI1ftNYMtCRxd+XDq6MOttLgam2tmhKAVA+j0ko47UT+VNlDvKTkqe4K2sJhBvB0EhYNLebqlCTjatQ==",
|
||||
"version": "5.3.1",
|
||||
"resolved": "https://registry.npmjs.org/zrender/-/zrender-5.3.1.tgz",
|
||||
"integrity": "sha512-7olqIjy0gWfznKr6vgfnGBk7y4UtdMvdwFmK92vVQsQeDPyzkHW1OlrLEKg6GHz1W5ePf0FeN1q2vkl/HFqhXw==",
|
||||
"dependencies": {
|
||||
"tslib": "2.3.0"
|
||||
}
|
||||
@ -10699,28 +10715,20 @@
|
||||
"integrity": "sha512-ws57AidsDvREKrZKYffXddNkyaF14iHNHm8VQnZH6t99E8gczjNN0GpvcGny0imC80yQ0tHz1xVUKk/KFQSUyA=="
|
||||
},
|
||||
"@eslint/eslintrc": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.0.tgz",
|
||||
"integrity": "sha512-igm9SjJHNEJRiUnecP/1R5T3wKLEJ7pL6e2P+GUSfCd0dGjPYYZve08uzw8L2J8foVHFz+NGu12JxRcU2gGo6w==",
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.2.1.tgz",
|
||||
"integrity": "sha512-bxvbYnBPN1Gibwyp6NrpnFzA3YtRL3BBAyEAFVIpNTm2Rn4Vy87GA5M4aSn3InRrlsbX5N0GW7XIx+U4SAEKdQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ajv": "^6.12.4",
|
||||
"debug": "^4.3.2",
|
||||
"espree": "^9.3.1",
|
||||
"globals": "^13.9.0",
|
||||
"ignore": "^4.0.6",
|
||||
"ignore": "^5.2.0",
|
||||
"import-fresh": "^3.2.1",
|
||||
"js-yaml": "^4.1.0",
|
||||
"minimatch": "^3.0.4",
|
||||
"strip-json-comments": "^3.1.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"ignore": {
|
||||
"version": "4.0.6",
|
||||
"resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
|
||||
"integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"@headlessui/vue": {
|
||||
@ -10730,9 +10738,9 @@
|
||||
"requires": {}
|
||||
},
|
||||
"@heroicons/vue": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@heroicons/vue/-/vue-1.0.5.tgz",
|
||||
"integrity": "sha512-idWtp20Fjr7mqnD7EdGDUDi83oWHnx3SwyuQY6GZyF33OApzpBOLxz7xa4t6rPOddGz9tI5RGnndLk+ake7ijQ==",
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@heroicons/vue/-/vue-1.0.6.tgz",
|
||||
"integrity": "sha512-ng2YcCQrdoQWEFpw+ipFl2rZo8mZ56v0T5+MyfQQvNqfKChwgP6DMloZLW+rl17GEcHkE3H82UTAMKBKZr4+WA==",
|
||||
"requires": {}
|
||||
},
|
||||
"@humanwhocodes/config-array": {
|
||||
@ -10837,9 +10845,9 @@
|
||||
"integrity": "sha512-92FRmppjjqz29VMJ2dn+xdyXZBrMlE42AV6Kq6BwjWV7CNUW1hs2FtxSNLQE+gJhaZ6AAmYuO9y8dshhcBl7vA=="
|
||||
},
|
||||
"@tailwindcss/forms": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@tailwindcss/forms/-/forms-0.4.0.tgz",
|
||||
"integrity": "sha512-DeaQBx6EgEeuZPQACvC+mKneJsD8am1uiJugjgQK1+/Vt+Ai0GpFBC2T2fqnUad71WgOxyrZPE6BG1VaI6YqfQ==",
|
||||
"version": "0.5.0",
|
||||
"resolved": "https://registry.npmjs.org/@tailwindcss/forms/-/forms-0.5.0.tgz",
|
||||
"integrity": "sha512-KzWugryEBFkmoaYcBE18rs6gthWCFHHO7cAZm2/hv3hwD67AzwP7udSCa22E7R1+CEJL/FfhYsJWrc0b1aeSzw==",
|
||||
"requires": {
|
||||
"mini-svg-data-uri": "^1.2.3"
|
||||
}
|
||||
@ -11585,22 +11593,22 @@
|
||||
}
|
||||
},
|
||||
"autoprefixer": {
|
||||
"version": "10.4.2",
|
||||
"resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.2.tgz",
|
||||
"integrity": "sha512-9fOPpHKuDW1w/0EKfRmVnxTDt8166MAnLI3mgZ1JCnhNtYWxcJ6Ud5CO/AVOZi/AvFa8DY9RTy3h3+tFBlrrdQ==",
|
||||
"version": "10.4.4",
|
||||
"resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.4.tgz",
|
||||
"integrity": "sha512-Tm8JxsB286VweiZ5F0anmbyGiNI3v3wGv3mz9W+cxEDYB/6jbnj6GM9H9mK3wIL8ftgl+C07Lcwb8PG5PCCPzA==",
|
||||
"requires": {
|
||||
"browserslist": "^4.19.1",
|
||||
"caniuse-lite": "^1.0.30001297",
|
||||
"fraction.js": "^4.1.2",
|
||||
"browserslist": "^4.20.2",
|
||||
"caniuse-lite": "^1.0.30001317",
|
||||
"fraction.js": "^4.2.0",
|
||||
"normalize-range": "^0.1.2",
|
||||
"picocolors": "^1.0.0",
|
||||
"postcss-value-parser": "^4.2.0"
|
||||
}
|
||||
},
|
||||
"axios": {
|
||||
"version": "0.26.0",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-0.26.0.tgz",
|
||||
"integrity": "sha512-lKoGLMYtHvFrPVt3r+RBMp9nh34N0M8zEfCWqdWZx6phynIEhQqAdydpyBAAG211zlhX9Rgu08cOamy6XjE5Og==",
|
||||
"version": "0.26.1",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-0.26.1.tgz",
|
||||
"integrity": "sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==",
|
||||
"requires": {
|
||||
"follow-redirects": "^1.14.8"
|
||||
}
|
||||
@ -11855,12 +11863,12 @@
|
||||
}
|
||||
},
|
||||
"browserslist": {
|
||||
"version": "4.19.3",
|
||||
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.19.3.tgz",
|
||||
"integrity": "sha512-XK3X4xtKJ+Txj8G5c30B4gsm71s69lqXlkYui4s6EkKxuv49qjYlY6oVd+IFJ73d4YymtM3+djvvt/R/iJwwDg==",
|
||||
"version": "4.20.2",
|
||||
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.20.2.tgz",
|
||||
"integrity": "sha512-CQOBCqp/9pDvDbx3xfMi+86pr4KXIf2FDkTTdeuYw8OxS9t898LA1Khq57gtufFILXpfgsSx5woNgsBgvGjpsA==",
|
||||
"requires": {
|
||||
"caniuse-lite": "^1.0.30001312",
|
||||
"electron-to-chromium": "^1.4.71",
|
||||
"caniuse-lite": "^1.0.30001317",
|
||||
"electron-to-chromium": "^1.4.84",
|
||||
"escalade": "^3.1.1",
|
||||
"node-releases": "^2.0.2",
|
||||
"picocolors": "^1.0.0"
|
||||
@ -11941,9 +11949,9 @@
|
||||
}
|
||||
},
|
||||
"caniuse-lite": {
|
||||
"version": "1.0.30001312",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001312.tgz",
|
||||
"integrity": "sha512-Wiz1Psk2MEK0pX3rUzWaunLTZzqS2JYZFzNKqAiJGiuxIjRPLgV6+VDPOg6lQOUxmDwhTlh198JsTTi8Hzw6aQ=="
|
||||
"version": "1.0.30001320",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001320.tgz",
|
||||
"integrity": "sha512-MWPzG54AGdo3nWx7zHZTefseM5Y1ccM7hlQKHRqJkPozUaw3hNbBTMmLn16GG2FUzjR13Cr3NPfhIieX5PzXDA=="
|
||||
},
|
||||
"chalk": {
|
||||
"version": "4.1.2",
|
||||
@ -12730,12 +12738,12 @@
|
||||
"integrity": "sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA=="
|
||||
},
|
||||
"echarts": {
|
||||
"version": "5.3.0",
|
||||
"resolved": "https://registry.npmjs.org/echarts/-/echarts-5.3.0.tgz",
|
||||
"integrity": "sha512-zENufmwFE6WjM+24tW3xQq4ICqQtI0CGj4bDVDNd3BK3LtaA/5wBp+64ykIyKy3QElz0cieKqSYP4FX9Lv9MwQ==",
|
||||
"version": "5.3.1",
|
||||
"resolved": "https://registry.npmjs.org/echarts/-/echarts-5.3.1.tgz",
|
||||
"integrity": "sha512-nWdlbgX3OVY0hpqncSvp0gDt1FRSKWn7lsWEH+PHmfCuvE0QmSw17pczQvm8AvawnLEkmf1Cts7YwQJZNC0AEQ==",
|
||||
"requires": {
|
||||
"tslib": "2.3.0",
|
||||
"zrender": "5.3.0"
|
||||
"zrender": "5.3.1"
|
||||
}
|
||||
},
|
||||
"ee-first": {
|
||||
@ -12744,9 +12752,9 @@
|
||||
"integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
|
||||
},
|
||||
"electron-to-chromium": {
|
||||
"version": "1.4.75",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.75.tgz",
|
||||
"integrity": "sha512-LxgUNeu3BVU7sXaKjUDD9xivocQLxFtq6wgERrutdY/yIOps3ODOZExK1jg8DTEg4U8TUCb5MLGeWFOYuxjF3Q=="
|
||||
"version": "1.4.92",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.92.tgz",
|
||||
"integrity": "sha512-YAVbvQIcDE/IJ/vzDMjD484/hsRbFPW2qXJPaYTfOhtligmfYEYOep+5QojpaEU9kq6bMvNeC2aG7arYvTHYsA=="
|
||||
},
|
||||
"elliptic": {
|
||||
"version": "6.5.4",
|
||||
@ -12833,12 +12841,12 @@
|
||||
"dev": true
|
||||
},
|
||||
"eslint": {
|
||||
"version": "8.10.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.10.0.tgz",
|
||||
"integrity": "sha512-tcI1D9lfVec+R4LE1mNDnzoJ/f71Kl/9Cv4nG47jOueCMBrCCKYXr4AUVS7go6mWYGFD4+EoN6+eXSrEbRzXVw==",
|
||||
"version": "8.11.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.11.0.tgz",
|
||||
"integrity": "sha512-/KRpd9mIRg2raGxHRGwW9ZywYNAClZrHjdueHcrVDuO3a6bj83eoTirCCk0M0yPwOjWYKHwRVRid+xK4F/GHgA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@eslint/eslintrc": "^1.2.0",
|
||||
"@eslint/eslintrc": "^1.2.1",
|
||||
"@humanwhocodes/config-array": "^0.9.2",
|
||||
"ajv": "^6.10.0",
|
||||
"chalk": "^4.0.0",
|
||||
@ -13251,9 +13259,9 @@
|
||||
}
|
||||
},
|
||||
"flatpickr": {
|
||||
"version": "4.6.9",
|
||||
"resolved": "https://registry.npmjs.org/flatpickr/-/flatpickr-4.6.9.tgz",
|
||||
"integrity": "sha512-F0azNNi8foVWKSF+8X+ZJzz8r9sE1G4hl06RyceIaLvyltKvDl6vqk9Lm/6AUUCi5HWaIjiUbk7UpeE/fOXOpw=="
|
||||
"version": "4.6.11",
|
||||
"resolved": "https://registry.npmjs.org/flatpickr/-/flatpickr-4.6.11.tgz",
|
||||
"integrity": "sha512-/rnbE/hu5I5zndLEyYfYvqE4vPDvI5At0lFcQA5eOPfjquZLcQ0HMKTL7rv5/+DvbPM3/vJcXpXjB/DjBh+1jw=="
|
||||
},
|
||||
"flatted": {
|
||||
"version": "3.2.5",
|
||||
@ -13272,9 +13280,9 @@
|
||||
"integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow=="
|
||||
},
|
||||
"fraction.js": {
|
||||
"version": "4.1.3",
|
||||
"resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.1.3.tgz",
|
||||
"integrity": "sha512-pUHWWt6vHzZZiQJcM6S/0PXfS+g6FM4BF5rj9wZyreivhQPdsh5PpE25VtSNxq80wHS5RfY51Ii+8Z0Zl/pmzg=="
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.2.0.tgz",
|
||||
"integrity": "sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA=="
|
||||
},
|
||||
"fresh": {
|
||||
"version": "0.5.2",
|
||||
@ -13370,9 +13378,9 @@
|
||||
"integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw=="
|
||||
},
|
||||
"globals": {
|
||||
"version": "13.12.1",
|
||||
"resolved": "https://registry.npmjs.org/globals/-/globals-13.12.1.tgz",
|
||||
"integrity": "sha512-317dFlgY2pdJZ9rspXDks7073GpDmXdfbM3vYYp0HAMKGDh1FfWPleI2ljVNLQX5M5lXcAslTcPTrOrMEFOjyw==",
|
||||
"version": "13.13.0",
|
||||
"resolved": "https://registry.npmjs.org/globals/-/globals-13.13.0.tgz",
|
||||
"integrity": "sha512-EQ7Q18AJlPwp3vUDL4mKA0KXrXyNIQyWon6T6XQiBQF0XHvRsiCSrWmmeATpUzdJN2HhWZU6Pdl0a9zdep5p6A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"type-fest": "^0.20.2"
|
||||
@ -14774,9 +14782,9 @@
|
||||
}
|
||||
},
|
||||
"postcss": {
|
||||
"version": "8.4.7",
|
||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.7.tgz",
|
||||
"integrity": "sha512-L9Ye3r6hkkCeOETQX6iOaWZgjp3LL6Lpqm6EtgbKrgqGGteRMNb9vzBfRL96YOSu8o7x3MfIH9Mo5cPJFGrW6A==",
|
||||
"version": "8.4.12",
|
||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.12.tgz",
|
||||
"integrity": "sha512-lg6eITwYe9v6Hr5CncVbK70SoioNQIq81nsaG86ev5hAidQvmOeETBqs7jm43K2F5/Ley3ytDtriImV6TpNiSg==",
|
||||
"requires": {
|
||||
"nanoid": "^3.3.1",
|
||||
"picocolors": "^1.0.0",
|
||||
@ -16615,9 +16623,9 @@
|
||||
"integrity": "sha512-9BK1jFpLzJROCI5TzwZL/TU4gqjK5xiHV/RfWLOahrjAko/e4DJkRDZQXfvqAsiZzzYhgAzbgz6lg48jcm4GLg=="
|
||||
},
|
||||
"zrender": {
|
||||
"version": "5.3.0",
|
||||
"resolved": "https://registry.npmjs.org/zrender/-/zrender-5.3.0.tgz",
|
||||
"integrity": "sha512-Ln2QB5uqI1ftNYMtCRxd+XDq6MOttLgam2tmhKAVA+j0ko47UT+VNlDvKTkqe4K2sJhBvB0EhYNLebqlCTjatQ==",
|
||||
"version": "5.3.1",
|
||||
"resolved": "https://registry.npmjs.org/zrender/-/zrender-5.3.1.tgz",
|
||||
"integrity": "sha512-7olqIjy0gWfznKr6vgfnGBk7y4UtdMvdwFmK92vVQsQeDPyzkHW1OlrLEKg6GHz1W5ePf0FeN1q2vkl/HFqhXw==",
|
||||
"requires": {
|
||||
"tslib": "2.3.0"
|
||||
}
|
||||
|
16
package.json
16
package.json
@ -14,22 +14,22 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@headlessui/vue": "^1.5.0",
|
||||
"@heroicons/vue": "^1.0.5",
|
||||
"@heroicons/vue": "^1.0.6",
|
||||
"@inertiajs/inertia": "^0.11.0",
|
||||
"@inertiajs/inertia-vue3": "^0.6.0",
|
||||
"@inertiajs/progress": "^0.2.7",
|
||||
"@tailwindcss/forms": "^0.4.0",
|
||||
"@tailwindcss/forms": "^0.5.0",
|
||||
"@tailwindcss/line-clamp": "^0.3.1",
|
||||
"@tailwindcss/typography": "^0.5.2",
|
||||
"@vue/compiler-sfc": "^3.2.31",
|
||||
"autoprefixer": "^10.4.2",
|
||||
"axios": "^0.26.0",
|
||||
"echarts": "^5.3.0",
|
||||
"autoprefixer": "^10.4.4",
|
||||
"axios": "^0.26.1",
|
||||
"echarts": "^5.3.1",
|
||||
"eslit": "^6.0.0",
|
||||
"flatpickr": "^4.6.9",
|
||||
"flatpickr": "^4.6.11",
|
||||
"laravel-mix": "^6.0.43",
|
||||
"lodash": "^4.17.21",
|
||||
"postcss": "^8.4.7",
|
||||
"postcss": "^8.4.12",
|
||||
"tailwindcss": "^3.0.23",
|
||||
"vue": "^3.2.31",
|
||||
"vue-echarts": "^6.0.2",
|
||||
@ -40,7 +40,7 @@
|
||||
"vue3-popper": "^1.4.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"eslint": "^8.10.0",
|
||||
"eslint": "^8.11.0",
|
||||
"eslint-plugin-vue": "^8.5.0"
|
||||
}
|
||||
}
|
||||
|
@ -2,50 +2,62 @@ const months = [
|
||||
{
|
||||
'name': 'Styczeń',
|
||||
'value': 'january',
|
||||
'shortcut': 'Sty',
|
||||
},
|
||||
{
|
||||
'name': 'Luty',
|
||||
'value': 'february',
|
||||
'shortcut': 'Lut',
|
||||
},
|
||||
{
|
||||
'name': 'Marzec',
|
||||
'value': 'march',
|
||||
'shortcut': 'Mar',
|
||||
},
|
||||
{
|
||||
'name': 'Kwiecień',
|
||||
'value': 'april',
|
||||
'shortcut': 'Kwi',
|
||||
},
|
||||
{
|
||||
'name': 'Maj',
|
||||
'value': 'may',
|
||||
'shortcut':'Maj',
|
||||
},
|
||||
{
|
||||
'name': 'Czerwiec',
|
||||
'value': 'june',
|
||||
'shortcut': 'Cze',
|
||||
},
|
||||
{
|
||||
'name': 'Lipiec',
|
||||
'value': 'july',
|
||||
'shortcut': 'Lip',
|
||||
},
|
||||
{
|
||||
'name': 'Sierpień',
|
||||
'value': 'august',
|
||||
'shortcut': 'Sie',
|
||||
},
|
||||
{
|
||||
'name': 'Wrzesień',
|
||||
'value': 'september',
|
||||
'shortcut': 'Wrz',
|
||||
},
|
||||
{
|
||||
'name': 'Październik',
|
||||
'value': 'october',
|
||||
'shortcut': 'Paź',
|
||||
},
|
||||
{
|
||||
'name': 'Listopad',
|
||||
'value': 'november',
|
||||
'shortcut': 'Lis',
|
||||
},
|
||||
{
|
||||
'name': 'Grudzień',
|
||||
'value': 'december',
|
||||
'shortcut': 'Gru',
|
||||
},
|
||||
]
|
||||
|
||||
|
@ -22,7 +22,7 @@
|
||||
<div class="border-t border-gray-200">
|
||||
<div class="overflow-x-auto xl:overflow-x-visible overflow-y-auto xl:overflow-y-visible">
|
||||
<table class="min-w-full divide-y divide-gray-200">
|
||||
<thead class="bg-gray-100">
|
||||
<thead class="bg-gray-50">
|
||||
<tr>
|
||||
<th
|
||||
scope="col"
|
||||
|
94
resources/js/Pages/MonthlyUsage.vue
Normal file
94
resources/js/Pages/MonthlyUsage.vue
Normal file
@ -0,0 +1,94 @@
|
||||
<template>
|
||||
<InertiaHead title="Wykorzystanie miesięczne urlopu" />
|
||||
<div class="bg-white shadow-md">
|
||||
<div class="flex justify-between items-center p-4 sm:px-6">
|
||||
<div class="flex items-center">
|
||||
<h2 class="text-lg leading-6 font-medium text-gray-900">
|
||||
Wykorzystanie miesięczne urlopu wypoczynkowego
|
||||
</h2>
|
||||
</div>
|
||||
</div>
|
||||
<div class="border-t border-gray-200">
|
||||
<div class="overflow-x-auto xl:overflow-x-visible overflow-y-hidden">
|
||||
<table class="min-w-full divide-y divide-gray-200">
|
||||
<thead class="bg-gray-50">
|
||||
<tr>
|
||||
<th class="w-64 px-6 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider text-left">
|
||||
Pracownik
|
||||
</th>
|
||||
<th
|
||||
v-for="month in months"
|
||||
:key="month"
|
||||
class="px-6 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider text-center"
|
||||
:class="{'bg-blumilk-50': isCurrentMonth(month)}"
|
||||
style="min-width: 46px;"
|
||||
>
|
||||
<span :class="{'text-blumilk-600': isCurrentMonth(month)}">
|
||||
{{ month.shortcut }}
|
||||
</span>
|
||||
</th>
|
||||
<th class="px-6 py-3 text-left text-xs font-semibold text-gray-500 uppercase tracking-wider text-center">
|
||||
Wykorzystanie urlopu
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="bg-white divide-y divide-gray-100">
|
||||
<tr
|
||||
v-for="item in monthlyUsage"
|
||||
:key="item.user.id"
|
||||
class="hover:bg-blumilk-25"
|
||||
>
|
||||
<th class="px-4 py-4 whitespace-nowrap text-sm text-gray-500 font-semibold capitalize">
|
||||
<div class="flex justify-start items-center">
|
||||
<span class="inline-flex items-center justify-center h-10 w-10 rounded-full">
|
||||
<img
|
||||
class="h-10 w-10 rounded-full"
|
||||
:src="item.user.avatar"
|
||||
>
|
||||
</span>
|
||||
<div class="ml-3">
|
||||
<div
|
||||
class="text-sm font-medium text-gray-900 whitespace-nowrap"
|
||||
>
|
||||
{{ item.user.name }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</th>
|
||||
<td
|
||||
v-for="month in months"
|
||||
:key="month.value"
|
||||
class="px-4 py-4 text-sm text-gray-500 font-semibold text-center"
|
||||
:class="{'bg-blumilk-25': isCurrentMonth(month)}"
|
||||
>
|
||||
{{ item.months[month.value] ?? '-' }}
|
||||
</td>
|
||||
<td class="px-4 py-4 text-sm text-gray-500 font-semibold text-center">
|
||||
<div style="min-width: 300px;">
|
||||
<VacationBar :stats="{ used: item.stats.used, pending: item.stats.pending, remaining: item.stats.remaining }" />
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { useMonthInfo } from '@/Composables/monthInfo'
|
||||
import VacationBar from '@/Shared/VacationBar'
|
||||
|
||||
const props = defineProps({
|
||||
monthlyUsage: Object,
|
||||
currentMonth: String,
|
||||
})
|
||||
|
||||
const { getMonths } = useMonthInfo()
|
||||
const months = getMonths()
|
||||
|
||||
function isCurrentMonth(month) {
|
||||
return props.currentMonth === month.value
|
||||
}
|
||||
</script>
|
@ -11,6 +11,7 @@
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="border-t border-gray-200">
|
||||
<div class="overflow-x-auto xl:overflow-x-visible overflow-y-auto xl:overflow-y-visible">
|
||||
<form @submit.prevent="submitVacationDays">
|
||||
<table class="min-w-full divide-y divide-gray-200">
|
||||
@ -130,6 +131,7 @@
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
|
@ -15,7 +15,7 @@
|
||||
<script setup>
|
||||
import MainMenu from '@/Shared/MainMenu'
|
||||
import { useToast } from 'vue-toastification'
|
||||
import { defineProps, watch } from 'vue'
|
||||
import { watch } from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
flash: Object,
|
||||
@ -30,6 +30,10 @@ watch(() => props.flash, flash => {
|
||||
toast.success(flash.success)
|
||||
}
|
||||
|
||||
if (flash.info) {
|
||||
toast.info(flash.info)
|
||||
}
|
||||
|
||||
if (flash.error) {
|
||||
toast.error(flash.error)
|
||||
}
|
||||
|
@ -268,7 +268,9 @@ import {
|
||||
XIcon,
|
||||
SunIcon,
|
||||
StarIcon,
|
||||
CalendarIcon, DocumentTextIcon,
|
||||
CalendarIcon,
|
||||
DocumentTextIcon,
|
||||
AdjustmentsIcon,
|
||||
} from '@heroicons/vue/outline'
|
||||
import { CheckIcon, ChevronDownIcon } from '@heroicons/vue/solid'
|
||||
|
||||
@ -302,6 +304,13 @@ const navigation = computed(() =>
|
||||
icon: CalendarIcon,
|
||||
can: true,
|
||||
},
|
||||
{
|
||||
name: 'Wykorzystanie urlopu',
|
||||
href: '/monthly-usage',
|
||||
component: 'MonthlyUsage',
|
||||
icon: AdjustmentsIcon,
|
||||
can: props.auth.can.listMonthlyUsage,
|
||||
},
|
||||
{
|
||||
name: 'Dni wolne',
|
||||
href: '/holidays',
|
||||
|
84
resources/js/Shared/VacationBar.vue
Normal file
84
resources/js/Shared/VacationBar.vue
Normal file
@ -0,0 +1,84 @@
|
||||
<template>
|
||||
<Popper
|
||||
hover
|
||||
class="h-full w-full"
|
||||
>
|
||||
<div class="flex bg-white text-white">
|
||||
<div
|
||||
v-show="stats.used > 0"
|
||||
:style="`background-color: ${colors.used}; flex-basis: ${calculatePercent(stats.used)}%;`"
|
||||
class="flex items-center justify-center py-2 px-0.5"
|
||||
>
|
||||
<strong>{{ stats.used }}</strong>
|
||||
</div>
|
||||
<div
|
||||
v-show="stats.pending > 0"
|
||||
:style="`background-color: ${colors.pending}; flex-basis: ${calculatePercent(stats.pending)}%;`"
|
||||
class="flex items-center justify-center py-2 px-0.5"
|
||||
>
|
||||
<strong>{{ stats.pending }}</strong>
|
||||
</div>
|
||||
<div
|
||||
v-show="stats.remaining > 0"
|
||||
:style="`background-color: ${colors.remaining}; flex-basis: ${calculatePercent(stats.remaining)}%;`"
|
||||
class="flex items-center justify-center py-2 px-0.5"
|
||||
>
|
||||
<strong>{{ stats.remaining }}</strong>
|
||||
</div>
|
||||
</div>
|
||||
<template #content>
|
||||
<div class="px-4 py-2 bg-white text-md text-gray-900 rounded-md shadow-md flext">
|
||||
<div class="flex items-center font-normal">
|
||||
<i
|
||||
class="inline-block w-5 h-3 mr-3"
|
||||
:style="`background-color: ${colors.used}`"
|
||||
/>
|
||||
Wykorzystane:
|
||||
<span class="font-semibold ml-1">{{ stats.used }}</span>
|
||||
</div>
|
||||
<div class="flex items-center font-normal">
|
||||
<i
|
||||
class="inline-block w-5 h-3 mr-3"
|
||||
:style="`background-color: ${colors.pending}`"
|
||||
/>
|
||||
Rozpatrywane:
|
||||
<span class="font-semibold ml-1">{{ stats.pending }}</span>
|
||||
</div>
|
||||
<div class="flex items-center font-normal">
|
||||
<i
|
||||
class="inline-block w-5 h-3 mr-3"
|
||||
:style="`background-color: ${colors.remaining}`"
|
||||
/>
|
||||
Pozostałe:
|
||||
<span class="font-semibold ml-1">{{ stats.remaining }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</Popper>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import Popper from 'vue3-popper'
|
||||
|
||||
const props = defineProps({
|
||||
stats: {
|
||||
type: Object,
|
||||
default: () => ({
|
||||
used: 0,
|
||||
pending: 0,
|
||||
remaining: 0,
|
||||
}),
|
||||
},
|
||||
})
|
||||
|
||||
const colors = {
|
||||
used: '#2C466F',
|
||||
pending: '#AABDDD',
|
||||
remaining: '#527ABA',
|
||||
}
|
||||
|
||||
function calculatePercent(value) {
|
||||
return value / (props.stats.used + props.stats.pending + props.stats.remaining) * 100
|
||||
}
|
||||
|
||||
</script>
|
@ -20,7 +20,8 @@ createInertiaApp({
|
||||
.use(Toast, {
|
||||
position: 'bottom-right',
|
||||
maxToast: 5,
|
||||
|
||||
timeout: 3000,
|
||||
pauseOnFocusLoss: false,
|
||||
})
|
||||
.component('InertiaLink', Link)
|
||||
.component('InertiaHead', Head)
|
||||
|
@ -7,6 +7,7 @@ use Toby\Infrastructure\Http\Controllers\DashboardController;
|
||||
use Toby\Infrastructure\Http\Controllers\GoogleController;
|
||||
use Toby\Infrastructure\Http\Controllers\HolidayController;
|
||||
use Toby\Infrastructure\Http\Controllers\LogoutController;
|
||||
use Toby\Infrastructure\Http\Controllers\MonthlyUsageController;
|
||||
use Toby\Infrastructure\Http\Controllers\SelectYearPeriodController;
|
||||
use Toby\Infrastructure\Http\Controllers\TimesheetController;
|
||||
use Toby\Infrastructure\Http\Controllers\UserController;
|
||||
@ -63,6 +64,8 @@ Route::middleware("auth")->group(function (): void {
|
||||
|
||||
Route::post("year-periods/{yearPeriod}/select", SelectYearPeriodController::class)
|
||||
->name("year-periods.select");
|
||||
|
||||
Route::get("/monthly-usage", MonthlyUsageController::class)->name("monthly-usage");
|
||||
});
|
||||
|
||||
Route::middleware("guest")->group(function (): void {
|
||||
|
Loading…
x
Reference in New Issue
Block a user