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

Moderator notifications #290

Merged
merged 63 commits into from
Jan 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
eaf77dc
Add mostly-working login
skanderm Nov 18, 2023
ced2ce0
Add sign-in form component, helper functions for storing auth token a…
skanderm Nov 20, 2023
342af66
Merge branch 'main' into skander/login-form
skanderm Nov 20, 2023
6ae1f6b
Update fetcher to use dynamic headers
skanderm Nov 20, 2023
758434f
Add register form with /register page
skanderm Nov 21, 2023
59165c0
Add password reset request form and route
skanderm Nov 21, 2023
c281c07
Update password reset form button text
skanderm Nov 21, 2023
e4f226c
Rename SigninForm.tsx to SignInForm.tsx
skanderm Nov 21, 2023
f434de7
Add reset password form, mutation
skanderm Nov 22, 2023
fdcae70
Merge branch 'main' into skander/login-form
skanderm Nov 22, 2023
f4274a7
Move rest of backend auth routes to /admin prefix
skanderm Nov 22, 2023
1e9d9d2
Move backend password reset up in router
skanderm Nov 22, 2023
032c579
Add sign out page
skanderm Nov 24, 2023
2fbf650
Move register and sign-in pages to top level
paulcretu Nov 26, 2023
74a020f
Move auth page layout into separate component
paulcretu Nov 26, 2023
e721149
Move reports pages layout into separate component
paulcretu Nov 26, 2023
4069e05
Refactor types for client
paulcretu Nov 26, 2023
8ad2133
Rename auth folder to lowercase
paulcretu Nov 26, 2023
f454c0e
Refactor SignInForm
paulcretu Nov 27, 2023
8bfcf5d
Use theme.palette.augmentColor for accent colors
skanderm Nov 28, 2023
c7fe828
Use Container for auth forms
skanderm Nov 28, 2023
cb6a47a
Remove unnecessary color='primary'
skanderm Nov 28, 2023
fe71063
Merge props into sx in AuthLayout
skanderm Nov 28, 2023
a1db985
Update React imports, replace interfaces with types
skanderm Nov 28, 2023
fd0ed80
Remvoe a few more interfaces
skanderm Nov 28, 2023
4635b34
Remove FC type return
skanderm Nov 28, 2023
990ade1
Use mutation variable types for auth form annotations
skanderm Nov 28, 2023
fb0af04
Use our Link components
skanderm Nov 28, 2023
5fb6451
Remove token, use session auth
skanderm Dec 6, 2023
48b682b
Authorization policies (#283)
skanderm Dec 6, 2023
7f040ba
Fix wrong form arg shape
skanderm Dec 6, 2023
82b709c
Underscore unused variables
skanderm Dec 6, 2023
326e878
Revert router fallback
skanderm Dec 6, 2023
dc74064
Update authorization for auth actions
skanderm Dec 6, 2023
81ec285
Merge branch 'skander/login-form' into skander/sign-out-page
skanderm Dec 6, 2023
9b45f36
Clear session on signOut graphql request
skanderm Dec 6, 2023
8b848b8
Update dependencies
skanderm Dec 8, 2023
c09acd2
Add moderator flag to users
skanderm Dec 8, 2023
805693e
Add visible flags to candidates, detections. Add policies and mutatio…
skanderm Dec 12, 2023
ce79988
Merge branch 'skander/sign-out-page' into skander/moderator-flag
skanderm Dec 12, 2023
a9c005d
Add visible columns to detections, candidates
skanderm Dec 12, 2023
6223ec6
Add actions for moderator hiding/showing detections and candidate
skanderm Dec 12, 2023
423e55a
Show visible/hidden chip for moderators on candidate row, modal, and …
skanderm Dec 12, 2023
e6cd7bc
Remove setCandidateVisible mutation
skanderm Dec 13, 2023
d71c949
Revert router settings
skanderm Dec 13, 2023
8263352
Add graphql to Notifications API, show notifying and canceling notifi…
skanderm Dec 14, 2023
4585ec6
Add cancel_candidate_notifications mutation for candidate
skanderm Dec 14, 2023
144d6ca
Refactor to use auth layout
paulcretu Dec 15, 2023
1e94e39
Fix useEffect deps array
paulcretu Dec 15, 2023
967bbb1
Add indexes to meta columns in notifications, subscribers, subscripti…
skanderm Dec 18, 2023
1443392
Invalidate candidate query on detection update
skanderm Dec 18, 2023
096ab14
Merge branch 'main' into skander/sign-out-page
skanderm Dec 18, 2023
6d95c6c
Re-add missing sign out mutation
skanderm Dec 18, 2023
d45ff2c
Merge branch 'skander/sign-out-page' into skander/moderator-flag
skanderm Dec 18, 2023
626b29a
Merge branch 'skander/moderator-flag' into skander/moderator-notifica…
skanderm Dec 18, 2023
686d18f
Add confirmation, cancel, and notification submission
skanderm Dec 18, 2023
fb73ce1
Merge branch 'main' into skander/moderator-flag
skanderm Dec 19, 2023
2af3416
Merge branch 'main' into skander/moderator-flag
skanderm Dec 20, 2023
9d3f9f7
Merge branch 'skander/moderator-flag' into skander/moderator-notifica…
skanderm Dec 20, 2023
d4748e5
Merge branch 'main' into skander/moderator-notifications
skanderm Jan 1, 2024
fa336a6
Change invalidateQuery to refetch when creating new notification
skanderm Jan 3, 2024
b4161cb
Merge branch 'main' into skander/moderator-notifications
skanderm Jan 3, 2024
49665f8
Merge branch 'main' into skander/moderator-notifications
skanderm Jan 3, 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
1 change: 1 addition & 0 deletions server/config/config.exs
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ config :spark, :formatter,
:authentication,
:token,
:policies,
:field_policies,
:actions,
:admin,
:json_api,
Expand Down
5 changes: 4 additions & 1 deletion server/lib/orcasite/notifications.ex
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
defmodule Orcasite.Notifications do
use Ash.Api, extensions: [AshAdmin.Api, AshJsonApi.Api]
use Ash.Api, extensions: [AshAdmin.Api, AshJsonApi.Api, AshGraphql.Api]

resources do
registry Orcasite.Notifications.Registry
Expand All @@ -12,4 +12,7 @@ defmodule Orcasite.Notifications do
json_api do
log_errors? true
end

graphql do
end
end
124 changes: 93 additions & 31 deletions server/lib/orcasite/notifications/resources/notification.ex
Original file line number Diff line number Diff line change
@@ -1,26 +1,31 @@
defmodule Orcasite.Notifications.Notification do
use Ash.Resource,
extensions: [AshAdmin.Resource],
data_layer: AshPostgres.DataLayer
extensions: [AshAdmin.Resource, AshGraphql.Resource],
data_layer: AshPostgres.DataLayer,
authorizers: [Ash.Policy.Authorizer]

alias Orcasite.Notifications.{Event, NotificationInstance, Subscription}

postgres do
table "notifications"
repo Orcasite.Repo

custom_indexes do
index [:meta], using: "gin"
end
end

attributes do
uuid_primary_key :id

attribute :meta, :map
attribute :meta, :map, default: %{}
attribute :active, :boolean, default: true

attribute :event_type, :atom do
constraints one_of: Event.types()
end

create_timestamp :inserted_at
create_timestamp :inserted_at, private?: false, writable?: false
update_timestamp :updated_at
end

Expand All @@ -34,24 +39,16 @@ defmodule Orcasite.Notifications.Notification do
end
end

code_interface do
define_for Orcasite.Notifications

define :notify_new_detection,
action: :notify_new_detection,
args: [:detection_id, :node, :description, :listener_count, :candidate_id]

define :notify_confirmed_candidate,
action: :notify_confirmed_candidate,
args: [:candidate_id, :node]
end
policies do
bypass actor_attribute_equals(:admin, true) do
authorize_if always()
end

resource do
description """
Notification for a specific event type. Once created, all Subscriptions that match this Notification's
event type (new detection, confirmed candidate, etc.) will be notified using the Subscription's particular
channel settings (email, browser notification, webhooks).
"""
bypass actor_attribute_equals(:moderator, true) do
authorize_if action(:notify_confirmed_candidate)
authorize_if action(:cancel_notification)
authorize_if action(:for_candidate)
end
end

actions do
Expand All @@ -64,7 +61,31 @@ defmodule Orcasite.Notifications.Notification do
manual Orcasite.Notifications.ManualReadNotificationsSince
end

read :for_candidate do
prepare build(sort: [inserted_at: :desc])
argument :candidate_id, :string, allow_nil?: false

argument :event_type, :atom do
constraints one_of: Event.types()
end

argument :active, :boolean

filter expr(
fragment("(? @> ?)", meta, expr(%{candidate_id: ^arg(:candidate_id)})) and
if(not is_nil(^arg(:event_type)),
do: event_type == ^arg(:event_type),
else: true
) and
if(not is_nil(^arg(:active)),
do: active == ^arg(:active),
else: true
)
)
end

update :cancel_notification do
accept []
change set_attribute(:active, false)

change fn changeset, _context ->
Expand All @@ -84,9 +105,8 @@ defmodule Orcasite.Notifications.Notification do

create :notify_confirmed_candidate do
description "Create a notification for confirmed candidate (i.e. detection group)"
accept [:candidate_id]
argument :candidate_id, :string
argument :node, :string, allow_nil?: false
accept [:candidate_id, :message]
argument :candidate_id, :string, allow_nil?: false

argument :message, :string do
description """
Expand All @@ -100,10 +120,19 @@ defmodule Orcasite.Notifications.Notification do
change set_attribute(:event_type, :confirmed_candidate)

change fn changeset, _context ->
candidate_id =
Ash.Changeset.get_argument(changeset, :candidate_id)
|> IO.inspect(label: "candidate id")

candidate =
Orcasite.Radio.Candidate
|> Orcasite.Radio.get(candidate_id)
|> Orcasite.Radio.load!(:feed)

changeset
|> Ash.Changeset.change_attribute(:meta, %{
candidate_id: Ash.Changeset.get_argument(changeset, :candidate_id),
node: Ash.Changeset.get_argument(changeset, :node),
candidate_id: candidate_id,
node: candidate.feed.slug,
message: Ash.Changeset.get_argument(changeset, :message)
})
end
Expand Down Expand Up @@ -134,6 +163,36 @@ defmodule Orcasite.Notifications.Notification do
end
end

code_interface do
define_for Orcasite.Notifications

define :notify_new_detection,
action: :notify_new_detection,
args: [:detection_id, :node, :description, :listener_count, :candidate_id]

define :notify_confirmed_candidate,
action: :notify_confirmed_candidate,
args: [:candidate_id]
end

resource do
description """
Notification for a specific event type. Once created, all Subscriptions that match this Notification's
event type (new detection, confirmed candidate, etc.) will be notified using the Subscription's particular
channel settings (email, browser notification, webhooks).
"""
end

admin do
table_columns [:id, :meta, :event_type, :inserted_at]

format_fields meta: {Jason, :encode!, []}

form do
field :event_type, type: :default
end
end

changes do
change fn changeset, _context ->
changeset
Expand Down Expand Up @@ -162,13 +221,16 @@ defmodule Orcasite.Notifications.Notification do
on: :create
end

admin do
table_columns [:id, :meta, :event_type, :inserted_at]
graphql do
type :notification

format_fields meta: {Jason, :encode!, []}
queries do
list :notifications_for_candidate, :for_candidate
end

form do
field :event_type, type: :default
mutations do
create :notify_confirmed_candidate, :notify_confirmed_candidate
update :cancel_notification, :cancel_notification
end
end
end
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ defmodule Orcasite.Notifications.NotificationInstance do
attributes do
uuid_primary_key :id

attribute :meta, :map
attribute :meta, :map, default: %{}

attribute :channel, :atom do
constraints one_of: [:email]
Expand Down
18 changes: 11 additions & 7 deletions server/lib/orcasite/notifications/resources/subscriber.ex
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ defmodule Orcasite.Notifications.Subscriber do
postgres do
table "subscribers"
repo Orcasite.Repo

custom_indexes do
index [:meta], using: "gin"
end
end

identities do
Expand All @@ -24,7 +28,7 @@ defmodule Orcasite.Notifications.Subscriber do
constraints one_of: [:individual, :organization]
end

attribute :meta, :map
attribute :meta, :map, default: %{}

create_timestamp :inserted_at
update_timestamp :updated_at
Expand All @@ -39,12 +43,6 @@ defmodule Orcasite.Notifications.Subscriber do
define :by_email, args: [:email]
end

resource do
description """
A subscriber object. Can relate to an individual, an organization, a newsletter, or an admin.
"""
end

authentication do
api Orcasite.Notifications

Expand Down Expand Up @@ -78,6 +76,12 @@ defmodule Orcasite.Notifications.Subscriber do
end
end

resource do
description """
A subscriber object. Can relate to an individual, an organization, a newsletter, or an admin.
"""
end

actions do
defaults [:create, :read, :update, :destroy]

Expand Down
66 changes: 35 additions & 31 deletions server/lib/orcasite/notifications/resources/subscription.ex
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,48 @@ defmodule Orcasite.Notifications.Subscription do
postgres do
table "subscriptions"
repo Orcasite.Repo

custom_indexes do
index [:meta], using: "gin"
end
end

identities do
# Needed by magic_token. Primary key doesn't show up as an identity otherwise
identity :id, [:id]
end

attributes do
uuid_primary_key :id

attribute :name, :string
attribute :meta, :map, default: %{}

attribute :active, :boolean, default: true

attribute :event_type, :atom do
constraints one_of: Event.types()
end

attribute :last_notified_at, :utc_datetime_usec

create_timestamp :inserted_at
update_timestamp :updated_at
end

relationships do
belongs_to :subscriber, Subscriber
has_many :notification_instances, NotificationInstance

many_to_many :notifications, Notification do
through NotificationInstance
source_attribute_on_join_resource :subscription_id
destination_attribute_on_join_resource :notification_id
end

belongs_to :last_notification, Notification
end

authentication do
api Orcasite.Notifications

Expand Down Expand Up @@ -48,37 +83,6 @@ defmodule Orcasite.Notifications.Subscription do
end
end

attributes do
uuid_primary_key :id

attribute :name, :string
attribute :meta, :map

attribute :active, :boolean, default: true

attribute :event_type, :atom do
constraints one_of: Event.types()
end

attribute :last_notified_at, :utc_datetime_usec

create_timestamp :inserted_at
update_timestamp :updated_at
end

relationships do
belongs_to :subscriber, Subscriber
has_many :notification_instances, NotificationInstance

many_to_many :notifications, Notification do
through NotificationInstance
source_attribute_on_join_resource :subscription_id
destination_attribute_on_join_resource :notification_id
end

belongs_to :last_notification, Notification
end

code_interface do
define_for Orcasite.Notifications

Expand Down
Loading
Loading