Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: department pages #470

Merged
merged 47 commits into from
Apr 18, 2024
Merged
Show file tree
Hide file tree
Changes from 34 commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
5f97303
refactor: department index & show
joaodiaslobo Feb 24, 2024
80d3c7e
feat: pagination
joaodiaslobo Feb 24, 2024
a8e8250
feat: collaborators view
joaodiaslobo Feb 25, 2024
7597828
Merge branch 'develop' into jl/improve-departments-pages
joaodiaslobo Feb 25, 2024
7cb85d4
feat: department collaborator applications configuration
joaodiaslobo Feb 26, 2024
03e92aa
Merge branch 'develop' into jl/improve-departments-pages
joaodiaslobo Feb 27, 2024
3eb77a9
feat: collaborator edit modal
joaodiaslobo Feb 27, 2024
f552711
chore: format
joaodiaslobo Feb 27, 2024
deee179
fix: unecessary parameter
joaodiaslobo Feb 27, 2024
0c1daa5
Merge branch 'develop' into jl/improve-departments-pages
joaodiaslobo Mar 13, 2024
3ba4ccb
fix: woop
joaodiaslobo Mar 13, 2024
368fc95
Merge branch 'develop' into jl/improve-departments-pages
joaodiaslobo Mar 13, 2024
c384855
feat: confirm modals
joaodiaslobo Mar 16, 2024
8339f19
Merge branch 'develop' into jl/improve-departments-pages
joaodiaslobo Mar 16, 2024
367caae
feat: remove collaborator
joaodiaslobo Mar 16, 2024
6f78aef
feat: table improvements
joaodiaslobo Mar 16, 2024
df087e8
refactor: action buttons
joaodiaslobo Mar 17, 2024
0dbcb01
feat: edit & new page
joaodiaslobo Mar 19, 2024
6fef032
refactor: single file component
joaodiaslobo Mar 19, 2024
e378b7b
refactor: code readability
joaodiaslobo Mar 19, 2024
e6547e8
feat: initial banner logic
joaodiaslobo Mar 19, 2024
41c639d
refactor: ui changes
joaodiaslobo Mar 19, 2024
233d348
feat: add icon to new department button
joaodiaslobo Mar 19, 2024
a9a25fd
Merge branch 'develop' into jl/improve-departments-pages
joaodiaslobo Mar 19, 2024
347dcdd
feat: accept or deny collaborator requests
joaodiaslobo Mar 21, 2024
6cab79c
Merge branch 'develop' into jl/improve-departments-pages
joaodiaslobo Mar 21, 2024
5773091
refactor: use pattern matching for department form
joaodiaslobo Mar 21, 2024
4f8efd7
Merge branch 'develop' into jl/improve-departments-pages
joaodiaslobo Mar 22, 2024
aa71f14
refactor: use new forms components
joaodiaslobo Mar 24, 2024
2c8a19a
feat: empty states
joaodiaslobo Mar 27, 2024
234cf40
fix: stupid bug
joaodiaslobo Mar 27, 2024
62c0d71
feat: archive and delete actions
joaodiaslobo Apr 10, 2024
f3fc197
fix: department banner upload
joaodiaslobo Apr 11, 2024
be1945e
fix: department show on mobile
joaodiaslobo Apr 11, 2024
aceb458
chore: remove kanban board button (will be added when implemented)
joaodiaslobo Apr 14, 2024
f86da76
ux: delete department tooltip
joaodiaslobo Apr 14, 2024
01976a3
chore: suggestions and ensure strings uses `gettext`
joaodiaslobo Apr 15, 2024
fcab0eb
chore: specify `button` type
joaodiaslobo Apr 15, 2024
dac435b
refactor: modal parent notify logic
joaodiaslobo Apr 15, 2024
d9fd1b5
BREAKING CHANGE: 👹
joaodiaslobo Apr 15, 2024
cb4115c
feat: banner resolution recommendation
joaodiaslobo Apr 15, 2024
e2d291b
feat: gradient component
joaodiaslobo Apr 15, 2024
5e27395
ci: lint
joaodiaslobo Apr 15, 2024
226f079
fix: stupid
joaodiaslobo Apr 15, 2024
66dd16c
feat: add collaborator accepted email
joaodiaslobo Apr 17, 2024
4184f1b
feat: notify department admins on new collaborator request
joaodiaslobo Apr 18, 2024
41631d0
fix: mario
joaodiaslobo Apr 18, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion assets/css/components/button.css
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/* Buttons */

