From 91980163e00c84ab89fc6693cdcf530d13b10c22 Mon Sep 17 00:00:00 2001 From: EwelinaLasowy Date: Thu, 10 Mar 2022 09:30:33 +0100 Subject: [PATCH 1/3] - polishing calendar --- app/Domain/CalendarGenerator.php | 2 + .../Resources/VacationRequestResource.php | 2 +- package-lock.json | 62 +++++++- package.json | 4 +- resources/js/Composables/vacationTypeInfo.js | 139 ++++++++++++++++++ resources/js/Pages/Calendar.vue | 24 +-- resources/js/Pages/VacationRequest/Index.vue | 8 +- .../VacationRequest/IndexForApprovers.vue | 4 +- resources/js/Pages/VacationRequest/Show.vue | 6 +- resources/js/Shared/VacationType.vue | 38 +++++ .../js/Shared/VacationTypeCalendarIcon.vue | 40 +++++ 11 files changed, 309 insertions(+), 20 deletions(-) create mode 100644 resources/js/Composables/vacationTypeInfo.js create mode 100644 resources/js/Shared/VacationType.vue create mode 100644 resources/js/Shared/VacationTypeCalendarIcon.vue diff --git a/app/Domain/CalendarGenerator.php b/app/Domain/CalendarGenerator.php index 5409284..61313cb 100644 --- a/app/Domain/CalendarGenerator.php +++ b/app/Domain/CalendarGenerator.php @@ -44,6 +44,7 @@ class CalendarGenerator "isWeekend" => $day->isWeekend(), "isHoliday" => $holidays->contains($day), "vacations" => $vacationsForDay->pluck("user_id"), + "vacationTypes" => $vacationsForDay->pluck("vacationRequest.type", "user_id"), ]; } @@ -55,6 +56,7 @@ class CalendarGenerator return Vacation::query() ->whereBetween("date", [$period->start, $period->end]) ->whereRelation("vacationRequest", fn(Builder $query) => $query->states(VacationRequestStatesRetriever::successStates())) + ->with("vacationRequest") ->get() ->groupBy(fn(Vacation $vacation) => $vacation->date->toDateString()); } diff --git a/app/Infrastructure/Http/Resources/VacationRequestResource.php b/app/Infrastructure/Http/Resources/VacationRequestResource.php index 112d7a0..e7d5615 100644 --- a/app/Infrastructure/Http/Resources/VacationRequestResource.php +++ b/app/Infrastructure/Http/Resources/VacationRequestResource.php @@ -16,7 +16,7 @@ class VacationRequestResource extends JsonResource "id" => $this->id, "name" => $this->name, "user" => new UserResource($this->user), - "type" => $this->type->label(), + "type" => $this->type, "state" => $this->state, "from" => $this->from->toDisplayString(), "to" => $this->to->toDisplayString(), diff --git a/package-lock.json b/package-lock.json index eb8a495..929d686 100644 --- a/package-lock.json +++ b/package-lock.json @@ -27,7 +27,9 @@ "vue-echarts": "^6.0.2", "vue-flatpickr-component": "^9.0.5", "vue-loader": "^17.0.0", - "vue-toastification": "^2.0.0-rc.5" + "vue-material-design-icons": "^5.0.0", + "vue-toastification": "^2.0.0-rc.5", + "vue3-popper": "^1.4.2" }, "devDependencies": { "eslint": "^8.10.0", @@ -1820,6 +1822,15 @@ "node": ">= 8" } }, + "node_modules/@popperjs/core": { + "version": "2.11.2", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.2.tgz", + "integrity": "sha512-92FRmppjjqz29VMJ2dn+xdyXZBrMlE42AV6Kq6BwjWV7CNUW1hs2FtxSNLQE+gJhaZ6AAmYuO9y8dshhcBl7vA==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/popperjs" + } + }, "node_modules/@tailwindcss/forms": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/@tailwindcss/forms/-/forms-0.4.0.tgz", @@ -3794,6 +3805,11 @@ "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.19.tgz", "integrity": "sha512-ZVxXaNy28/k3kJg0Fou5MiYpp88j7H9hLZp8PDC3jV0WFjfH5E9xHb56L0W59cPbKbcHXeP4qyT8PrHp8t6LcQ==" }, + "node_modules/debounce": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz", + "integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==" + }, "node_modules/debug": { "version": "4.3.3", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", @@ -8968,6 +8984,11 @@ "node": ">=8.9.0" } }, + "node_modules/vue-material-design-icons": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/vue-material-design-icons/-/vue-material-design-icons-5.0.0.tgz", + "integrity": "sha512-lYSJFW/TyQqmg7MvUbEB8ua1mwWy/v8qve7QJuA/UWUAXC4/yVUdAm4pg/sM9+k5n7VLckBv6ucOROuGBsGPDQ==" + }, "node_modules/vue-style-loader": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/vue-style-loader/-/vue-style-loader-4.1.3.tgz", @@ -8990,6 +9011,21 @@ "vue": "^3.0.2" } }, + "node_modules/vue3-popper": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/vue3-popper/-/vue3-popper-1.4.2.tgz", + "integrity": "sha512-nc5vM//AJ8/DyNetjrrgkkLv7aKVdSsljvqlQ1tWhAV2lgA8tkn8xE6icDd0/kBt0Yo5Li8Pftf0H0C/hNmu1Q==", + "dependencies": { + "@popperjs/core": "^2.9.2", + "debounce": "^1.2.1" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "vue": "^3.2.20" + } + }, "node_modules/watchpack": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.3.1.tgz", @@ -10795,6 +10831,11 @@ "fastq": "^1.6.0" } }, + "@popperjs/core": { + "version": "2.11.2", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.2.tgz", + "integrity": "sha512-92FRmppjjqz29VMJ2dn+xdyXZBrMlE42AV6Kq6BwjWV7CNUW1hs2FtxSNLQE+gJhaZ6AAmYuO9y8dshhcBl7vA==" + }, "@tailwindcss/forms": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/@tailwindcss/forms/-/forms-0.4.0.tgz", @@ -12418,6 +12459,11 @@ "resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.19.tgz", "integrity": "sha512-ZVxXaNy28/k3kJg0Fou5MiYpp88j7H9hLZp8PDC3jV0WFjfH5E9xHb56L0W59cPbKbcHXeP4qyT8PrHp8t6LcQ==" }, + "debounce": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/debounce/-/debounce-1.2.1.tgz", + "integrity": "sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==" + }, "debug": { "version": "4.3.3", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", @@ -16166,6 +16212,11 @@ } } }, + "vue-material-design-icons": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/vue-material-design-icons/-/vue-material-design-icons-5.0.0.tgz", + "integrity": "sha512-lYSJFW/TyQqmg7MvUbEB8ua1mwWy/v8qve7QJuA/UWUAXC4/yVUdAm4pg/sM9+k5n7VLckBv6ucOROuGBsGPDQ==" + }, "vue-style-loader": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/vue-style-loader/-/vue-style-loader-4.1.3.tgz", @@ -16188,6 +16239,15 @@ "integrity": "sha512-q73e5jy6gucEO/U+P48hqX+/qyXDozAGmaGgLFm5tXX4wJBcVsnGp4e/iJqlm9xzHETYOilUuwOUje2Qg1JdwA==", "requires": {} }, + "vue3-popper": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/vue3-popper/-/vue3-popper-1.4.2.tgz", + "integrity": "sha512-nc5vM//AJ8/DyNetjrrgkkLv7aKVdSsljvqlQ1tWhAV2lgA8tkn8xE6icDd0/kBt0Yo5Li8Pftf0H0C/hNmu1Q==", + "requires": { + "@popperjs/core": "^2.9.2", + "debounce": "^1.2.1" + } + }, "watchpack": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.3.1.tgz", diff --git a/package.json b/package.json index 29e809e..ac4b36d 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,9 @@ "vue-echarts": "^6.0.2", "vue-flatpickr-component": "^9.0.5", "vue-loader": "^17.0.0", - "vue-toastification": "^2.0.0-rc.5" + "vue-material-design-icons": "^5.0.0", + "vue-toastification": "^2.0.0-rc.5", + "vue3-popper": "^1.4.2" }, "devDependencies": { "eslint": "^8.10.0", diff --git a/resources/js/Composables/vacationTypeInfo.js b/resources/js/Composables/vacationTypeInfo.js new file mode 100644 index 0000000..2ed8ca2 --- /dev/null +++ b/resources/js/Composables/vacationTypeInfo.js @@ -0,0 +1,139 @@ +import WhiteBalanceSunnyIcon from 'vue-material-design-icons/WhiteBalanceSunny.vue' +import CommentAlertIcon from 'vue-material-design-icons/CommentAlert.vue' +import StarShootingIcon from 'vue-material-design-icons/StarShooting.vue' +import BabyCarriageIcon from 'vue-material-design-icons/BabyCarriage.vue' +import HumanMaleBoardIcon from 'vue-material-design-icons/HumanMaleBoard.vue' +import CurrencyUsdOffIcon from 'vue-material-design-icons/CurrencyUsdOff.vue' +import HandHeartOutlineIcon from 'vue-material-design-icons/HandHeartOutline.vue' +import CalendarCheckIcon from 'vue-material-design-icons/CalendarCheck.vue' +import MedicalBagIcon from 'vue-material-design-icons/MedicalBag.vue' + +const statuses = [ + { + text: 'Urlop wypoczynkowy', + value: 'vacation', + outline: { + icon: WhiteBalanceSunnyIcon, + background: 'bg-white', + foreground: 'text-amber-500', + }, + solid: { + icon: WhiteBalanceSunnyIcon, + color: 'text-amber-500', + }, + }, + { + text: 'Urlop na żądanie', + value: 'vacation_on_request', + outline: { + icon: CommentAlertIcon, + background: 'bg-white', + foreground: 'text-slate-500', + }, + solid: { + icon: CommentAlertIcon, + color: 'text-slate-500', + }, + }, + { + text: 'Urlop okolicznościowy', + value: 'special_vacation', + outline: { + icon: StarShootingIcon, + background: 'bg-white', + foreground: 'text-orange-500', + }, + solid: { + icon: StarShootingIcon, + color: 'text-orange-500', + }, + }, + { + text: 'Opieka nad dzieckiem art 188 kp', + value: 'childcare_vacation', + outline: { + icon: BabyCarriageIcon, + background: 'bg-white', + foreground: 'text-purple-500', + }, + solid: { + icon: BabyCarriageIcon, + color: 'text-purple-500', + }, + }, + { + text: 'Urlop szkoleniowy', + value: 'training_vacation', + outline: { + icon: HumanMaleBoardIcon, + background: 'bg-white', + foreground: 'text-blumilk-500', + }, + solid: { + icon: HumanMaleBoardIcon, + color: 'text-blumilk-500', + }, + }, + { + text: 'Urlop bezpłatny', + value: 'unpaid_vacation', + outline: { + icon: CurrencyUsdOffIcon, + background: 'bg-white', + foreground: 'text-emerald-500', + }, + solid: { + icon: CurrencyUsdOffIcon, + color: 'text-emerald-500', + }, + }, + { + text: 'Wolontariat', + value: 'volunteering_vacation', + outline: { + icon: HandHeartOutlineIcon, + background: 'bg-white', + foreground: 'text-pink-500', + }, + solid: { + icon: HandHeartOutlineIcon, + color: 'text-pink-500', + }, + }, + { + text: 'Odbiór za święto', + value: 'time_in_lieu', + outline: { + icon: CalendarCheckIcon, + background: 'bg-white', + foreground: 'text-stone-500', + }, + solid: { + icon: CalendarCheckIcon, + color: 'text-stone-500', + }, + }, + { + text: 'Zwolnienie lekarskie', + value: 'sick_vacation', + outline: { + icon: MedicalBagIcon, + background: 'bg-white', + foreground: 'text-rose-500', + }, + solid: { + icon: MedicalBagIcon, + color: 'text-rose-500', + }, + }, +] + +export function useVacationTypeInfo() { + const getStatues = () => statuses + const findStatus = value => statuses.find(month => month.value === value) + + return { + getStatues, + findStatus, + } +} diff --git a/resources/js/Pages/Calendar.vue b/resources/js/Pages/Calendar.vue index 4c0ade2..9a36776 100644 --- a/resources/js/Pages/Calendar.vue +++ b/resources/js/Pages/Calendar.vue @@ -106,22 +106,20 @@ v-for="day in calendar" :key="day.dayOfMonth" class="border border-gray-300" - :class="{'bg-red-100': day.isWeekend || day.isHoliday, 'bg-blumilk-500': day.vacations.includes(user.id) }" + :class="{'bg-red-100': day.isWeekend || day.isHoliday }" >
- - - + + + +
@@ -136,16 +134,20 @@ import {Menu, MenuButton, MenuItem, MenuItems} from '@headlessui/vue' import {CheckIcon, ChevronDownIcon} from '@heroicons/vue/solid' import {computed} from 'vue' import {useMonthInfo} from '@/Composables/monthInfo' +import VacationTypeCalendarIcon from '@/Shared/VacationTypeCalendarIcon' +import Popper from 'vue3-popper' export default { name: 'VacationCalendar', components: { + VacationTypeCalendarIcon, Menu, MenuButton, MenuItem, MenuItems, CheckIcon, ChevronDownIcon, + Popper, }, props: { users: { diff --git a/resources/js/Pages/VacationRequest/Index.vue b/resources/js/Pages/VacationRequest/Index.vue index 600dec2..c59ad2d 100644 --- a/resources/js/Pages/VacationRequest/Index.vue +++ b/resources/js/Pages/VacationRequest/Index.vue @@ -1,10 +1,10 @@ @@ -249,10 +249,12 @@ import {PaperClipIcon} from '@heroicons/vue/outline' import Activity from '@/Shared/Activity' import Status from '@/Shared/Status' +import VacationType from '@/Shared/VacationType' export default { name: 'VacationRequestShow', components: { + VacationType, Activity, PaperClipIcon, Status, diff --git a/resources/js/Shared/VacationType.vue b/resources/js/Shared/VacationType.vue new file mode 100644 index 0000000..cde127b --- /dev/null +++ b/resources/js/Shared/VacationType.vue @@ -0,0 +1,38 @@ + + + diff --git a/resources/js/Shared/VacationTypeCalendarIcon.vue b/resources/js/Shared/VacationTypeCalendarIcon.vue new file mode 100644 index 0000000..fd28020 --- /dev/null +++ b/resources/js/Shared/VacationTypeCalendarIcon.vue @@ -0,0 +1,40 @@ + + + From 1843451f3f19819210de9412b271e8f82b8eae72 Mon Sep 17 00:00:00 2001 From: Adrian Hopek Date: Mon, 14 Mar 2022 14:20:36 +0100 Subject: [PATCH 2/3] wip --- resources/js/Composables/statusInfo.js | 2 +- resources/js/Composables/vacationTypeInfo.js | 10 ++--- resources/js/Pages/Calendar.vue | 11 +----- resources/js/Pages/Dashboard.vue | 8 +++- resources/js/Pages/VacationRequest/Index.vue | 2 +- .../VacationRequest/IndexForApprovers.vue | 2 +- resources/js/Pages/VacationRequest/Show.vue | 2 +- resources/js/Shared/VacationType.vue | 6 +-- .../js/Shared/VacationTypeCalendarIcon.vue | 37 ++++++++++++------- 9 files changed, 43 insertions(+), 37 deletions(-) diff --git a/resources/js/Composables/statusInfo.js b/resources/js/Composables/statusInfo.js index 91e7ceb..a9c94bd 100644 --- a/resources/js/Composables/statusInfo.js +++ b/resources/js/Composables/statusInfo.js @@ -125,7 +125,7 @@ const statuses = [ export function useStatusInfo() { const getStatues = () => statuses - const findStatus = value => statuses.find(month => month.value === value) + const findStatus = value => statuses.find(status => status.value === value) return { getStatues, diff --git a/resources/js/Composables/vacationTypeInfo.js b/resources/js/Composables/vacationTypeInfo.js index 2ed8ca2..267f480 100644 --- a/resources/js/Composables/vacationTypeInfo.js +++ b/resources/js/Composables/vacationTypeInfo.js @@ -8,7 +8,7 @@ import HandHeartOutlineIcon from 'vue-material-design-icons/HandHeartOutline.vue import CalendarCheckIcon from 'vue-material-design-icons/CalendarCheck.vue' import MedicalBagIcon from 'vue-material-design-icons/MedicalBag.vue' -const statuses = [ +const types = [ { text: 'Urlop wypoczynkowy', value: 'vacation', @@ -129,11 +129,11 @@ const statuses = [ ] export function useVacationTypeInfo() { - const getStatues = () => statuses - const findStatus = value => statuses.find(month => month.value === value) + const getTypes = () => types + const findType = value => types.find(type => type.value === value) return { - getStatues, - findStatus, + getTypes, + findType, } } diff --git a/resources/js/Pages/Calendar.vue b/resources/js/Pages/Calendar.vue index 9a36776..0134352 100644 --- a/resources/js/Pages/Calendar.vue +++ b/resources/js/Pages/Calendar.vue @@ -112,14 +112,7 @@ v-if="day.vacations.includes(user.id)" class="flex justify-center items-center" > - - - - + @@ -135,7 +128,6 @@ import {CheckIcon, ChevronDownIcon} from '@heroicons/vue/solid' import {computed} from 'vue' import {useMonthInfo} from '@/Composables/monthInfo' import VacationTypeCalendarIcon from '@/Shared/VacationTypeCalendarIcon' -import Popper from 'vue3-popper' export default { name: 'VacationCalendar', @@ -147,7 +139,6 @@ export default { MenuItems, CheckIcon, ChevronDownIcon, - Popper, }, props: { users: { diff --git a/resources/js/Pages/Dashboard.vue b/resources/js/Pages/Dashboard.vue index caced10..2f2793f 100644 --- a/resources/js/Pages/Dashboard.vue +++ b/resources/js/Pages/Dashboard.vue @@ -119,7 +119,7 @@ class="hover:underline focus:outline-none" > - Wniosek o {{ request.type.toLowerCase() }} + Wniosek o {{ findType(request.type).text.toLowerCase() }} [{{ request.name }}] @@ -185,7 +185,7 @@ class="hover:underline focus:outline-none" > - Wniosek o {{ request.type.toLowerCase() }} + Wniosek o {{ findType(request.type).text.toLowerCase() }} [{{ request.name }}] @@ -302,6 +302,7 @@ import {computed} from 'vue' import {usePage} from '@inertiajs/inertia-vue3' import Status from '@/Shared/Status' import VacationChart from '@/Shared/VacationChart' +import {useVacationTypeInfo} from '@/Composables/vacationTypeInfo' export default { name: 'DashboardPage', @@ -335,8 +336,11 @@ export default { setup() { const user = computed(() => usePage().props.value.auth.user) + const { findType } = useVacationTypeInfo() + return { user, + findType, } }, } diff --git a/resources/js/Pages/VacationRequest/Index.vue b/resources/js/Pages/VacationRequest/Index.vue index c59ad2d..5b7d0bc 100644 --- a/resources/js/Pages/VacationRequest/Index.vue +++ b/resources/js/Pages/VacationRequest/Index.vue @@ -85,7 +85,7 @@ - + {{ request.from }} diff --git a/resources/js/Pages/VacationRequest/IndexForApprovers.vue b/resources/js/Pages/VacationRequest/IndexForApprovers.vue index 599fd06..69adae8 100644 --- a/resources/js/Pages/VacationRequest/IndexForApprovers.vue +++ b/resources/js/Pages/VacationRequest/IndexForApprovers.vue @@ -247,7 +247,7 @@ - + {{ request.from }} diff --git a/resources/js/Pages/VacationRequest/Show.vue b/resources/js/Pages/VacationRequest/Show.vue index c6e3162..7c65269 100644 --- a/resources/js/Pages/VacationRequest/Show.vue +++ b/resources/js/Pages/VacationRequest/Show.vue @@ -44,7 +44,7 @@ Rodzaj urlopu
- +
diff --git a/resources/js/Shared/VacationType.vue b/resources/js/Shared/VacationType.vue index cde127b..4bc7162 100644 --- a/resources/js/Shared/VacationType.vue +++ b/resources/js/Shared/VacationType.vue @@ -16,7 +16,7 @@ import {useVacationTypeInfo} from '@/Composables/vacationTypeInfo' export default { name: 'VacationType', props: { - status: { + type: { type: String, default: () => null, }, @@ -26,9 +26,9 @@ export default { }, }, setup(props) { - const { findStatus } = useVacationTypeInfo() + const { findType } = useVacationTypeInfo() - const vacationTypeInfo = computed(() => findStatus(props.status)) + const vacationTypeInfo = computed(() => findType(props.type)) return { vacationTypeInfo, diff --git a/resources/js/Shared/VacationTypeCalendarIcon.vue b/resources/js/Shared/VacationTypeCalendarIcon.vue index fd28020..0d92605 100644 --- a/resources/js/Shared/VacationTypeCalendarIcon.vue +++ b/resources/js/Shared/VacationTypeCalendarIcon.vue @@ -1,24 +1,35 @@