From 83edea0afae7cb6b82bcf1203d308d1550d5cfb1 Mon Sep 17 00:00:00 2001 From: Apoorv Tiwari Date: Fri, 19 Apr 2024 13:56:52 +0530 Subject: [PATCH 1/4] Send client member emails for payment reminders (#1813) send client reminder emails on client show --- app/controllers/internal_api/v1/clients_controller.rb | 3 ++- app/controllers/internal_api/v1/invoices_controller.rb | 2 +- .../Clients/Modals/PaymentReminder/MobileView/index.tsx | 2 +- app/views/internal_api/v1/clients/show.json.jbuilder | 1 + 4 files changed, 5 insertions(+), 3 deletions(-) diff --git a/app/controllers/internal_api/v1/clients_controller.rb b/app/controllers/internal_api/v1/clients_controller.rb index 197cff3561..fdc00906b8 100644 --- a/app/controllers/internal_api/v1/clients_controller.rb +++ b/app/controllers/internal_api/v1/clients_controller.rb @@ -31,6 +31,7 @@ def show render locals: { client_details: Client::ShowPresenter.new(client).process, + client_member_emails: client.send_invoice_emails(@virtual_verified_invitations_allowed), project_details: client.project_details(params[:time_frame]), total_minutes: client.total_hours_logged(params[:time_frame]), overdue_outstanding_amount: client.client_overdue_and_outstanding_calculation, @@ -78,7 +79,7 @@ def send_payment_reminder subject: client_email_params[:email_params][:subject], ).send_payment_reminder.deliver_later - render json: { notice: "Payment reminder has been sent to #{client.email}" }, status: :accepted + render json: { notice: "Payment reminder has been sent" }, status: :accepted end private diff --git a/app/controllers/internal_api/v1/invoices_controller.rb b/app/controllers/internal_api/v1/invoices_controller.rb index 2f09bac198..459c18244d 100644 --- a/app/controllers/internal_api/v1/invoices_controller.rb +++ b/app/controllers/internal_api/v1/invoices_controller.rb @@ -93,7 +93,7 @@ def send_reminder message: invoice_email_params[:message] ).send_reminder.deliver_later - render json: { message: "A reminder has been sent to #{invoice.client.email}" }, status: :accepted + render json: { message: "A reminder has been sent" }, status: :accepted end end diff --git a/app/javascript/src/components/Clients/Modals/PaymentReminder/MobileView/index.tsx b/app/javascript/src/components/Clients/Modals/PaymentReminder/MobileView/index.tsx index 3df8bb46df..42311c5a5d 100644 --- a/app/javascript/src/components/Clients/Modals/PaymentReminder/MobileView/index.tsx +++ b/app/javascript/src/components/Clients/Modals/PaymentReminder/MobileView/index.tsx @@ -44,7 +44,7 @@ const MobilePaymentReminder = ({ subject: "Reminder to complete payments for unpaid invoices", message: "This is a gentle reminder to complete payments for the following invoices. You can find the respective payment links along with the invoice details given below", - recipients: [client.email], + recipients: client.clientMembersEmails, }); const isStepFormSubmittedOrVisited = stepNo => { diff --git a/app/views/internal_api/v1/clients/show.json.jbuilder b/app/views/internal_api/v1/clients/show.json.jbuilder index db3737a2ca..1d3cb44a3b 100644 --- a/app/views/internal_api/v1/clients/show.json.jbuilder +++ b/app/views/internal_api/v1/clients/show.json.jbuilder @@ -1,6 +1,7 @@ # frozen_string_literal: true json.client_details client_details +json.client_members_emails client_member_emails json.project_details project_details json.total_minutes total_minutes json.overdue_outstanding_amount overdue_outstanding_amount From b413c1110f9fd76105e90a1df46104fe54ce1f5e Mon Sep 17 00:00:00 2001 From: Shruti-Apte <72149587+Shruti-Apte@users.noreply.github.com> Date: Mon, 22 Apr 2024 09:50:56 +0530 Subject: [PATCH 2/4] Icons issue fixed (#1812) icon library updated, icon color changed, regional holiday icon updated leave block missing icon added Co-authored-by: Shruti Apte --- .../Clients/Modals/PaymentReminder/Step.tsx | 4 +- .../MultipleEntriesModal/Filters/index.tsx | 10 +-- .../components/Invoices/common/MoreButton.tsx | 4 +- .../LeaveManagement/Container/LeaveBlock.tsx | 32 ++++---- .../Container/Table/TableRow.tsx | 19 ++--- .../src/components/OrganizationSetup/Step.tsx | 4 +- .../Organization/Leaves/Details/TableRow.tsx | 13 ++-- .../Organization/Leaves/EditLeaves/index.tsx | 2 +- .../Organization/Leaves/EditLeaves/utils.js | 4 +- .../TimesheetEntries/EntryButtons.tsx | 6 +- .../TimesheetEntries/WeekView/index.tsx | 4 +- .../constants/{leaveType.ts => leaveType.tsx} | 74 ++++++++++++++----- app/javascript/src/miruIcons/index.ts | 26 +++---- .../src/miruIcons/svgIcons/baby.svg | 14 ---- .../src/miruIcons/svgIcons/cake.svg | 5 -- .../src/miruIcons/svgIcons/calendarBlack.svg | 10 --- app/javascript/src/miruIcons/svgIcons/car.svg | 15 ---- .../src/miruIcons/svgIcons/flower.svg | 16 ---- .../src/miruIcons/svgIcons/medicine.svg | 12 --- .../src/miruIcons/svgIcons/vacation.svg | 14 ---- docs/docs/contributing-guide/icons/list.md | 15 ++-- .../contributing-guide/icons/miruicons.md | 2 +- package.json | 4 +- 23 files changed, 124 insertions(+), 185 deletions(-) rename app/javascript/src/constants/{leaveType.ts => leaveType.tsx} (70%) delete mode 100644 app/javascript/src/miruIcons/svgIcons/baby.svg delete mode 100644 app/javascript/src/miruIcons/svgIcons/cake.svg delete mode 100644 app/javascript/src/miruIcons/svgIcons/calendarBlack.svg delete mode 100644 app/javascript/src/miruIcons/svgIcons/car.svg delete mode 100644 app/javascript/src/miruIcons/svgIcons/flower.svg delete mode 100644 app/javascript/src/miruIcons/svgIcons/medicine.svg delete mode 100644 app/javascript/src/miruIcons/svgIcons/vacation.svg diff --git a/app/javascript/src/components/Clients/Modals/PaymentReminder/Step.tsx b/app/javascript/src/components/Clients/Modals/PaymentReminder/Step.tsx index 9be46d9187..f3bedf8645 100644 --- a/app/javascript/src/components/Clients/Modals/PaymentReminder/Step.tsx +++ b/app/javascript/src/components/Clients/Modals/PaymentReminder/Step.tsx @@ -1,6 +1,6 @@ import React, { useEffect, useState } from "react"; -import { CheckCircle } from "phosphor-react"; +import { CheckCircleIcon } from "miruIcons"; const Step = (props: any) => { const [stepNumber, setStepNumber] = useState(1); @@ -32,7 +32,7 @@ const Step = (props: any) => {
{stepIsFinished(status) ? (
- setFilters({ ...filters, searchTerm: e.target.value })} /> {filters.searchTerm ? ( - setFilters({ ...filters, searchTerm: "" })} /> ) : ( - + )}
diff --git a/app/javascript/src/components/Invoices/common/MoreButton.tsx b/app/javascript/src/components/Invoices/common/MoreButton.tsx index e125ab9256..c7e03c1270 100644 --- a/app/javascript/src/components/Invoices/common/MoreButton.tsx +++ b/app/javascript/src/components/Invoices/common/MoreButton.tsx @@ -1,6 +1,6 @@ import React from "react"; -import { DotsThreeVertical } from "phosphor-react"; +import { DotsThreeVerticalIcon } from "miruIcons"; const MoreButton = ({ onClick }) => ( ); diff --git a/app/javascript/src/components/LeaveManagement/Container/LeaveBlock.tsx b/app/javascript/src/components/LeaveManagement/Container/LeaveBlock.tsx index 5f18b78b69..37e4f7638c 100644 --- a/app/javascript/src/components/LeaveManagement/Container/LeaveBlock.tsx +++ b/app/javascript/src/components/LeaveManagement/Container/LeaveBlock.tsx @@ -1,7 +1,6 @@ import React from "react"; import { minToHHMM } from "helpers"; -import { Avatar } from "StyledComponents"; import { generateLeaveIcon, @@ -28,8 +27,8 @@ const LeaveBlock = ({ leaveType, selectedLeaveType, setSelectedLeaveType }) => { const selectedDiv = selectedLeaveType?.name == name - ? "flex w-full cursor-pointer justify-start rounded-lg p-2 text-white lg:flex-col lg:p-6 shadow-2xl border-2 border-miru-dark-purple-1000 border-opacity-20" - : "flex w-full cursor-pointer justify-start rounded-lg p-2 text-white lg:flex-col lg:p-6 hover:opacity-80"; + ? "flex w-full cursor-pointer justify-between rounded-lg p-2 text-white lg:p-6 shadow-2xl border-2 border-miru-dark-purple-1000 border-opacity-20 relative" + : "flex w-full cursor-pointer justify-between rounded-lg p-2 text-white lg:p-6 hover:opacity-80 relative"; return (
{ style={{ background: leaveColor.value }} onClick={() => setSelectedLeaveType(leaveType)} > - -
- {name} - - {formattedDuration} - +
+
+ {leaveIcon?.icon} +
+
+ {name} + + {formattedDuration} + +
+
+
+ {leaveIcon?.icon}
); diff --git a/app/javascript/src/components/LeaveManagement/Container/Table/TableRow.tsx b/app/javascript/src/components/LeaveManagement/Container/Table/TableRow.tsx index b61ef5cb27..f518bb5384 100644 --- a/app/javascript/src/components/LeaveManagement/Container/Table/TableRow.tsx +++ b/app/javascript/src/components/LeaveManagement/Container/Table/TableRow.tsx @@ -1,7 +1,6 @@ import React from "react"; import { minToHHMM } from "helpers"; -import { Avatar } from "StyledComponents"; import { generateLeaveIcon, @@ -27,16 +26,14 @@ const TableRow = ({ timeoffEntry }) => { {leaveDate} - -
- -
- {leaveName} + +
+ {leaveIcon?.icon} +
+ {leaveName} {minToHHMM(duration)} diff --git a/app/javascript/src/components/OrganizationSetup/Step.tsx b/app/javascript/src/components/OrganizationSetup/Step.tsx index 4f9266d894..e241414c17 100644 --- a/app/javascript/src/components/OrganizationSetup/Step.tsx +++ b/app/javascript/src/components/OrganizationSetup/Step.tsx @@ -1,6 +1,6 @@ import React, { useEffect, useState } from "react"; -import { CheckCircle } from "phosphor-react"; +import { CheckCircleIcon } from "miruIcons"; const Step = (props: any) => { const [stepNumber, setStepNumber] = useState(1); @@ -32,7 +32,7 @@ const Step = (props: any) => {
{stepIsFinished(status) ? (
- { @@ -22,11 +20,12 @@ const TableRow = ({ leave, key }) => { return ( - +
+ {leaveIcon?.icon} +
{leaveType} diff --git a/app/javascript/src/components/Profile/Organization/Leaves/EditLeaves/index.tsx b/app/javascript/src/components/Profile/Organization/Leaves/EditLeaves/index.tsx index a0c2c012d5..0e85b6c14a 100644 --- a/app/javascript/src/components/Profile/Organization/Leaves/EditLeaves/index.tsx +++ b/app/javascript/src/components/Profile/Organization/Leaves/EditLeaves/index.tsx @@ -83,7 +83,7 @@ const EditLeaves = ({ IndicatorSeparator: () => null, }} getOptionLabel={e => ( - {e.label} +
{e.icon}
)} handleOnChange={e => updateCondition("leaveIcon", e, index) diff --git a/app/javascript/src/components/Profile/Organization/Leaves/EditLeaves/utils.js b/app/javascript/src/components/Profile/Organization/Leaves/EditLeaves/utils.js index 3de17931f5..99672ab2b0 100644 --- a/app/javascript/src/components/Profile/Organization/Leaves/EditLeaves/utils.js +++ b/app/javascript/src/components/Profile/Organization/Leaves/EditLeaves/utils.js @@ -92,8 +92,8 @@ export const customStyles = { }; export const IconOption = props => ( - ); diff --git a/app/javascript/src/components/TimesheetEntries/EntryButtons.tsx b/app/javascript/src/components/TimesheetEntries/EntryButtons.tsx index a851b27e13..2d9192d382 100644 --- a/app/javascript/src/components/TimesheetEntries/EntryButtons.tsx +++ b/app/javascript/src/components/TimesheetEntries/EntryButtons.tsx @@ -1,6 +1,6 @@ import React from "react"; -import { VacationIconSVG } from "miruIcons"; +import { VacationIcon } from "miruIcons"; import { Button } from "StyledComponents"; import { useTimesheetEntries } from "context/TimesheetEntries"; @@ -38,7 +38,7 @@ const EntryButtons = () => { setNewTimeoffEntryView(true); }} > - Vacation Icon + MARK TIME OFF
@@ -65,7 +65,7 @@ const EntryButtons = () => { setNewTimeoffEntryView(true); }} > - Vacation Icon + MARK TIME OFF
diff --git a/app/javascript/src/components/TimesheetEntries/WeekView/index.tsx b/app/javascript/src/components/TimesheetEntries/WeekView/index.tsx index a128b3e8c5..2d7241c19f 100644 --- a/app/javascript/src/components/TimesheetEntries/WeekView/index.tsx +++ b/app/javascript/src/components/TimesheetEntries/WeekView/index.tsx @@ -1,6 +1,6 @@ import React from "react"; -import { VacationIconSVG } from "miruIcons"; +import { VacationIcon } from "miruIcons"; import TimeoffEntryManager from "components/TimeoffEntries/TimeoffEntryManager"; import { useTimesheetEntries } from "context/TimesheetEntries"; @@ -49,7 +49,7 @@ const WeekView = () => { setNewTimeoffEntryView(true); }} > - + Mark Time Off
diff --git a/app/javascript/src/constants/leaveType.ts b/app/javascript/src/constants/leaveType.tsx similarity index 70% rename from app/javascript/src/constants/leaveType.ts rename to app/javascript/src/constants/leaveType.tsx index 5e30ba1191..10d30126e1 100644 --- a/app/javascript/src/constants/leaveType.ts +++ b/app/javascript/src/constants/leaveType.tsx @@ -1,14 +1,16 @@ +import React from "react"; + import { - CakeIconSVG, - CalendarBlackIconSVG, - CarIconSVG, - VacationIconSVG, - FlowerIconSVG, - UserIconSVG, - MedicineIconSVG, - BabyIconSVG, - ShieldSVG, - HelpIconSVG, + CakeIcon, + CalendarIcon, + CarIcon, + VacationIcon, + FlowerIcon, + UserIcon, + MedicineIcon, + BabyIcon, + ShieldIcon, + OptionIcon, } from "miruIcons"; export const leaveTypes = [ @@ -70,14 +72,46 @@ export const leaveColors = [ ]; export const leaveIcons = [ - { value: "calendar", label: "label", icon: CalendarBlackIconSVG }, - { value: "cake", label: "label2", icon: CakeIconSVG }, - { value: "vacation", label: "label3", icon: VacationIconSVG }, - { value: "medicine", label: "label4", icon: MedicineIconSVG }, - { value: "baby", label: "label5", icon: BabyIconSVG }, - { value: "flower", label: "label6", icon: FlowerIconSVG }, - { value: "car", label: "label7", icon: CarIconSVG }, - { value: "user", label: "label8", icon: UserIconSVG }, + { + value: "calendar", + label: "label", + icon: , + }, + { + value: "cake", + label: "label2", + icon: , + }, + { + value: "vacation", + label: "label3", + icon: , + }, + { + value: "medicine", + label: "label4", + icon: , + }, + { + value: "baby", + label: "label5", + icon: , + }, + { + value: "flower", + label: "label6", + icon: , + }, + { + value: "car", + label: "label7", + icon: , + }, + { + value: "user", + label: "label8", + icon: , + }, ]; export const holidayColors = [ @@ -94,11 +128,11 @@ export const holidayColors = [ export const holidayIcons = [ { label: "national", - icon: ShieldSVG, + icon: , }, { label: "optional", - icon: HelpIconSVG, + icon: , }, ]; diff --git a/app/javascript/src/miruIcons/index.ts b/app/javascript/src/miruIcons/index.ts index 744ab1b0b5..077051c3c7 100644 --- a/app/javascript/src/miruIcons/index.ts +++ b/app/javascript/src/miruIcons/index.ts @@ -62,33 +62,31 @@ import { Wrench, Armchair, ForkKnife, -} from "phosphor-react"; + TreePalm, + Flower, + Baby, + Pill, + Option, +} from "@phosphor-icons/react"; const error404Animation = require("./GIFS/404_animation.gif"); const accountsAgingIcon = require("./svgIcons/accountsAging.svg"); const accountsAgingHoverIcon = require("./svgIcons/accountsAgingHover.svg"); -const baby = require("./svgIcons/baby.svg"); const blurredMiruLogo = require("./svgIcons/blurred-miru-logo.svg"); -const cake = require("./svgIcons/cake.svg"); const reportcalendarIcon = require("./svgIcons/Calendar.svg"); -const calendarBlack = require("./svgIcons/calendarBlack.svg"); const calendarHoverIcon = require("./svgIcons/CalendarHover.svg"); -const car = require("./svgIcons/car.svg"); const deductions = require("./svgIcons/Deductions.svg"); const earnings = require("./svgIcons/Earnings.svg"); const emptyState = require("./svgIcons/emptyState.svg"); const expenseIcon = require("./svgIcons/expenseIcon.svg"); -const flower = require("./svgIcons/flower.svg"); const hoursIcon = require("./svgIcons/Hours.svg"); const hoursHoverIcon = require("./svgIcons/HoursHover.svg"); -const medicine = require("./svgIcons/medicine.svg"); const noSearchResultsState = require("./svgIcons/NoSearchResultsState.svg"); const overdueOutstandingIcon = require("./svgIcons/OverdueOutstanding.svg"); const overdueOutstandingHoverIcon = require("./svgIcons/OverdueOutstandingHover.svg"); const revenueIcon = require("./svgIcons/Revenue.svg"); const revenueHoverIcon = require("./svgIcons/RevenueHover.svg"); const user = require("./svgIcons/user.svg"); -const vacation = require("./svgIcons/vacation.svg"); const alert = require("../../../assets/images/alert-error-close.svg"); const amex = require("../../../assets/images/amex.svg"); @@ -227,6 +225,11 @@ export const CarIcon = Car; export const FurnitureIcon = Armchair; export const WrenchIcon = Wrench; export const ShieldIcon = ShieldCheck; +export const VacationIcon = TreePalm; +export const BabyIcon = Baby; +export const FlowerIcon = Flower; +export const MedicineIcon = Pill; +export const OptionIcon = Option; // custom svg icons export const WarningTriangleSVG = warningTriangle; @@ -316,14 +319,7 @@ export const GreenCheckCirleIcon = greenCheckCirleIcon; export const deleteImageIcon = deleteImage; export const Animation_404 = error404Animation; export const GoogleCalendarIcon = googleCalendarIcon; -export const VacationIconSVG = vacation; -export const BabyIconSVG = baby; -export const CakeIconSVG = cake; -export const FlowerIconSVG = flower; -export const CarIconSVG = car; export const UserIconSVG = user; -export const CalendarBlackIconSVG = calendarBlack; -export const MedicineIconSVG = medicine; export const EarningsIconSVG = earnings; export const DeductionIconSVG = deductions; export const ExpenseIconSVG = expenseIcon; diff --git a/app/javascript/src/miruIcons/svgIcons/baby.svg b/app/javascript/src/miruIcons/svgIcons/baby.svg deleted file mode 100644 index 2809a66cd3..0000000000 --- a/app/javascript/src/miruIcons/svgIcons/baby.svg +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - diff --git a/app/javascript/src/miruIcons/svgIcons/cake.svg b/app/javascript/src/miruIcons/svgIcons/cake.svg deleted file mode 100644 index b69cbe68e4..0000000000 --- a/app/javascript/src/miruIcons/svgIcons/cake.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/app/javascript/src/miruIcons/svgIcons/calendarBlack.svg b/app/javascript/src/miruIcons/svgIcons/calendarBlack.svg deleted file mode 100644 index a4fa6139a2..0000000000 --- a/app/javascript/src/miruIcons/svgIcons/calendarBlack.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/app/javascript/src/miruIcons/svgIcons/car.svg b/app/javascript/src/miruIcons/svgIcons/car.svg deleted file mode 100644 index 873f7b78ac..0000000000 --- a/app/javascript/src/miruIcons/svgIcons/car.svg +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/app/javascript/src/miruIcons/svgIcons/flower.svg b/app/javascript/src/miruIcons/svgIcons/flower.svg deleted file mode 100644 index 8f42cb706c..0000000000 --- a/app/javascript/src/miruIcons/svgIcons/flower.svg +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - - - - diff --git a/app/javascript/src/miruIcons/svgIcons/medicine.svg b/app/javascript/src/miruIcons/svgIcons/medicine.svg deleted file mode 100644 index 53ce3d51ef..0000000000 --- a/app/javascript/src/miruIcons/svgIcons/medicine.svg +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - diff --git a/app/javascript/src/miruIcons/svgIcons/vacation.svg b/app/javascript/src/miruIcons/svgIcons/vacation.svg deleted file mode 100644 index f6c5ad955f..0000000000 --- a/app/javascript/src/miruIcons/svgIcons/vacation.svg +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - diff --git a/docs/docs/contributing-guide/icons/list.md b/docs/docs/contributing-guide/icons/list.md index 4e867a9bf8..00612a12b0 100644 --- a/docs/docs/contributing-guide/icons/list.md +++ b/docs/docs/contributing-guide/icons/list.md @@ -30,7 +30,7 @@ MasterCardSVG LogoutIconSVG LogoSVG CloseInfoSVG -HelpIconSVG +OptionIcon CircleInfoSVG GoogleSVG ErrorOctagonSVG @@ -93,12 +93,11 @@ GreenCheckCirleIcon deleteImageIcon Animation_404 GoogleCalendarIcon -VacationIconSVG -BabyIconSVG -CakeIconSVG -FlowerIconSVG -CarIconSVG +VacationIcon +BabyIcon +CakeIcon +FlowerIcon +CarIcon UserIconSVG -CalendarBlackIconSVG -MedicineIconSVG +MedicineIcon ``` diff --git a/docs/docs/contributing-guide/icons/miruicons.md b/docs/docs/contributing-guide/icons/miruicons.md index 389d69d132..be673693cf 100644 --- a/docs/docs/contributing-guide/icons/miruicons.md +++ b/docs/docs/contributing-guide/icons/miruicons.md @@ -56,7 +56,7 @@ One of the strengths of MiruIcons is its flexibility. If we need an icon that isn't already in the collection, we can easily add it. Follow these steps: - **Step 1: Prepare the Icon File** Before adding a new icon, we'll need the - icon's SVG file or import it from `phosphor-react` package or we can even add + icon's SVG file or import it from `@phosphor-icons/react` package or we can even add gif file. Basically we can create our own or obtain one that suits our needs. Ensure the file adheres to any format or dimension requirements. diff --git a/package.json b/package.json index 6ddff0f171..293a730edd 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "@fontsource/plus-jakarta-sans": "^4.5.0", "@headlessui/react": "^1.4.2", "@heroicons/react": "^1.0.5", + "@phosphor-icons/react": "^2.1.4", "@rails/actioncable": "^7.0.4", "@rails/activestorage": "^7.0.4", "@rails/ujs": "^7.0.4", @@ -44,7 +45,6 @@ "js-cookie": "^3.0.5", "js-logger": "^1.6.1", "mini-css-extract-plugin": "^2.7.2", - "phosphor-react": "^1.4.1", "pnp-webpack-plugin": "^1.7.0", "postcss": "^8.4.21", "postcss-flexbugs-fixes": "^5.0.2", @@ -148,4 +148,4 @@ }, "license": "MIT", "packageManager": "yarn@1.22.17" -} \ No newline at end of file +} From 334c82b726e3e7d95c67e59b3be802e85dba7a86 Mon Sep 17 00:00:00 2001 From: Apoorv Tiwari Date: Tue, 23 Apr 2024 10:27:46 +0530 Subject: [PATCH 3/4] sort-revenue-report-by-total (#1817) --- .../reports/client_revenues/index_service.rb | 12 ++++++++++-- yarn.lock | 10 +++++----- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/app/services/reports/client_revenues/index_service.rb b/app/services/reports/client_revenues/index_service.rb index ff8817ebd4..f3810160e1 100644 --- a/app/services/reports/client_revenues/index_service.rb +++ b/app/services/reports/client_revenues/index_service.rb @@ -19,9 +19,17 @@ def process private def clients - current_clients.includes(:invoices).map do |client| - client.payment_summary(duration_params).merge({ name: client.name, logo: client.logo_url }) + client_data = current_clients.includes(:invoices).map do |client| + summary = client.payment_summary(duration_params) + { + name: client.name, + logo: client.logo_url, + paid_amount: summary[:paid_amount], + outstanding_amount: summary[:outstanding_amount], + overdue_amount: summary[:overdue_amount] + } end + client_data.sort_by { |client| -(client[:paid_amount] + client[:outstanding_amount] + client[:overdue_amount]) } end def summary diff --git a/yarn.lock b/yarn.lock index bd82f37517..d3782bc1b3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1616,6 +1616,11 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" +"@phosphor-icons/react@^2.1.4": + version "2.1.5" + resolved "https://registry.yarnpkg.com/@phosphor-icons/react/-/react-2.1.5.tgz#762c368778a4040d52c5532b8af1692b66e16783" + integrity sha512-B7vRm/w+P/+eavWZP5CB5Ul0ffK4Y7fpd/auWKuGvm+8pVgAJzbOK8O0s+DqzR+TwWkh5pHtJTuoAtaSvgCPzg== + "@popperjs/core@^2.9.2": version "2.11.7" resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.7.tgz#ccab5c8f7dc557a52ca3288c10075c9ccd37fff7" @@ -5453,11 +5458,6 @@ pend@~1.2.0: resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50" integrity sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg== -phosphor-react@^1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/phosphor-react/-/phosphor-react-1.4.1.tgz#97b0e034d9937db9b97fe53b186e9646464fd4e7" - integrity sha512-gO5j7U0xZrdglTAYDYPACU4xDOFBTJmptrrB/GeR+tHhCZF3nUMyGmV/0hnloKjuTrOmpSFlbfOY78H39rgjUQ== - picocolors@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-0.2.1.tgz#570670f793646851d1ba135996962abad587859f" From 7fa42e5196c6cd6e456fc7cb09b978b2697aa8fa Mon Sep 17 00:00:00 2001 From: Akhil G Krishnan Date: Wed, 24 Apr 2024 09:57:13 +0530 Subject: [PATCH 4/4] Upgrade Rails to 7.1 (#1540) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Upgrade Rails to 7.1 * RSpec fixtures path updated * Database cleaner fix * Upgrade rails to 7.1.3 * Rdoc cve fix * migration fix * migration fix * rspec fix * Upgraded ransack * rspec sidekiq gem upgrade * use rspec-sdeiqkiq from main * upgrade sidekiq * upgrde sentry and newrelic * remove arm64 darwin 23 --------- Co-authored-by: Apoorv Tiwari Co-authored-by: “Apoorv <“tiwari.apoorv1316@gmail.com”> --- Gemfile | 18 +- Gemfile.lock | 260 ++++++++++-------- app/services/projects/search_service.rb | 41 --- bin/setup | 7 +- config/application.rb | 8 +- config/environments/development.rb | 10 +- config/environments/production.rb | 79 ++---- config/environments/test.rb | 16 +- config/initializers/assets.rb | 1 + .../initializers/content_security_policy.rb | 13 +- .../initializers/filter_parameter_logging.rb | 4 +- config/initializers/inflections.rb | 1 + .../new_framework_defaults_7_1.rb | 224 +++++++++++++++ config/initializers/permissions_policy.rb | 20 +- ..._to_active_storage_blobs.active_storage.rb | 24 ++ ..._storage_variant_records.active_storage.rb | 30 ++ ...e_storage_blobs_checksum.active_storage.rb | 10 + db/schema.rb | 5 +- spec/services/projects/search_service_spec.rb | 73 ----- 19 files changed, 526 insertions(+), 318 deletions(-) delete mode 100644 app/services/projects/search_service.rb create mode 100644 config/initializers/new_framework_defaults_7_1.rb create mode 100644 db/migrate/20240331034032_add_service_name_to_active_storage_blobs.active_storage.rb create mode 100644 db/migrate/20240331034127_create_active_storage_variant_records.active_storage.rb create mode 100644 db/migrate/20240331034308_remove_not_null_on_active_storage_blobs_checksum.active_storage.rb delete mode 100644 spec/services/projects/search_service_spec.rb diff --git a/Gemfile b/Gemfile index 01076dfc8a..91ceb7648f 100644 --- a/Gemfile +++ b/Gemfile @@ -6,7 +6,7 @@ git_source(:github) { |repo| "https://github.com/#{repo}.git" } ruby "3.2.2" # Bundle edge Rails instead: gem "rails", github: "rails/rails", branch: "main" -gem "rails", "~> 7.0.8.1" +gem "rails", "~> 7.1.3" # Use postgresql as the database for Active Record gem "pg" @@ -65,7 +65,7 @@ gem "react-rails", "2.6.2" # Use SCSS for stylesheets gem "sass-rails" -##--- gems for server & infra configuration ---## +# #--- gems for server & infra configuration ---## gem "dotenv-rails" gem "foreman" @@ -82,13 +82,13 @@ gem "money" gem "aws-sdk-s3", require: false # Ransack gem for advanced searching -gem "ransack" +gem "ransack", "~> 4.1" # For Soft deletion gem "discard", "~> 1.2" # Use newrelic for monitoring -gem "newrelic_rpm", "~> 8.4" +gem "newrelic_rpm", "~> 9.8.0" # Role management library with resource scoping gem "rolify", "~> 6.0" @@ -115,7 +115,7 @@ gem "active_interaction" gem "stripe" # Background job processing adapter -gem "sidekiq", "<8" +gem "sidekiq", "~> 7.2" # job scheduler extension for Sidekiq gem "sidekiq-scheduler" @@ -155,7 +155,7 @@ group :development, :test, :ci do gem "rubocop-rspec", require: false # Use RSpec as the testing framework - gem "rspec-rails", "~> 5.0", ">= 5.0.2" + gem "rspec-rails", "~> 6.1" # For linting ERB files gem "erb_lint", require: false, git: "https://github.com/Shopify/erb-lint.git", branch: "main" @@ -174,7 +174,7 @@ group :development, :test, :ci do gem "rails-controller-testing", "~> 1.0", ">= 1.0.5" # help to kill N+1 queries and unused eager loading. https://github.com/flyerhzm/bullet - gem "bullet" + gem "bullet", "~> 7.1" # To record response of outgoing API calls gem "vcr", "~> 6.1" @@ -209,7 +209,7 @@ group :test, :ci do # Strategies for cleaning databases in Ruby. gem "database_cleaner", "~> 2.0" gem "hash_dot" - gem "rspec-sidekiq" + gem "rspec-sidekiq", git: "https://github.com/wspurgin/rspec-sidekiq", branch: "main" gem "rspec-buildkite" gem "rspec-retry" @@ -225,7 +225,7 @@ gem "strong_migrations" # Error tracking: https://docs.sentry.io/platforms/ruby/guides/rails/ gem "sentry-rails" -gem "sentry-ruby" +gem "sentry-ruby", "~> 5.17" # https://github.com/grosser/parallel_tests gem "parallel_tests", group: [:development, :test] diff --git a/Gemfile.lock b/Gemfile.lock index afbbffae9e..e5c8bab7f0 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -11,82 +11,102 @@ GIT rubocop smart_properties +GIT + remote: https://github.com/wspurgin/rspec-sidekiq + revision: 0e710d7698c2fcea77245c7d458bb00b0fc50dae + branch: main + specs: + rspec-sidekiq (4.1.0) + rspec-core (~> 3.0) + rspec-expectations (~> 3.0) + rspec-mocks (~> 3.0) + sidekiq (>= 5, < 8) + GEM remote: https://rubygems.org/ specs: - actioncable (7.0.8.1) - actionpack (= 7.0.8.1) - activesupport (= 7.0.8.1) + actioncable (7.1.3.2) + actionpack (= 7.1.3.2) + activesupport (= 7.1.3.2) nio4r (~> 2.0) websocket-driver (>= 0.6.1) - actionmailbox (7.0.8.1) - actionpack (= 7.0.8.1) - activejob (= 7.0.8.1) - activerecord (= 7.0.8.1) - activestorage (= 7.0.8.1) - activesupport (= 7.0.8.1) + zeitwerk (~> 2.6) + actionmailbox (7.1.3.2) + actionpack (= 7.1.3.2) + activejob (= 7.1.3.2) + activerecord (= 7.1.3.2) + activestorage (= 7.1.3.2) + activesupport (= 7.1.3.2) mail (>= 2.7.1) net-imap net-pop net-smtp - actionmailer (7.0.8.1) - actionpack (= 7.0.8.1) - actionview (= 7.0.8.1) - activejob (= 7.0.8.1) - activesupport (= 7.0.8.1) + actionmailer (7.1.3.2) + actionpack (= 7.1.3.2) + actionview (= 7.1.3.2) + activejob (= 7.1.3.2) + activesupport (= 7.1.3.2) mail (~> 2.5, >= 2.5.4) net-imap net-pop net-smtp - rails-dom-testing (~> 2.0) - actionpack (7.0.8.1) - actionview (= 7.0.8.1) - activesupport (= 7.0.8.1) - rack (~> 2.0, >= 2.2.4) + rails-dom-testing (~> 2.2) + actionpack (7.1.3.2) + actionview (= 7.1.3.2) + activesupport (= 7.1.3.2) + nokogiri (>= 1.8.5) + racc + rack (>= 2.2.4) + rack-session (>= 1.0.1) rack-test (>= 0.6.3) - rails-dom-testing (~> 2.0) - rails-html-sanitizer (~> 1.0, >= 1.2.0) - actiontext (7.0.8.1) - actionpack (= 7.0.8.1) - activerecord (= 7.0.8.1) - activestorage (= 7.0.8.1) - activesupport (= 7.0.8.1) + rails-dom-testing (~> 2.2) + rails-html-sanitizer (~> 1.6) + actiontext (7.1.3.2) + actionpack (= 7.1.3.2) + activerecord (= 7.1.3.2) + activestorage (= 7.1.3.2) + activesupport (= 7.1.3.2) globalid (>= 0.6.0) nokogiri (>= 1.8.5) - actionview (7.0.8.1) - activesupport (= 7.0.8.1) + actionview (7.1.3.2) + activesupport (= 7.1.3.2) builder (~> 3.1) - erubi (~> 1.4) - rails-dom-testing (~> 2.0) - rails-html-sanitizer (~> 1.1, >= 1.2.0) + erubi (~> 1.11) + rails-dom-testing (~> 2.2) + rails-html-sanitizer (~> 1.6) active_interaction (5.2.0) activemodel (>= 5.2, < 8) activesupport (>= 5.2, < 8) - activejob (7.0.8.1) - activesupport (= 7.0.8.1) + activejob (7.1.3.2) + activesupport (= 7.1.3.2) globalid (>= 0.3.6) - activemodel (7.0.8.1) - activesupport (= 7.0.8.1) - activerecord (7.0.8.1) - activemodel (= 7.0.8.1) - activesupport (= 7.0.8.1) + activemodel (7.1.3.2) + activesupport (= 7.1.3.2) + activerecord (7.1.3.2) + activemodel (= 7.1.3.2) + activesupport (= 7.1.3.2) + timeout (>= 0.4.0) activerecord-import (1.4.1) activerecord (>= 4.2) - activestorage (7.0.8.1) - actionpack (= 7.0.8.1) - activejob (= 7.0.8.1) - activerecord (= 7.0.8.1) - activesupport (= 7.0.8.1) + activestorage (7.1.3.2) + actionpack (= 7.1.3.2) + activejob (= 7.1.3.2) + activerecord (= 7.1.3.2) + activesupport (= 7.1.3.2) marcel (~> 1.0) - mini_mime (>= 1.1.0) - activesupport (7.0.8.1) + activesupport (7.1.3.2) + base64 + bigdecimal concurrent-ruby (~> 1.0, >= 1.0.2) + connection_pool (>= 2.2.5) + drb i18n (>= 1.6, < 2) minitest (>= 5.1) + mutex_m tzinfo (~> 2.0) addressable (2.8.6) public_suffix (>= 2.0.2, < 6.0) - administrate (0.18.0) + administrate (0.19.0) actionpack (>= 5.0) actionview (>= 5.0) activerecord (>= 5.0) @@ -122,6 +142,7 @@ GEM babel-transpiler (0.7.0) babel-source (>= 4.0, < 6) execjs (~> 2.0) + base64 (0.1.1) bcrypt (3.1.18) better_html (2.0.1) actionview (>= 6.0) @@ -130,11 +151,12 @@ GEM erubi (~> 1.4) parser (>= 2.4) smart_properties + bigdecimal (3.1.4) bindex (0.8.1) bootsnap (1.16.0) msgpack (~> 1.2) builder (3.2.4) - bullet (7.0.7) + bullet (7.1.1) activesupport (>= 3.0.0) uniform_notifier (~> 1.11) bundler-audit (0.9.1) @@ -162,9 +184,9 @@ GEM data_migrate (8.0.0) activerecord (>= 5.0) railties (>= 5.0) - database_cleaner (2.0.1) - database_cleaner-active_record (~> 2.0.0) - database_cleaner-active_record (2.0.1) + database_cleaner (2.0.2) + database_cleaner-active_record (>= 2, < 3) + database_cleaner-active_record (2.1.0) activerecord (>= 5.a) database_cleaner-core (~> 2.0.0) database_cleaner-core (2.0.1) @@ -180,7 +202,7 @@ GEM railties (>= 4.1.0) responders warden (~> 1.2.3) - diff-lcs (1.5.0) + diff-lcs (1.5.1) discard (1.2.1) activerecord (>= 4.2, < 8) docile (1.4.0) @@ -190,6 +212,8 @@ GEM dotenv-rails (2.8.1) dotenv (= 2.8.1) railties (>= 3.2) + drb (2.1.1) + ruby2_keywords elasticsearch (7.13.3) elasticsearch-api (= 7.13.3) elasticsearch-transport (= 7.13.3) @@ -283,8 +307,9 @@ GEM mini_magick (>= 4.9.5, < 5) ruby-vips (>= 2.0.17, < 3) io-console (0.6.0) - irb (1.6.3) - reline (>= 0.3.0) + irb (1.12.0) + rdoc + reline (>= 0.4.2) jbuilder (2.11.5) actionview (>= 5.0.0) activesupport (>= 5.0.0) @@ -316,7 +341,7 @@ GEM letter_opener (~> 1.7) railties (>= 5.2) rexml - loofah (2.21.3) + loofah (2.21.4) crass (~> 1.0.2) nokogiri (>= 1.12.0) mail (2.8.1) @@ -324,19 +349,19 @@ GEM net-imap net-pop net-smtp - marcel (1.0.2) + marcel (1.0.4) matrix (0.4.2) memoist (0.16.2) - method_source (1.0.0) mini_magick (4.12.0) mini_mime (1.1.5) - minitest (5.19.0) + minitest (5.20.0) money (6.16.0) i18n (>= 0.6.4, <= 2) msgpack (1.6.0) multi_json (1.15.0) multi_xml (0.6.0) multipart-post (2.3.0) + mutex_m (0.1.2) net-imap (0.3.4) date net-protocol @@ -346,7 +371,7 @@ GEM timeout net-smtp (0.3.3) net-protocol - newrelic_rpm (8.16.0) + newrelic_rpm (9.8.0) nio4r (2.5.9) nokogiri (1.16.2-arm64-darwin) racc (~> 1.4) @@ -386,6 +411,8 @@ GEM parser (3.2.0.0) ast (~> 2.4.1) pg (1.4.5) + psych (5.1.2) + stringio public_suffix (5.0.4) puma (6.4.2) nio4r (~> 2.0) @@ -393,7 +420,7 @@ GEM activesupport (>= 3.0.0) raabro (1.4.0) racc (1.7.3) - rack (2.2.8.1) + rack (3.0.10) rack-cors (2.0.0) rack (>= 2.0.0) rack-mini-profiler (3.0.0) @@ -402,22 +429,27 @@ GEM rack rack-proxy (0.7.6) rack + rack-session (2.0.0) + rack (>= 3.0.0) rack-test (2.1.0) rack (>= 1.3) - rails (7.0.8.1) - actioncable (= 7.0.8.1) - actionmailbox (= 7.0.8.1) - actionmailer (= 7.0.8.1) - actionpack (= 7.0.8.1) - actiontext (= 7.0.8.1) - actionview (= 7.0.8.1) - activejob (= 7.0.8.1) - activemodel (= 7.0.8.1) - activerecord (= 7.0.8.1) - activestorage (= 7.0.8.1) - activesupport (= 7.0.8.1) + rackup (2.1.0) + rack (>= 3) + webrick (~> 1.8) + rails (7.1.3.2) + actioncable (= 7.1.3.2) + actionmailbox (= 7.1.3.2) + actionmailer (= 7.1.3.2) + actionpack (= 7.1.3.2) + actiontext (= 7.1.3.2) + actionview (= 7.1.3.2) + activejob (= 7.1.3.2) + activemodel (= 7.1.3.2) + activerecord (= 7.1.3.2) + activestorage (= 7.1.3.2) + activesupport (= 7.1.3.2) bundler (>= 1.15.0) - railties (= 7.0.8.1) + railties (= 7.1.3.2) rails-controller-testing (1.0.5) actionpack (>= 5.0.1.rc1) actionview (>= 5.0.1.rc1) @@ -429,19 +461,22 @@ GEM rails-html-sanitizer (1.6.0) loofah (~> 2.21) nokogiri (~> 1.14) - railties (7.0.8.1) - actionpack (= 7.0.8.1) - activesupport (= 7.0.8.1) - method_source + railties (7.1.3.2) + actionpack (= 7.1.3.2) + activesupport (= 7.1.3.2) + irb + rackup (>= 1.0.0) rake (>= 12.2) - thor (~> 1.0) - zeitwerk (~> 2.5) + thor (~> 1.0, >= 1.2.2) + zeitwerk (~> 2.6) rainbow (3.1.1) rake (13.0.6) - ransack (3.2.1) + ransack (4.1.1) activerecord (>= 6.1.5) activesupport (>= 6.1.5) i18n + rdoc (6.6.3.1) + psych (>= 4.0.0) react-rails (2.6.2) babel-transpiler (>= 0.7.0) connection_pool @@ -449,10 +484,10 @@ GEM railties (>= 3.2) tilt redis (4.8.0) - redis-client (0.17.0) + redis-client (0.22.0) connection_pool regexp_parser (2.9.0) - reline (0.3.3) + reline (0.5.0) io-console (~> 0.5) representable (3.2.0) declarative (< 0.1.0) @@ -466,28 +501,25 @@ GEM rolify (6.0.1) rspec-buildkite (0.1.6) rspec-core (~> 3.0) - rspec-core (3.12.1) + rspec-core (3.12.2) rspec-support (~> 3.12.0) - rspec-expectations (3.12.2) + rspec-expectations (3.12.4) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.12.0) - rspec-mocks (3.12.3) + rspec-mocks (3.12.7) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.12.0) - rspec-rails (5.1.2) - actionpack (>= 5.2) - activesupport (>= 5.2) - railties (>= 5.2) - rspec-core (~> 3.10) - rspec-expectations (~> 3.10) - rspec-mocks (~> 3.10) - rspec-support (~> 3.10) + rspec-rails (6.1.1) + actionpack (>= 6.1) + activesupport (>= 6.1) + railties (>= 6.1) + rspec-core (~> 3.12) + rspec-expectations (~> 3.12) + rspec-mocks (~> 3.12) + rspec-support (~> 3.12) rspec-retry (0.6.2) rspec-core (> 3.3) - rspec-sidekiq (3.1.0) - rspec-core (~> 3.0, >= 3.0.0) - sidekiq (>= 2.4.0) - rspec-support (3.12.0) + rspec-support (3.12.1) rubocop (1.44.1) json (~> 2.3) parallel (~> 1.10) @@ -542,10 +574,11 @@ GEM rubyzip (>= 1.2.2, < 3.0) websocket (~> 1.0) semantic_range (3.0.0) - sentry-rails (5.7.0) + sentry-rails (5.17.3) railties (>= 5.0) - sentry-ruby (~> 5.7.0) - sentry-ruby (5.7.0) + sentry-ruby (~> 5.17.3) + sentry-ruby (5.17.3) + bigdecimal concurrent-ruby (~> 1.0, >= 1.0.2) shakapacker (6.0.0) activesupport (>= 5.2) @@ -556,11 +589,11 @@ GEM activesupport (>= 3) shoulda-matchers (5.3.0) activesupport (>= 5.2.0) - sidekiq (7.1.3) + sidekiq (7.2.2) concurrent-ruby (< 2) connection_pool (>= 2.3.0) rack (>= 2.2.4) - redis-client (>= 0.14.0) + redis-client (>= 0.19.0) sidekiq-scheduler (5.0.1) rufus-scheduler (~> 3.2) sidekiq (>= 4, < 8) @@ -581,19 +614,20 @@ GEM hashie version_gem (~> 1.1, >= 1.1.1) spring (4.1.1) - sprockets (4.2.0) + sprockets (4.2.1) concurrent-ruby (~> 1.0) rack (>= 2.2.4, < 4) sprockets-rails (3.4.2) actionpack (>= 5.2) activesupport (>= 5.2) sprockets (>= 3.0.0) + stringio (3.1.0) stripe (8.2.0) strong_migrations (1.4.2) activerecord (>= 5.2) - thor (1.2.1) + thor (1.2.2) tilt (2.0.11) - timeout (0.3.2) + timeout (0.4.0) trailblazer-option (0.1.2) tzinfo (2.0.6) concurrent-ruby (~> 1.0) @@ -621,7 +655,7 @@ GEM websocket-extensions (0.1.5) xpath (3.2.0) nokogiri (~> 1.8) - zeitwerk (2.6.7) + zeitwerk (2.6.12) PLATFORMS arm64-darwin-21 @@ -638,7 +672,7 @@ DEPENDENCIES annotate aws-sdk-s3 bootsnap (>= 1.4.4) - bullet + bullet (~> 7.1) bundler-audit capybara (>= 3.26) countries @@ -663,7 +697,7 @@ DEPENDENCIES letter_opener letter_opener_web money - newrelic_rpm (~> 8.4) + newrelic_rpm (~> 9.8.0) nokogiri (>= 1.16.2) omniauth-google-oauth2 (~> 1.0) omniauth-rails_csrf_protection (~> 1.0) @@ -674,16 +708,16 @@ DEPENDENCIES pundit (~> 2.2) rack-cors (= 2.0.0) rack-mini-profiler (>= 2.3.3) - rails (~> 7.0.8.1) + rails (~> 7.1.3) rails-controller-testing (~> 1.0, >= 1.0.5) - ransack + ransack (~> 4.1) react-rails (= 2.6.2) redis (~> 4.0) rolify (~> 6.0) rspec-buildkite - rspec-rails (~> 5.0, >= 5.0.2) + rspec-rails (~> 6.1) rspec-retry - rspec-sidekiq + rspec-sidekiq! rubocop rubocop-performance rubocop-rails @@ -694,11 +728,11 @@ DEPENDENCIES searchkick selenium-webdriver (>= 4.0.0) sentry-rails - sentry-ruby + sentry-ruby (~> 5.17) shakapacker (= 6.0.0) shoulda-callback-matchers (~> 1.1.1) shoulda-matchers (~> 5.1) - sidekiq (< 8) + sidekiq (~> 7.2) sidekiq-scheduler simplecov spring diff --git a/app/services/projects/search_service.rb b/app/services/projects/search_service.rb deleted file mode 100644 index 030bd5628f..0000000000 --- a/app/services/projects/search_service.rb +++ /dev/null @@ -1,41 +0,0 @@ -# frozen_string_literal: true - -module Projects - class SearchService < ApplicationService - def initialize(query, current_company, client_id = nil, user_id = nil, billable = nil) - @query = query - @current_company = current_company - @client_id = client_id - @user_id = user_id - @billable = billable - end - - def process - minutes_spent = @current_company.timesheet_entries.kept.group(:project_id).sum(:duration) - project_list = project_list_query.ransack({ name_or_client_name_cont: @query }).result - project_ids = project_list.ids.uniq - - @current_company.projects.left_outer_joins([:project_members, :timesheet_entries]).joins([:client]).select( - "projects.id, - projects.name, - projects.billable, - clients.name as _client_name, - SUM(timesheet_entries.duration) as minutes_spent" - ).group("projects.id, clients.name").where(projects: { id: project_ids }).order("projects.name DESC") - end - - def project_list_query - @_project_list_query ||= @current_company.projects.kept.left_outer_joins(:project_members).joins(:client) - @_project_list_query ||= @_project_list_query.where(project_members: { user_id: }) if @user_id.present? - @_project_list_query ||= @_project_list_query.where(client_id:) if @client_id.present? - @_project_list_query ||= @_project_list_query.where(projects: { billable: }) if @billable.present? - - @_project_list_query.select( - "projects.id as id, - projects.name as project_name, - projects.billable as is_billable, - clients.name as project_client_name" - ) - end - end -end diff --git a/bin/setup b/bin/setup index 484df6f539..2af185f2d1 100755 --- a/bin/setup +++ b/bin/setup @@ -7,7 +7,7 @@ require "fileutils" APP_ROOT = File.expand_path("..", __dir__) def system!(*args) - system(*args) || abort("\n== Command #{args} failed ==") + system(*args, exception: true) end FileUtils.chdir APP_ROOT do @@ -21,6 +21,11 @@ FileUtils.chdir APP_ROOT do system! cmd system("bundle check") || system!("bundle install") + # puts "\n== Copying sample files ==" + # unless File.exist?("config/database.yml") + # FileUtils.cp "config/database.yml.sample", "config/database.yml" + # end + puts "\n== Executing yarn ==" system!("bin/yarn --frozen-lockfile ") diff --git a/config/application.rb b/config/application.rb index 5ca338751e..56a9aec35f 100644 --- a/config/application.rb +++ b/config/application.rb @@ -13,6 +13,11 @@ class Application < Rails::Application # Initialize configuration defaults for originally generated Rails version. config.load_defaults 7.0 + # Please, add to the `ignore` list any other `lib` subdirectories that do + # not contain `.rb` files, or that should not be reloaded or eager loaded. + # Common ones are `templates`, `generators`, or `middleware`, for example. + config.autoload_lib(ignore: %w(assets tasks)) + # Configuration for the application, engines, and railties goes here. # # These settings can be overridden in specific environments using the files @@ -20,7 +25,7 @@ class Application < Rails::Application # # config.time_zone = "Central Time (US & Canada)" # config.eager_load_paths << Rails.root.join("extras") - # + config.generators do |g| g.test_framework :rspec, fixture: false end @@ -35,7 +40,6 @@ class Application < Rails::Application config.action_mailer.delivery_method = email_delivery_method.to_sym end - config.autoload_paths << Rails.root.join("lib") config.active_model.i18n_customize_full_message = true config.react.camelize_props = true diff --git a/config/environments/development.rb b/config/environments/development.rb index 5a5312d5d4..bc9f590126 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -4,13 +4,11 @@ Rails.application.configure do # Settings specified here will take precedence over those in config/application.rb. - # This is to be used for ngrok. - # config.hosts << "bdf0-43-242-224-245.ngrok-free.app" # In the development environment your application's code is reloaded any time # it changes. This slows down response time but is perfect for development # since you don't have to restart the web server when you make code changes. - config.cache_classes = false + config.enable_reloading = true # Do not eager load code on boot. config.eager_load = false @@ -60,6 +58,9 @@ # Highlight code that triggered database queries in logs. config.active_record.verbose_query_logs = true + # Highlight code that enqueued background job in logs. + config.active_job.verbose_enqueue_logs = true + # Suppress logger output for asset requests. config.assets.quiet = true @@ -72,6 +73,9 @@ # Uncomment if you wish to allow Action Cable access from any origin. # config.action_cable.disable_request_forgery_protection = true + # Raise error when a before_action's only/except options reference missing actions + config.action_controller.raise_on_missing_callback_actions = true + # Action Mailer Configuration host = ENV.fetch("APP_BASE_URL", "localhost") config.action_mailer.default_url_options = { host: } diff --git a/config/environments/production.rb b/config/environments/production.rb index 71a3d11cf3..c2c0b2a67f 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -6,7 +6,7 @@ # Settings specified here will take precedence over those in config/application.rb. # Code is not reloaded between requests. - config.cache_classes = true + config.enable_reloading = false # Eager load code on boot. This eager loads most of Rails and # your application in memory, allowing both threaded web servers @@ -18,21 +18,22 @@ config.consider_all_requests_local = false config.action_controller.perform_caching = true - # Ensures that a master key has been made available in either ENV["RAILS_MASTER_KEY"] - # or in config/master.key. This key is used to decrypt credentials (and other encrypted files). + # Ensures that a master key has been made available in ENV["RAILS_MASTER_KEY"], config/master.key, or an environment + # key such as config/credentials/production.key. This key is used to decrypt credentials (and other encrypted files). # config.require_master_key = true - # Disable serving static files from the `/public` folder by default since - # Apache or NGINX already handles this. + # Enable static file serving from the `/public` folder (turn off if using NGINX/Apache for it). config.public_file_server.enabled = ENV["RAILS_SERVE_STATIC_FILES"].present? + # Compress CSS using a preprocessor. + # config.assets.css_compressor = :sass + # Do not fallback to assets pipeline if a precompiled asset is missed. config.assets.compile = false # Enable serving of images, stylesheets, and JavaScripts from an asset server. # config.asset_host = "http://assets.example.com" config.action_controller.asset_host = ENV["CLOUDFRONT_ASSET_HOST"] - # Specifies the header that your server uses for sending files. # config.action_dispatch.x_sendfile_header = "X-Sendfile" # for Apache # config.action_dispatch.x_sendfile_header = "X-Accel-Redirect" # for NGINX @@ -45,16 +46,26 @@ # config.action_cable.url = "wss://example.com/cable" # config.action_cable.allowed_request_origins = [ "http://example.com", /http:\/\/example.*/ ] + # Assume all access to the app is happening through a SSL-terminating reverse proxy. + # Can be used together with config.force_ssl for Strict-Transport-Security and secure cookies. + # config.assume_ssl = true + # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. config.force_ssl = false - # Include generic and useful information about system operation, but avoid logging too much - # information to avoid inadvertent exposure of personally identifiable information (PII). - config.log_level = :info + # Log to STDOUT by default + config.logger = ActiveSupport::Logger.new(STDOUT) + .tap { |logger| logger.formatter = ::Logger::Formatter.new } + .then { |logger| ActiveSupport::TaggedLogging.new(logger) } # Prepend all log lines with the following tags. config.log_tags = [ :request_id ] + # Info include generic and useful information about system operation, but avoids logging too much + # information to avoid inadvertent exposure of personally identifiable information (PII). If you + # want to log everything, set the level to "debug". + config.log_level = ENV.fetch("RAILS_LOG_LEVEL", "info") + # Use a different cache store in production. # config.cache_store = :mem_cache_store @@ -75,52 +86,16 @@ # Don't log any deprecations. config.active_support.report_deprecations = false - # Use default logging formatter so that PID and timestamp are not suppressed. - config.log_formatter = ::Logger::Formatter.new - - # Use a different logger for distributed setups. - # require "syslog/logger" - # config.logger = ActiveSupport::TaggedLogging.new(Syslog::Logger.new "app-name") - - if ENV["RAILS_LOG_TO_STDOUT"].present? - logger = ActiveSupport::Logger.new(STDOUT) - logger.formatter = config.log_formatter - config.logger = ActiveSupport::TaggedLogging.new(logger) - end - # Do not dump schema after migrations. config.active_record.dump_schema_after_migration = false - # Inserts middleware to perform automatic connection switching. - # The `database_selector` hash is used to pass options to the DatabaseSelector - # middleware. The `delay` is used to determine how long to wait after a write - # to send a subsequent read to the primary. - # - # The `database_resolver` class is used by the middleware to determine which - # database is appropriate to use based on the time delay. - # - # The `database_resolver_context` class is used by the middleware to set - # timestamps for the last write to the primary. The resolver uses the context - # class timestamps to determine how long to wait before reading from the - # replica. - # - # By default Rails will store a last write timestamp in the session. The - # DatabaseSelector middleware is designed as such you can define your own - # strategy for connection switching and pass that into the middleware through - # these configuration options. - # config.active_record.database_selector = { delay: 2.seconds } - # config.active_record.database_resolver = ActiveRecord::Middleware::DatabaseSelector::Resolver - # config.active_record.database_resolver_context = ActiveRecord::Middleware::DatabaseSelector::Resolver::Session - - # Inserts middleware to perform automatic shard swapping. The `shard_selector` hash - # can be used to pass options to the `ShardSelector` middleware. The `lock` option is - # used to determine whether shard swapping should be prohibited for the request. - # - # The `shard_resolver` option is used by the middleware to determine which shard - # to switch to. The application must provide a mechanism for finding the shard name - # in a proc. See guides for an example. - # config.active_record.shard_selector = { lock: true } - # config.active_record.shard_resolver = ->(request) { Tenant.find_by!(host: request.host).shard } + # Enable DNS rebinding protection and other `Host` header attacks. + # config.hosts = [ + # "example.com", # Allow requests from example.com + # /.*\.example\.com/ # Allow requests from subdomains like `www.example.com` + # ] + # Skip DNS rebinding protection for the default health check endpoint. + # config.host_authorization = { exclude: ->(request) { request.path == "/up" } } # Action Mailer Configuration host = ENV.fetch("APP_BASE_URL") diff --git a/config/environments/test.rb b/config/environments/test.rb index 6d4415cdf8..9fce0d1855 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -10,12 +10,13 @@ Rails.application.configure do # Settings specified here will take precedence over those in config/application.rb. - # Turn false under Spring and add config.action_view.cache_template_loading = true - config.cache_classes = true + # While tests run files are not watched, reloading is not necessary. + config.enable_reloading = false - # Eager loading loads your whole application. When running a single test locally, - # this probably isn't necessary. It's a good idea to do in a continuous integration - # system, or in some way before deploying your code. + # Eager loading loads your entire application. When running a single test locally, + # this is usually not necessary, and can slow down your test suite. However, it's + # recommended that you enable it in continuous integration systems to ensure eager + # loading is working properly before deploying your code. config.eager_load = ENV["CI"].present? # Configure public file server for tests with Cache-Control for performance. @@ -30,7 +31,7 @@ config.cache_store = :null_store # Raise exceptions instead of rendering exception templates. - config.action_dispatch.show_exceptions = false + config.action_dispatch.show_exceptions = :none # Disable request forgery protection in test environment. config.action_controller.allow_forgery_protection = false @@ -62,6 +63,9 @@ # Annotate rendered view with file names. # config.action_view.annotate_rendered_view_with_filenames = true + # Raise error when a before_action's only/except options reference missing actions + config.action_controller.raise_on_missing_callback_actions = true + # Action Mailer Configuration host = ENV.fetch("APP_BASE_URL", "localhost") config.action_mailer.default_url_options = { host: } diff --git a/config/initializers/assets.rb b/config/initializers/assets.rb index c5380b08dd..101a2902e5 100644 --- a/config/initializers/assets.rb +++ b/config/initializers/assets.rb @@ -4,6 +4,7 @@ # Version of your assets, change this if you want to expire all your assets. Rails.application.config.assets.version = "1.0" + # Add additional assets to the asset load path. # Rails.application.config.assets.paths << Emoji.images_path diff --git a/config/initializers/content_security_policy.rb b/config/initializers/content_security_policy.rb index f37ed8de48..af395e4632 100644 --- a/config/initializers/content_security_policy.rb +++ b/config/initializers/content_security_policy.rb @@ -1,9 +1,9 @@ # frozen_string_literal: true # Be sure to restart your server when you modify this file. -# Define an application-wide content security policy -# For further information see the following documentation -# https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy +# Define an application-wide content security policy. +# See the Securing Rails Applications Guide for more information: +# https://guides.rubyonrails.org/security.html#content-security-policy-header # Rails.application.configure do # config.content_security_policy do |policy| @@ -17,11 +17,10 @@ # # policy.report_uri "/csp-violation-report-endpoint" # end # -# # Generate session nonces for permitted importmap and inline scripts +# # Generate session nonces for permitted importmap, inline scripts, and inline styles. # config.content_security_policy_nonce_generator = ->(request) { request.session.id.to_s } -# config.content_security_policy_nonce_directives = %w(script-src) +# config.content_security_policy_nonce_directives = %w(script-src style-src) # -# # Report CSP violations to a specified URI. See: -# # https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy-Report-Only +# # Report violations without enforcing the policy. # # config.content_security_policy_report_only = true # end diff --git a/config/initializers/filter_parameter_logging.rb b/config/initializers/filter_parameter_logging.rb index 5118eb69cc..a119afa124 100644 --- a/config/initializers/filter_parameter_logging.rb +++ b/config/initializers/filter_parameter_logging.rb @@ -2,7 +2,9 @@ # Be sure to restart your server when you modify this file. -# Configure sensitive parameters which will be filtered from the log file. +# Configure parameters to be partially matched (e.g. passw matches password) and filtered from the log file. +# Use this to limit dissemination of sensitive information. +# See the ActiveSupport::ParameterFilter documentation for supported notations and behaviors. Rails.application.config.filter_parameters += [ :passw, :secret, :token, :_key, :crypt, :salt, :certificate, :otp, :ssn ] diff --git a/config/initializers/inflections.rb b/config/initializers/inflections.rb index 6c78420e71..9e049dcc91 100644 --- a/config/initializers/inflections.rb +++ b/config/initializers/inflections.rb @@ -1,4 +1,5 @@ # frozen_string_literal: true + # Be sure to restart your server when you modify this file. # Add new inflection rules using the following format. Inflections diff --git a/config/initializers/new_framework_defaults_7_1.rb b/config/initializers/new_framework_defaults_7_1.rb new file mode 100644 index 0000000000..974cc2aa3a --- /dev/null +++ b/config/initializers/new_framework_defaults_7_1.rb @@ -0,0 +1,224 @@ +# frozen_string_literal: true +# Be sure to restart your server when you modify this file. +# +# This file eases your Rails 7.1 framework defaults upgrade. +# +# Uncomment each configuration one by one to switch to the new default. +# Once your application is ready to run with all new defaults, you can remove +# this file and set the `config.load_defaults` to `7.1`. +# +# Read the Guide for Upgrading Ruby on Rails for more info on each option. +# https://guides.rubyonrails.org/upgrading_ruby_on_rails.html + +# No longer add autoloaded paths into `$LOAD_PATH`. This means that you won't be able +# to manually require files that are managed by the autoloader, which you shouldn't do anyway. +# This will reduce the size of the load path, making `require` faster if you don't use bootsnap, or reduce the size +# of the bootsnap cache if you use it. +# Rails.application.config.add_autoload_paths_to_load_path = false + +# Remove the default X-Download-Options headers since it is used only by Internet Explorer. +# If you need to support Internet Explorer, add back `"X-Download-Options" => "noopen"`. +# Rails.application.config.action_dispatch.default_headers = { +# "X-Frame-Options" => "SAMEORIGIN", +# "X-XSS-Protection" => "0", +# "X-Content-Type-Options" => "nosniff", +# "X-Permitted-Cross-Domain-Policies" => "none", +# "Referrer-Policy" => "strict-origin-when-cross-origin" +# } + +# Do not treat an `ActionController::Parameters` instance +# as equal to an equivalent `Hash` by default. +# Rails.application.config.action_controller.allow_deprecated_parameters_hash_equality = false + +# Active Record Encryption now uses SHA-256 as its hash digest algorithm. Important: If you have +# data encrypted with previous Rails versions, there are two scenarios to consider: +# +# 1. If you have +config.active_support.key_generator_hash_digest_class+ configured as SHA1 (the default +# before Rails 7.0), you need to configure SHA-1 for Active Record Encryption too: +# Rails.application.config.active_record.encryption.hash_digest_class = OpenSSL::Digest::SHA1 +# 2. If you have +config.active_support.key_generator_hash_digest_class+ configured as SHA256 (the new default +# in 7.0), then you need to configure SHA-256 for Active Record Encryption: +# Rails.application.config.active_record.encryption.hash_digest_class = OpenSSL::Digest::SHA256 +# +# If you don't currently have data encrypted with Active Record encryption, you can disable this setting to +# configure the default behavior starting 7.1+: +# Rails.application.config.active_record.encryption.support_sha1_for_non_deterministic_encryption = false + +# No longer run after_commit callbacks on the first of multiple Active Record +# instances to save changes to the same database row within a transaction. +# Instead, run these callbacks on the instance most likely to have internal +# state which matches what was committed to the database, typically the last +# instance to save. +# Rails.application.config.active_record.run_commit_callbacks_on_first_saved_instances_in_transaction = false + +# Configures SQLite with a strict strings mode, which disables double-quoted string literals. +# +# SQLite has some quirks around double-quoted string literals. +# It first tries to consider double-quoted strings as identifier names, but if they don't exist +# it then considers them as string literals. Because of this, typos can silently go unnoticed. +# For example, it is possible to create an index for a non existing column. +# See https://www.sqlite.org/quirks.html#double_quoted_string_literals_are_accepted for more details. +# Rails.application.config.active_record.sqlite3_adapter_strict_strings_by_default = true + +# Disable deprecated singular associations names +# Rails.application.config.active_record.allow_deprecated_singular_associations_name = false + +# Enable the Active Job `BigDecimal` argument serializer, which guarantees +# roundtripping. Without this serializer, some queue adapters may serialize +# `BigDecimal` arguments as simple (non-roundtrippable) strings. +# +# When deploying an application with multiple replicas, old (pre-Rails 7.1) +# replicas will not be able to deserialize `BigDecimal` arguments from this +# serializer. Therefore, this setting should only be enabled after all replicas +# have been successfully upgraded to Rails 7.1. +# Rails.application.config.active_job.use_big_decimal_serializer = true + +# Specify if an `ArgumentError` should be raised if `Rails.cache` `fetch` or +# `write` are given an invalid `expires_at` or `expires_in` time. +# Options are `true`, and `false`. If `false`, the exception will be reported +# as `handled` and logged instead. +# Rails.application.config.active_support.raise_on_invalid_cache_expiration_time = true + +# Specify whether Query Logs will format tags using the SQLCommenter format +# (https://open-telemetry.github.io/opentelemetry-sqlcommenter/), or using the legacy format. +# Options are `:legacy` and `:sqlcommenter`. +# Rails.application.config.active_record.query_log_tags_format = :sqlcommenter + +# Specify the default serializer used by `MessageEncryptor` and `MessageVerifier` +# instances. +# +# The legacy default is `:marshal`, which is a potential vector for +# deserialization attacks in cases where a message signing secret has been +# leaked. +# +# In Rails 7.1, the new default is `:json_allow_marshal` which serializes and +# deserializes with `ActiveSupport::JSON`, but can fall back to deserializing +# with `Marshal` so that legacy messages can still be read. +# +# In Rails 7.2, the default will become `:json` which serializes and +# deserializes with `ActiveSupport::JSON` only. +# +# Alternatively, you can choose `:message_pack` or `:message_pack_allow_marshal`, +# which serialize with `ActiveSupport::MessagePack`. `ActiveSupport::MessagePack` +# can roundtrip some Ruby types that are not supported by JSON, and may provide +# improved performance, but it requires the `msgpack` gem. +# +# For more information, see +# https://guides.rubyonrails.org/v7.1/configuring.html#config-active-support-message-serializer +# +# If you are performing a rolling deploy of a Rails 7.1 upgrade, wherein servers +# that have not yet been upgraded must be able to read messages from upgraded +# servers, first deploy without changing the serializer, then set the serializer +# in a subsequent deploy. +# Rails.application.config.active_support.message_serializer = :json_allow_marshal + +# Enable a performance optimization that serializes message data and metadata +# together. This changes the message format, so messages serialized this way +# cannot be read by older versions of Rails. However, messages that use the old +# format can still be read, regardless of whether this optimization is enabled. +# +# To perform a rolling deploy of a Rails 7.1 upgrade, wherein servers that have +# not yet been upgraded must be able to read messages from upgraded servers, +# leave this optimization off on the first deploy, then enable it on a +# subsequent deploy. +# Rails.application.config.active_support.use_message_serializer_for_metadata = true + +# Set the maximum size for Rails log files. +# +# `config.load_defaults 7.1` does not set this value for environments other than +# development and test. +# +# if Rails.env.local? +# Rails.application.config.log_file_size = 100 * 1024 * 1024 +# end + +# Enable raising on assignment to attr_readonly attributes. The previous +# behavior would allow assignment but silently not persist changes to the +# database. +# Rails.application.config.active_record.raise_on_assign_to_attr_readonly = true + +# Enable validating only parent-related columns for presence when the parent is mandatory. +# The previous behavior was to validate the presence of the parent record, which performed an extra query +# to get the parent every time the child record was updated, even when parent has not changed. +# Rails.application.config.active_record.belongs_to_required_validates_foreign_key = false + +# Enable precompilation of `config.filter_parameters`. Precompilation can +# improve filtering performance, depending on the quantity and types of filters. +# Rails.application.config.precompile_filter_parameters = true + +# Enable before_committed! callbacks on all enrolled records in a transaction. +# The previous behavior was to only run the callbacks on the first copy of a record +# if there were multiple copies of the same record enrolled in the transaction. +# Rails.application.config.active_record.before_committed_on_all_records = true + +# Disable automatic column serialization into YAML. +# To keep the historic behavior, you can set it to `YAML`, however it is +# recommended to explicitly define the serialization method for each column +# rather than to rely on a global default. +# Rails.application.config.active_record.default_column_serializer = nil + +# Enable a performance optimization that serializes Active Record models +# in a faster and more compact way. +# +# To perform a rolling deploy of a Rails 7.1 upgrade, wherein servers that have +# not yet been upgraded must be able to read caches from upgraded servers, +# leave this optimization off on the first deploy, then enable it on a +# subsequent deploy. +# Rails.application.config.active_record.marshalling_format_version = 7.1 + +# Run `after_commit` and `after_*_commit` callbacks in the order they are defined in a model. +# This matches the behaviour of all other callbacks. +# In previous versions of Rails, they ran in the inverse order. +# Rails.application.config.active_record.run_after_transaction_callbacks_in_order_defined = true + +# Whether a `transaction` block is committed or rolled back when exited via `return`, `break` or `throw`. +# +# Rails.application.config.active_record.commit_transaction_on_non_local_return = true + +# Controls when to generate a value for has_secure_token declarations. +# +# Rails.application.config.active_record.generate_secure_token_on = :initialize + +# ** Please read carefully, this must be configured in config/application.rb ** +# Change the format of the cache entry. +# Changing this default means that all new cache entries added to the cache +# will have a different format that is not supported by Rails 7.0 +# applications. +# Only change this value after your application is fully deployed to Rails 7.1 +# and you have no plans to rollback. +# When you're ready to change format, add this to `config/application.rb` (NOT +# this file): +# config.active_support.cache_format_version = 7.1 + +# Configure Action View to use HTML5 standards-compliant sanitizers when they are supported on your +# platform. +# +# `Rails::HTML::Sanitizer.best_supported_vendor` will cause Action View to use HTML5-compliant +# sanitizers if they are supported, else fall back to HTML4 sanitizers. +# +# In previous versions of Rails, Action View always used `Rails::HTML4::Sanitizer` as its vendor. +# +# Rails.application.config.action_view.sanitizer_vendor = Rails::HTML::Sanitizer.best_supported_vendor + +# Configure Action Text to use an HTML5 standards-compliant sanitizer when it is supported on your +# platform. +# +# `Rails::HTML::Sanitizer.best_supported_vendor` will cause Action Text to use HTML5-compliant +# sanitizers if they are supported, else fall back to HTML4 sanitizers. +# +# In previous versions of Rails, Action Text always used `Rails::HTML4::Sanitizer` as its vendor. +# +# Rails.application.config.action_text.sanitizer_vendor = Rails::HTML::Sanitizer.best_supported_vendor + +# Configure the log level used by the DebugExceptions middleware when logging +# uncaught exceptions during requests +# Rails.application.config.action_dispatch.debug_exception_log_level = :error + +# Configure the test helpers in Action View, Action Dispatch, and rails-dom-testing to use HTML5 +# parsers. +# +# Nokogiri::HTML5 isn't supported on JRuby, so JRuby applications must set this to :html4. +# +# In previous versions of Rails, these test helpers always used an HTML4 parser. +# +# Rails.application.config.dom_testing_default_html_version = :html5 diff --git a/config/initializers/permissions_policy.rb b/config/initializers/permissions_policy.rb index 50bcf4eade..b635b527ea 100644 --- a/config/initializers/permissions_policy.rb +++ b/config/initializers/permissions_policy.rb @@ -1,12 +1,14 @@ # frozen_string_literal: true +# Be sure to restart your server when you modify this file. + # Define an application-wide HTTP permissions policy. For further -# information see https://developers.google.com/web/updates/2018/06/feature-policy -# -# Rails.application.config.permissions_policy do |f| -# f.camera :none -# f.gyroscope :none -# f.microphone :none -# f.usb :none -# f.fullscreen :self -# f.payment :self, "https://secure.example.com" +# information see: https://developers.google.com/web/updates/2018/06/feature-policy + +# Rails.application.config.permissions_policy do |policy| +# policy.camera :none +# policy.gyroscope :none +# policy.microphone :none +# policy.usb :none +# policy.fullscreen :self +# policy.payment :self, "https://secure.example.com" # end diff --git a/db/migrate/20240331034032_add_service_name_to_active_storage_blobs.active_storage.rb b/db/migrate/20240331034032_add_service_name_to_active_storage_blobs.active_storage.rb new file mode 100644 index 0000000000..7f236bada8 --- /dev/null +++ b/db/migrate/20240331034032_add_service_name_to_active_storage_blobs.active_storage.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true + +# This migration comes from active_storage (originally 20190112182829) +class AddServiceNameToActiveStorageBlobs < ActiveRecord::Migration[7.1] + def up + return unless table_exists?(:active_storage_blobs) + + unless column_exists?(:active_storage_blobs, :service_name) + add_column :active_storage_blobs, :service_name, :string + + if (configured_service = ActiveStorage::Blob.service.name) + ActiveStorage::Blob.unscoped.update_all(service_name: configured_service) + end + + change_column :active_storage_blobs, :service_name, :string, null: false + end + end + + def down + return unless table_exists?(:active_storage_blobs) + + remove_column :active_storage_blobs, :service_name + end +end diff --git a/db/migrate/20240331034127_create_active_storage_variant_records.active_storage.rb b/db/migrate/20240331034127_create_active_storage_variant_records.active_storage.rb new file mode 100644 index 0000000000..d8fa25802b --- /dev/null +++ b/db/migrate/20240331034127_create_active_storage_variant_records.active_storage.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true + +# This migration comes from active_storage (originally 20191206030411) +class CreateActiveStorageVariantRecords < ActiveRecord::Migration[7.1] + def change + return unless table_exists?(:active_storage_blobs) + + # Use Active Record's configured type for primary key + create_table :active_storage_variant_records, id: primary_key_type, if_not_exists: true do |t| + t.belongs_to :blob, null: false, index: false, type: blobs_primary_key_type + t.string :variation_digest, null: false + + t.index %i[ blob_id variation_digest ], name: "index_active_storage_variant_records_uniqueness", unique: true + t.foreign_key :active_storage_blobs, column: :blob_id + end + end + + private + + def primary_key_type + config = Rails.configuration.generators + config.options[config.orm][:primary_key_type] || :primary_key + end + + def blobs_primary_key_type + pkey_name = connection.primary_key(:active_storage_blobs) + pkey_column = connection.columns(:active_storage_blobs).find { |c| c.name == pkey_name } + pkey_column.bigint? ? :bigint : pkey_column.type + end +end diff --git a/db/migrate/20240331034308_remove_not_null_on_active_storage_blobs_checksum.active_storage.rb b/db/migrate/20240331034308_remove_not_null_on_active_storage_blobs_checksum.active_storage.rb new file mode 100644 index 0000000000..340a671f4b --- /dev/null +++ b/db/migrate/20240331034308_remove_not_null_on_active_storage_blobs_checksum.active_storage.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +# This migration comes from active_storage (originally 20211119233751) +class RemoveNotNullOnActiveStorageBlobsChecksum < ActiveRecord::Migration[7.1] + def change + return unless table_exists?(:active_storage_blobs) + + change_column_null(:active_storage_blobs, :checksum, true) + end +end diff --git a/db/schema.rb b/db/schema.rb index a0c42bf716..813770e521 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.0].define(version: 2024_04_11_174949) do +ActiveRecord::Schema[7.1].define(version: 2024_04_11_174949) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -157,6 +157,9 @@ t.jsonb "specifications" t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.boolean "is_insured", default: false + t.date "insurance_bought_date" + t.date "insurance_expiry_date" t.index ["company_id"], name: "index_devices_on_company_id" t.index ["device_type"], name: "index_devices_on_device_type" t.index ["user_id"], name: "index_devices_on_user_id" diff --git a/spec/services/projects/search_service_spec.rb b/spec/services/projects/search_service_spec.rb deleted file mode 100644 index ff6a984c6e..0000000000 --- a/spec/services/projects/search_service_spec.rb +++ /dev/null @@ -1,73 +0,0 @@ -# frozen_string_literal: true - -require "rails_helper" - -describe Projects::SearchService do - let(:company) { create(:company) } - let(:client1) { create(:client, company:) } - let(:client2) { create(:client, company:) } - let(:project1) { create(:project, client: client1) } - let(:project2) { create(:project, client: client1) } - let(:project3) { create(:project, client: client2) } - let(:project4) { create(:project, client: client2) } - - describe "#process" do - it "returns all projects" do - service = Projects::SearchService.new(nil, company, nil, nil, nil) - expect(service.process).to eq(company.projects.kept) - end - - it "returns projects by client" do - service = Projects::SearchService.new(nil, company, client1.id, nil, nil) - expect(service.process).to eq(client1.projects.kept) - end - - it "returns projects by billable" do - service = Projects::SearchService.new(nil, company, nil, nil, true) - expect(service.process).to eq(company.projects.kept.where(billable: true)) - end - - it "returns projects by search" do - service = Projects::SearchService.new(project1.name, company, nil, nil, nil) - expect(service.process).to eq([project1]) - end - - it "returns projects by user" do - user = create(:user, current_workspace_id: company.id) - create(:project_member, user:, project: project1) - service = Projects::SearchService.new(nil, company, nil, user.id, nil) - expect(service.process).to eq([project1]) - end - - it "returns projects by user and client" do - user = create(:user, current_workspace_id: company.id) - create(:project_member, user:, project: project1) - service = Projects::SearchService.new(nil, company, client1.id, user.id, nil) - expect(service.process).to eq([project1]) - end - - it "returns projects by user and billable" do - user = create(:user, current_workspace_id: company.id) - create(:project_member, user:, project: project1) - service = Projects::SearchService.new(nil, company, nil, user.id, true) - expect(service.process).to eq([project1]) - end - - it "returns projects by user and search" do - user = create(:user, current_workspace_id: company.id) - create(:project_member, user:, project: project1) - service = Projects::SearchService.new(project1.name, company, nil, user.id, nil) - expect(service.process).to eq([project1]) - end - - it "returns projects by client and billable" do - service = Projects::SearchService.new(nil, company, client1.id, nil, true) - expect(service.process).to eq(client1.projects.kept.where(billable: true)) - end - - it "returns projects by client and search" do - service = Projects::SearchService.new(project1.name, company, client1.id, nil, nil) - expect(service.process).to eq(client1.projects.kept.where(id: project1.id)) - end - end -end