.atomic-button {
@apply inline-flex items-center justify-center font-medium transition duration-150 ease-in-out border rounded-md focus:outline-none;
@apply inline-flex items-center justify-center font-medium transition duration-150 ease-in-out border rounded-md select-none focus:outline-none;
}

/* Buttons - sizes */
Expand Down
99 changes: 96 additions & 3 deletions lib/atomic/departments.ex
Original file line number Diff line number Diff line change
Expand Up @@ -87,10 +87,11 @@ defmodule Atomic.Departments do
{:error, %Ecto.Changeset{}}

"""
def create_department(attrs \\ %{}) do
def create_department(attrs \\ %{}, after_save \\ &{:ok, &1}) do
%Department{}
|> Department.changeset(attrs)
|> Repo.insert()
|> after_save(after_save)
end

@doc """
Expand All @@ -105,10 +106,11 @@ defmodule Atomic.Departments do
{:error, %Ecto.Changeset{}}

"""
def update_department(%Department{} = department, attrs) do
def update_department(%Department{} = department, attrs, after_save \\ &{:ok, &1}) do
department
|> Department.changeset(attrs)
|> Repo.update()
|> after_save(after_save)
end

@doc """
Expand All @@ -127,6 +129,42 @@ defmodule Atomic.Departments do
Repo.delete(department)
end

@doc """
Archives a department.

## Examples

iex> archive_department(department)
{:ok, %Department{}}

iex> archive_department(department)
{:error, %Ecto.Changeset{}}

"""
def archive_department(%Department{} = department) do
department
|> Department.changeset(%{archived: true})
|> Repo.update()
end

@doc """
Unarchives a department.

## Examples

iex> unarchive_department(department)
{:ok, %Department{}}

iex> unarchive_department(department)
{:error, %Ecto.Changeset{}}

"""
def unarchive_department(%Department{} = department) do
department
|> Department.changeset(%{archived: false})
|> Repo.update()
end

@doc """
Returns an `%Ecto.Changeset{}` for tracking department changes.

Expand Down Expand Up @@ -180,7 +218,11 @@ defmodule Atomic.Departments do
** (Ecto.NoResultsError)

"""
def get_collaborator!(id), do: Repo.get!(Collaborator, id)
def get_collaborator!(id, opts \\ []) do
Collaborator
|> apply_filters(opts)
|> Repo.get!(id)
end

@doc """
Gets a single collaborator.
Expand Down Expand Up @@ -251,6 +293,24 @@ defmodule Atomic.Departments do
|> Repo.update()
end

@doc """
Accepts a collaborator.

## Examples

iex> accept_collaborator(collaborator)
{:ok, %Collaborator{}}

iex> accept_collaborator(collaborator)
{:error, %Ecto.Changeset{}}

"""
def accept_collaborator(%Collaborator{} = collaborator) do
collaborator
|> Collaborator.changeset(%{accepted: true, accepted_at: NaiveDateTime.utc_now()})
|> Repo.update()
end

@doc """
Deletes a collaborator.

Expand Down Expand Up @@ -280,6 +340,21 @@ defmodule Atomic.Departments do
Collaborator.changeset(collaborator, attrs)
end

@doc """
Returns a paginated list of collaborators.

## Examples

iex> list_display_collaborators()
[%Collaborator{}, ...]

"""
def list_display_collaborators(%{} = flop, opts \\ []) do
Collaborator
|> apply_filters(opts)
|> Flop.validate_and_run(flop, for: Collaborator)
end

@doc """
Returns the list of collaborators belonging to a department.

Expand All @@ -295,4 +370,22 @@ defmodule Atomic.Departments do
|> where([c], c.department_id == ^id)
|> Repo.all()
end

@doc """
Updates a department banner.

## Examples

iex> update_department_banner(department, %{field: new_value})
{:ok, %Department{}}

iex> update_department_banner(department, %{field: bad_value})
{:error, %Ecto.Changeset{}}

