Skip to content

Commit

Permalink
Merge branch 'release/0.5.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
akhilgkrishnan committed Oct 27, 2022
2 parents 2a2a86b + 9bb04cf commit 737aaa4
Show file tree
Hide file tree
Showing 91 changed files with 1,429 additions and 704 deletions.
3 changes: 3 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,6 @@ WISE_PROFILE_ID="123456"

#Feature Flags
ENABLE_WEEKLY_REMINDER=

# Sentry
SENTRY_DSN=
2 changes: 1 addition & 1 deletion .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -663,7 +663,7 @@ RSpec/MultipleMemoizedHelpers:
Description: Checks if example groups contain too many `let` and `subject` calls.
Enabled: true
StyleGuide: https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/MultipleMemoizedHelpers
Max: 10
Max: 15

RSpec/MissingExampleGroupArgument:
Description: Checks that the first argument to an example group is not empty.
Expand Down
File renamed without changes.
8 changes: 5 additions & 3 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -127,13 +127,15 @@ gem "grover"

gem "activerecord-import"

# Honeybadger for error reporting
gem "honeybadger"

# For finding the vulnerabilities in the gems
gem "bundler-audit", require: false
gem "ruby_audit", require: false

# For reporting messages, exceptions, and tracing events.
gem "sentry-rails"
gem "sentry-ruby"
gem "sentry-sidekiq"

group :development, :test do
# See https://edgeguides.rubyonrails.org/debugging_rails_applications.html#debugging-with-the-debug-gem
gem "debug", ">= 1.0.0", platforms: %i[mri mingw x64_mingw]
Expand Down
20 changes: 15 additions & 5 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -216,7 +216,6 @@ GEM
nokogiri (~> 1.0)
hashdiff (1.0.1)
hashie (5.0.0)
honeybadger (4.12.1)
i18n (1.10.0)
concurrent-ruby (~> 1.0)
i18n_data (0.16.0)
Expand Down Expand Up @@ -274,13 +273,13 @@ GEM
timeout
newrelic_rpm (8.7.0)
nio4r (2.5.8)
nokogiri (1.13.7-aarch64-linux)
nokogiri (1.13.9-aarch64-linux)
racc (~> 1.4)
nokogiri (1.13.7-arm64-darwin)
nokogiri (1.13.9-arm64-darwin)
racc (~> 1.4)
nokogiri (1.13.7-x86_64-darwin)
nokogiri (1.13.9-x86_64-darwin)
racc (~> 1.4)
nokogiri (1.13.7-x86_64-linux)
nokogiri (1.13.9-x86_64-linux)
racc (~> 1.4)
oauth2 (1.4.9)
faraday (>= 0.17.3, < 3.0)
Expand Down Expand Up @@ -445,6 +444,14 @@ GEM
rubyzip (>= 1.2.2, < 3.0)
websocket (~> 1.0)
semantic_range (3.0.0)
sentry-rails (5.5.0)
railties (>= 5.0)
sentry-ruby (~> 5.5.0)
sentry-ruby (5.5.0)
concurrent-ruby (~> 1.0, >= 1.0.2)
sentry-sidekiq (5.5.0)
sentry-ruby (~> 5.5.0)
sidekiq (>= 3.0)
shoulda-callback-matchers (1.1.4)
activesupport (>= 3)
shoulda-matchers (5.1.0)
Expand Down Expand Up @@ -570,6 +577,9 @@ DEPENDENCIES
sass-rails
searchkick
selenium-webdriver (>= 4.0.0)
sentry-rails
sentry-ruby
sentry-sidekiq
shoulda-callback-matchers (~> 1.1.1)
shoulda-matchers (~> 5.1)
sidekiq
Expand Down
8 changes: 0 additions & 8 deletions app/controllers/internal_api/v1/clients_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -53,14 +53,6 @@ def destroy
end
end

def new_invoice_line_items
authorize client
render json: {
client:,
lineItems: client.new_line_item_entries([])
}, status: :ok
end