"""
def update_department_banner(%Department{} = department, attrs) do
department
|> Department.banner_changeset(attrs)
|> Repo.update()
end
end
17 changes: 16 additions & 1 deletion lib/atomic/organizations/collaborator.ex
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,28 @@ defmodule Atomic.Organizations.Collaborator do
alias Atomic.Organizations.Department

@required_fields ~w(user_id department_id)a
@optional_fields ~w(accepted)a
@optional_fields ~w(accepted accepted_at)a
joaodiaslobo marked this conversation as resolved.
Show resolved Hide resolved

@derive {
Flop.Schema,
default_limit: 7,
filterable: [:accepted],
sortable: [:collaborator_name, :inserted_at, :updated_at],
default_order: %{
order_by: [:inserted_at],
order_directions: [:desc]
},
join_fields: [
collaborator_name: [binding: :user, field: :name, path: [:user, :name]]
]
}

schema "collaborators" do
belongs_to :user, User
belongs_to :department, Department

field :accepted, :boolean, default: false
field :accepted_at, :naive_datetime

timestamps()
end
Expand Down
10 changes: 9 additions & 1 deletion lib/atomic/organizations/department.ex
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,14 @@ defmodule Atomic.Organizations.Department do
alias Atomic.Organizations.Organization

@required_fields ~w(name organization_id)a
@optional_fields ~w(description)a
@optional_fields ~w(description collaborator_applications archived)a

schema "departments" do
field :name, :string
field :description, :string
field :banner, Atomic.Uploaders.Banner.Type
field :collaborator_applications, :boolean, default: false
field :archived, :boolean, default: false

belongs_to :organization, Organization, on_replace: :delete_if_exists

Expand All @@ -22,4 +25,9 @@ defmodule Atomic.Organizations.Department do
|> cast(attrs, @required_fields ++ @optional_fields)
|> validate_required(@required_fields)
end

def banner_changeset(department, attrs) do
department
|> cast_attachments(attrs, [:banner])
end
end
11 changes: 11 additions & 0 deletions lib/atomic/uploaders/banner.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
defmodule Atomic.Uploaders.Banner do
@moduledoc """
Uploader for department banners.
"""
use Atomic.Uploader
alias Atomic.Organizations.Department
joaodiaslobo marked this conversation as resolved.
Show resolved Hide resolved

def storage_dir(_version, {_file, %Department{} = scope}) do
"uploads/atomic/departments/#{scope.id}/banner"
end
end
1 change: 0 additions & 1 deletion lib/atomic_web.ex
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,6 @@ defmodule AtomicWeb do
# Import LiveView and .heex helpers (live_render, live_patch, <.form>, etc)
import Phoenix.LiveView.Helpers
import Phoenix.Component
import AtomicWeb.LiveHelpers

# Import commonly used components
unquote(components())
Expand Down
10 changes: 9 additions & 1 deletion lib/atomic_web/components/avatar.ex
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ defmodule AtomicWeb.Components.Avatar do

attr :name, :string, required: true, doc: "The name of the entity associated with the avatar."

attr :auto_generate_initials, :boolean,
default: true,
doc: "Whether to automatically generate the initials from the name."

attr :type, :atom,
values: [:user, :organization, :company],
default: :user,
Expand Down Expand Up @@ -42,7 +46,11 @@ defmodule AtomicWeb.Components.Avatar do
<%= if @src do %>
<img src={@src} class={"atomic-avatar--#{assigns.type} h-full w-full"} />
<% else %>
<%= extract_initials(@name) %>
<%= if @auto_generate_initials do %>
<%= extract_initials(@name) %>
<% else %>
<%= @name %>
<% end %>
<% end %>
</span>
"""
Expand Down
4 changes: 2 additions & 2 deletions lib/atomic_web/components/button.ex
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,10 @@ defmodule AtomicWeb.Components.Button do

attr :rest, :global,
include:
~w(csrf_token disabled download form href hreflang method name navigate patch referrerpolicy rel replace target type value),
~w(csrf_token disabled download form href hreflang method name navigate patch referrerpolicy rel replace target type value autofocus tabindex),
doc: "Arbitrary HTML or phx attributes."

slot :inner_block, required: true, doc: "Slot for the body content of the page."
slot :inner_block, required: true, doc: "Slot for the content of the button."

def button(assigns) do
assigns
Expand Down
4 changes: 1 addition & 3 deletions lib/atomic_web/components/forms.ex
Original file line number Diff line number Diff line change
Expand Up @@ -153,9 +153,7 @@ defmodule AtomicWeb.Components.Forms do
<%= @label %>
</.field_label>