private

def client
Expand Down
13 changes: 9 additions & 4 deletions app/controllers/internal_api/v1/generate_invoice_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

class InternalApi::V1::GenerateInvoiceController < InternalApi::V1::ApplicationController
def index
authorize :index, policy_class: GenerateInvoicePolicy
authorize client, policy_class: GenerateInvoicePolicy
render :index, locals: {
filter_options:,
new_line_item_entries:,
Expand All @@ -13,7 +13,7 @@ def index
private

def client
@_client ||= Client.find(params[:client_id])
@_client ||= Client.find_by(id: params[:client_id])
end

def project
Expand All @@ -40,10 +40,15 @@ def project_filter
{ project_id: project }
end

def unbilled_status_filter
{ bill_status: "unbilled" }
end

def new_line_item_entries
default_filter = project_filter.merge(unselected_time_entries_filter)
where_clause = default_filter.merge(TimeEntries::Filters.process(params))
search_result = TimesheetEntry.search(
bill_status_filter = default_filter.merge(unbilled_status_filter)
where_clause = bill_status_filter.merge(TimeEntries::Filters.process(params))
@_new_line_item_entries ||= TimesheetEntry.search(
search_term,
fields: [:note, :user_name],
match: :text_middle,
Expand Down
6 changes: 3 additions & 3 deletions app/controllers/internal_api/v1/invoices_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ def create
end

def edit
authorize Invoice
authorize invoice
render :edit, locals: { invoice: }
end

Expand All @@ -47,7 +47,7 @@ def update
end

def show
authorize Invoice
authorize invoice
render :show, locals: {
invoice:
}
Expand All @@ -73,7 +73,7 @@ def send_invoice
def download
authorize invoice

send_data InvoicePayment::PdfGeneration.process(invoice, current_company.company_logo)
send_data InvoicePayment::PdfGeneration.process(invoice, current_company.company_logo, root_url)
end

private
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

class InternalApi::V1::ProjectMembersController < InternalApi::V1::ApplicationController
def update
authorize ProjectMember
authorize project, policy_class: ProjectMemberPolicy

ActiveRecord::Base.transaction do
add_new_members
Expand Down Expand Up @@ -62,4 +62,8 @@ def updated_members_params
def removed_members_params
params.require(:members).permit(removed_member_ids: [])["removed_member_ids"]
end

def project
@_project ||= Project.find_by(id: params[:id])
end
end
24 changes: 20 additions & 4 deletions app/controllers/internal_api/v1/projects/search_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,29 @@ class InternalApi::V1::Projects::SearchController < InternalApi::V1::Application
skip_after_action :verify_authorized, only: [:index]

def index
projects = Project.search_all_projects_by_name(search_params, current_company.id)
render json: { projects: }, status: :ok
render :index, locals: {
searched_projects:,
total_searched_projects: searched_projects.total_count
}, status: :ok
end

private

def search_params
params.require(:search_term)
def search_term
@search_term ||= (params[:search_term].present?) ? params[:search_term] : ""
end

def client_list
@_client_list ||= current_company.clients.pluck(:id).uniq
end

def searched_projects
@_searched_projects ||= Project.search(
search_term,
fields: [:client_name, :name],
match: :text_middle,
where: { client_id: client_list },
includes: [:client]
)
end
end
2 changes: 1 addition & 1 deletion app/controllers/internal_api/v1/projects_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ def index
end

def show
authorize Project
authorize project
render :show, locals: { project: }, status: :ok
end

Expand Down
22 changes: 11 additions & 11 deletions app/controllers/internal_api/v1/team_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,8 @@ def index
render :index, locals: { teams:, invitations: }, status: :ok
end

def destroy
authorize :team
employment.discard!
render json: {
user: employment.user,
notice: I18n.t("team.delete.success.message")
}, status: :ok
end

def update
authorize :team
authorize employment, policy_class: TeamPolicy
User.transaction do
employment.user.skip_reconfirmation!
employment.user.update!(user_params)
Expand All @@ -37,10 +28,19 @@ def update
}, status: :ok
end

def destroy
authorize employment, policy_class: TeamPolicy
employment.discard!
render json: {
user: employment.user,
notice: I18n.t("team.delete.success.message")
}, status: :ok
end

private

def employment
@employment ||= current_company.employments.kept.find_by!(user_id: params[:id])
@_employment ||= current_company.employments.kept.find_by!(user_id: params[:id])
end

def user_params
Expand Down
74 changes: 74 additions & 0 deletions app/javascript/src/StyledComponents/Avatar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import React, { useState, useEffect } from "react";

import classnames from "classnames";

const avatar = require("../../../assets/images/NavAvatar.svg"); //eslint-disable-line

type AvatarProps = {
url?: string;
name?: string;
classNameImg?: string;
classNameInitials?: string;
classNameInitialsWrapper?: string;
};

const Avatar = ({
url = "",
name = "",
classNameImg = "",
classNameInitials = "",
classNameInitialsWrapper = ""
}: AvatarProps) => {
const [initials, setInitials] = useState<string>(null);
const DEFAULT_STYLE_IMAGE = "inline-block md:h-10 md:w-10 h-5 w-5 rounded-full";
const DEFAULT_STYLE_INITIALS = "md:text-xl text-xs md:font-medium font-light leading-none text-white";
const DEFAULT_STYLE_INITIALS_WRAPPER = "inline-flex md:h-10 md:w-10 h-6 w-6 rounded-full items-center justify-center bg-gray-500";

const getInitials = () => {
if (name) {
const parts = name.match(/\b(\w)/g);
const initials = parts.join("").slice(0,2);
setInitials(initials.toUpperCase());
}
};

useEffect(() => getInitials(), []);

if (url) {
return (
<img
className={classnames(DEFAULT_STYLE_IMAGE, classNameImg)}
src={url}
alt="profile_pic"
/>
);
}
if (initials) {
return (
<div className={classnames("inline-block")}>
<span
className={classnames(
DEFAULT_STYLE_INITIALS_WRAPPER,
classNameInitialsWrapper
)}
>
<span
className={classnames(DEFAULT_STYLE_INITIALS, classNameInitials)}
>
{initials}
</span>
</span>
</div>
);
}

return (
<img
src={avatar}
className={classnames(DEFAULT_STYLE_IMAGE, classNameImg)}
alt="avatar"
/>
);
};

export default Avatar;
52 changes: 52 additions & 0 deletions app/javascript/src/StyledComponents/Tooltip.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import React, { useState } from "react";

import classnames from "classnames";

type TooltipProps = {
content?: string;
placeBottom?: boolean;
delay?: number;
className?: string;
children?: object;
};

const Tooltip = ({
content,
placeBottom = false,
delay = 400,
className,
...restprops
}: TooltipProps) => {
let timeout;
const [active, setActive] = useState<boolean>(false);
const DEFAULT_STYLE = `before:h-0 before:w-0 before:absolute before:pointer-events-none before:border-4 before:mr-4 before:content-none before:left-1/2
absolute left-1/2 z-10 rounded-md p-2 text-miru-dark-purple-1000 bg-miru-gray-1000 text-sm leading-none whitespace-nowrap ${
placeBottom ? "top-full mt-2" : "bottom-full mb-2"
}`;

const showTip = () => {
timeout = setTimeout(() => {
setActive(true);
}, delay);
};

const hideTip = () => {
clearInterval(timeout);
setActive(false);
};

return (
<div
className={classnames("block relative")}
onMouseEnter={showTip}
onMouseLeave={hideTip}
>
{restprops.children}
{active && (
<div className={classnames(DEFAULT_STYLE, className)}>{content}</div>
)}
</div>
);
};

export default Tooltip;
Loading

0 comments on commit 737aaa4

Please sign in to comment.