<textarea id={@id} name={@name} class={["atomic-text-input", @class]} rows={@rows} required={@required} {@rest}>
<%= Phoenix.HTML.Form.normalize_value("textarea", @value) %>
</textarea>
<textarea id={@id} name={@name} class={["atomic-text-input", @class]} rows={@rows} required={@required} {@rest}><%= Phoenix.HTML.Form.normalize_value("textarea", @value) %></textarea>

<.field_error :for={msg <- @errors}><%= msg %></.field_error>
<.field_help_text help_text={@help_text} />
Expand Down
7 changes: 2 additions & 5 deletions lib/atomic_web/components/image_uploader.ex
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,12 @@ defmodule AtomicWeb.Components.ImageUploader do
def render(assigns) do
~H"""
<div>
<div class="shrink-0 px-4 py-6 1.5xl:shrink-0 1.5xl:px-6 1.5xl:py-5 sm:px-6">
<span class="font-sm mb-1 pl-1 text-base text-gray-800 sm:text-lg">
Image
</span>
<div class="shrink-0 1.5xl:shrink-0">
<.live_file_input upload={@uploads.image} class="hidden" />
<div class={
"#{if length(@uploads.image.entries) != 0 do
"hidden"
end} mt-1 border-2 border-gray-300 border-dashed rounded-md"
end} border-2 border-gray-300 border-dashed rounded-md"
} phx-drop-target={@uploads.image.ref}>
<div class="mx-auto sm:col-span-6 lg:w-full">
<div class="my-[140px] flex justify-center px-6">
Expand Down
3 changes: 1 addition & 2 deletions lib/atomic_web/components/modal.ex
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ defmodule AtomicWeb.Components.Modal do
<div class="w-full max-w-3xl p-4 sm:p-6 lg:py-8">
<.focus_wrap id={"#{@id}-container"} phx-click-away={JS.exec("phx-cancel", to: "##{@id}")} class="shadow-zinc-700/10 ring-zinc-700/10 relative hidden rounded-2xl bg-white p-14 shadow-lg ring-1 transition">
<div class="absolute top-6 right-5">
<button phx-click={JS.exec("phx-cancel", to: "##{@id}")} type="button" class="-m-3 flex-none p-3 opacity-20 hover:opacity-40" aria-label={gettext("close")}>
<button phx-click={JS.exec("phx-cancel", to: "##{@id}")} type="button" class="-m-3 flex-none p-3 opacity-20 outline-none hover:opacity-40" aria-label={gettext("close")}>
<.icon name={:x_mark} solid class="h-5 w-5" />
</button>
</div>
Expand All @@ -65,7 +65,6 @@ defmodule AtomicWeb.Components.Modal do
)
|> show("##{id}-container")
|> JS.add_class("overflow-hidden", to: "body")
|> JS.focus_first(to: "##{id}-content")
end

def hide_modal(js \\ %JS{}, id) do
Expand Down
4 changes: 2 additions & 2 deletions lib/atomic_web/components/table.ex
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ defmodule AtomicWeb.Components.Table do
<%= for item <- @items do %>
<tr class="leading-3" style="height: 30px;">
<%= for col <- @col do %>
<td class="border-b-[1px] border-r-[1px] whitespace-nowrap px-3 py-4 text-sm text-zinc-500 sm:pl-6">
<td class="border-b-[1px] border-r-[1px] whitespace-nowrap p-4 text-sm text-zinc-500">
<%= render_slot(col, item) %>
</td>
<% end %>
Expand All @@ -48,7 +48,7 @@ defmodule AtomicWeb.Components.Table do
assign(assigns, :direction, order_direction(assigns.meta.flop.order_directions, index))

~H"""
<th class="border-r-[1px] py-3.5 pr-3 pl-4 text-left text-sm font-semibold text-zinc-900 sm:pl-6" scope="col">
<th class="border-r-[1px] px-4 py-3.5 text-left text-sm font-semibold text-zinc-900" scope="col">
<%= if is_sortable?(@field, @meta.schema) && is_filterable?(@field, @meta.schema) && should_filter(@field, @filter) do %>
<div class="flex justify-between">
<.link patch={build_sorting_query(@field, @meta)} class="mr-2 w-full">
Expand Down
Loading
Loading