Remove closure reasons
This commit is contained in:
@@ -2,7 +2,7 @@ class Cards::ClosuresController < ApplicationController
|
|||||||
include CardScoped
|
include CardScoped
|
||||||
|
|
||||||
def create
|
def create
|
||||||
@card.close(user: Current.user, reason: params[:reason])
|
@card.close(user: Current.user)
|
||||||
render_card_replacement
|
render_card_replacement
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ module EventsHelper
|
|||||||
when "card_published"
|
when "card_published"
|
||||||
"#{h event_creator_name(event) } added <span style='color: var(--card-color)'>#{h title }</span>".html_safe
|
"#{h event_creator_name(event) } added <span style='color: var(--card-color)'>#{h title }</span>".html_safe
|
||||||
when "card_closed"
|
when "card_closed"
|
||||||
"#{h event_creator_name(event) } closed <span style='color: var(--card-color)'>#{h title }</span>".html_safe
|
"#{h event_creator_name(event) } marked <span style='color: var(--card-color)'>#{h title }</span> as done".html_safe
|
||||||
when "card_reopened"
|
when "card_reopened"
|
||||||
"#{h event_creator_name(event) } reopened <span style='color: var(--card-color)'>#{h title }</span>".html_safe
|
"#{h event_creator_name(event) } reopened <span style='color: var(--card-color)'>#{h title }</span>".html_safe
|
||||||
when "card_due_date_added"
|
when "card_due_date_added"
|
||||||
|
|||||||
@@ -10,12 +10,7 @@ module NotificationsHelper
|
|||||||
name = event.creator.name
|
name = event.creator.name
|
||||||
|
|
||||||
case event_notification_action(event)
|
case event_notification_action(event)
|
||||||
when "card_closed"
|
when "card_closed" then "Marked as “Done” by #{name}"
|
||||||
if event.card.closure
|
|
||||||
"Closed as “#{event.card.closure.reason}” by #{name}"
|
|
||||||
else
|
|
||||||
"Closed by #{name}"
|
|
||||||
end
|
|
||||||
when "card_reopened" then "Reopened by #{name}"
|
when "card_reopened" then "Reopened by #{name}"
|
||||||
when "card_published" then "Added by #{name}"
|
when "card_published" then "Added by #{name}"
|
||||||
when "comment_created" then comment_notification_body(event)
|
when "comment_created" then comment_notification_body(event)
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
module WebhooksHelper
|
module WebhooksHelper
|
||||||
ACTION_LABELS = {
|
ACTION_LABELS = {
|
||||||
card_assigned: "Card assigned",
|
card_assigned: "Card assigned",
|
||||||
card_closed: "Card closed",
|
card_closed: "Card marked as Done",
|
||||||
card_collection_changed: "Card collection changed",
|
card_collection_changed: "Card collection changed",
|
||||||
card_due_date_added: "Card due date added",
|
card_due_date_added: "Card due date added",
|
||||||
card_due_date_changed: "Card due date changed",
|
card_due_date_changed: "Card due date changed",
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ class Account < ApplicationRecord
|
|||||||
def setup_basic_template
|
def setup_basic_template
|
||||||
user = User.first
|
user = User.first
|
||||||
|
|
||||||
Closure::Reason.create_defaults
|
|
||||||
Collection.create!(name: "Cards", creator: user, all_access: true)
|
Collection.create!(name: "Cards", creator: user, all_access: true)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -28,10 +28,10 @@ module Card::Closeable
|
|||||||
closure&.created_at
|
closure&.created_at
|
||||||
end
|
end
|
||||||
|
|
||||||
def close(user: Current.user, reason: Closure::Reason.default)
|
def close(user: Current.user)
|
||||||
unless closed?
|
unless closed?
|
||||||
transaction do
|
transaction do
|
||||||
create_closure! user: user, reason: reason
|
create_closure! user: user
|
||||||
track_event :closed, creator: user
|
track_event :closed, creator: user
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ class Card::Eventable::SystemCommenter
|
|||||||
when "card_unassigned"
|
when "card_unassigned"
|
||||||
"#{event.creator.name} <strong>unassigned</strong> from #{event.assignees.pluck(:name).to_sentence}."
|
"#{event.creator.name} <strong>unassigned</strong> from #{event.assignees.pluck(:name).to_sentence}."
|
||||||
when "card_closed"
|
when "card_closed"
|
||||||
"<strong>Closed</strong> as ‘#{ card.closure.reason }’ by #{ event.creator.name }"
|
"<strong>Marked</strong> as “Done” by #{ event.creator.name }"
|
||||||
when "card_reopened"
|
when "card_reopened"
|
||||||
"<strong>Reopened</strong> by #{ event.creator.name }"
|
"<strong>Reopened</strong> by #{ event.creator.name }"
|
||||||
when "card_title_changed"
|
when "card_title_changed"
|
||||||
|
|||||||
@@ -1,27 +0,0 @@
|
|||||||
class Closure::Reason < ApplicationRecord
|
|
||||||
DEFAULT_LABELS = [
|
|
||||||
"Completed",
|
|
||||||
"Duplicate",
|
|
||||||
"Maybe later",
|
|
||||||
"Working as intended",
|
|
||||||
"Not now"
|
|
||||||
]
|
|
||||||
|
|
||||||
FALLBACK_LABEL = "Done"
|
|
||||||
|
|
||||||
class << self
|
|
||||||
def labels
|
|
||||||
pluck(:label).presence || [ FALLBACK_LABEL ]
|
|
||||||
end
|
|
||||||
|
|
||||||
def default
|
|
||||||
labels.first
|
|
||||||
end
|
|
||||||
|
|
||||||
def create_defaults
|
|
||||||
DEFAULT_LABELS.each do |label|
|
|
||||||
create! label: label
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@@ -59,7 +59,7 @@ class NotificationPusher
|
|||||||
)
|
)
|
||||||
when "card_closed"
|
when "card_closed"
|
||||||
base_payload.merge(
|
base_payload.merge(
|
||||||
body: card.closure ? "Closed as \"#{card.closure.reason}\" by #{event.creator.name}" : "Closed by #{event.creator.name}"
|
body: card.closure ? "Marked as “Done” by #{event.creator.name}" : "Closed by #{event.creator.name}"
|
||||||
)
|
)
|
||||||
when "card_reopened"
|
when "card_reopened"
|
||||||
base_payload.merge(
|
base_payload.merge(
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
<% end %>
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
<% else %>
|
<% else %>
|
||||||
<%= button_to card_closure_path(card, reason: "Done"), class: "btn borderless" do %>
|
<%= button_to card_closure_path(card), class: "btn borderless" do %>
|
||||||
<span class="overflow-ellipsis">Mark as Done</span>
|
<span class="overflow-ellipsis">Mark as Done</span>
|
||||||
<% end %>
|
<% end %>
|
||||||
<% if card.entropic? && card.open? %>
|
<% if card.entropic? && card.open? %>
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
<%= button_to_set_column card, column %>
|
<%= button_to_set_column card, column %>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<%= button_to "Done", card_closure_path(card, reason: "Completed"),
|
<%= button_to "Done", card_closure_path(card),
|
||||||
class: [ "card__column-name btn", { "card__column-name--current": card.closed? } ],
|
class: [ "card__column-name btn", { "card__column-name--current": card.closed? } ],
|
||||||
role: "radio",
|
role: "radio",
|
||||||
aria: { checked: card.closed? },
|
aria: { checked: card.closed? },
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
class RemoveClosureReasons < ActiveRecord::Migration[8.1]
|
||||||
|
def change
|
||||||
|
drop_table :closure_reasons
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
class RemoveReasonFromClosures < ActiveRecord::Migration[8.1]
|
||||||
|
def change
|
||||||
|
remove_column :closures, :reason
|
||||||
|
end
|
||||||
|
end
|
||||||
Generated
+12
-8
@@ -10,7 +10,7 @@
|
|||||||
#
|
#
|
||||||
# It's strongly recommended that you check this file into your version control system.
|
# It's strongly recommended that you check this file into your version control system.
|
||||||
|
|
||||||
ActiveRecord::Schema[8.1].define(version: 2025_10_15_123003) do
|
ActiveRecord::Schema[8.1].define(version: 2025_10_15_205212) do
|
||||||
create_table "accesses", force: :cascade do |t|
|
create_table "accesses", force: :cascade do |t|
|
||||||
t.datetime "accessed_at"
|
t.datetime "accessed_at"
|
||||||
t.integer "collection_id", null: false
|
t.integer "collection_id", null: false
|
||||||
@@ -29,6 +29,7 @@ ActiveRecord::Schema[8.1].define(version: 2025_10_15_123003) do
|
|||||||
t.integer "external_account_id"
|
t.integer "external_account_id"
|
||||||
t.string "join_code"
|
t.string "join_code"
|
||||||
t.string "name", null: false
|
t.string "name", null: false
|
||||||
|
t.string "setup_status"
|
||||||
t.datetime "updated_at", null: false
|
t.datetime "updated_at", null: false
|
||||||
t.index ["external_account_id"], name: "index_accounts_on_external_account_id", unique: true
|
t.index ["external_account_id"], name: "index_accounts_on_external_account_id", unique: true
|
||||||
end
|
end
|
||||||
@@ -162,16 +163,9 @@ ActiveRecord::Schema[8.1].define(version: 2025_10_15_123003) do
|
|||||||
t.index ["filter_id"], name: "index_closers_filters_on_filter_id"
|
t.index ["filter_id"], name: "index_closers_filters_on_filter_id"
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "closure_reasons", force: :cascade do |t|
|
|
||||||
t.datetime "created_at", null: false
|
|
||||||
t.string "label"
|
|
||||||
t.datetime "updated_at", null: false
|
|
||||||
end
|
|
||||||
|
|
||||||
create_table "closures", force: :cascade do |t|
|
create_table "closures", force: :cascade do |t|
|
||||||
t.integer "card_id", null: false
|
t.integer "card_id", null: false
|
||||||
t.datetime "created_at", null: false
|
t.datetime "created_at", null: false
|
||||||
t.string "reason", null: false
|
|
||||||
t.datetime "updated_at", null: false
|
t.datetime "updated_at", null: false
|
||||||
t.integer "user_id"
|
t.integer "user_id"
|
||||||
t.index ["card_id", "created_at"], name: "index_closures_on_card_id_and_created_at"
|
t.index ["card_id", "created_at"], name: "index_closures_on_card_id_and_created_at"
|
||||||
@@ -293,6 +287,15 @@ ActiveRecord::Schema[8.1].define(version: 2025_10_15_123003) do
|
|||||||
t.index ["tag_id"], name: "index_filters_tags_on_tag_id"
|
t.index ["tag_id"], name: "index_filters_tags_on_tag_id"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
create_table "integrations", force: :cascade do |t|
|
||||||
|
t.datetime "created_at", null: false
|
||||||
|
t.text "data"
|
||||||
|
t.integer "owner_id", null: false
|
||||||
|
t.string "type"
|
||||||
|
t.datetime "updated_at", null: false
|
||||||
|
t.index ["owner_id"], name: "index_integrations_on_owner_id"
|
||||||
|
end
|
||||||
|
|
||||||
create_table "mentions", force: :cascade do |t|
|
create_table "mentions", force: :cascade do |t|
|
||||||
t.datetime "created_at", null: false
|
t.datetime "created_at", null: false
|
||||||
t.integer "mentionee_id", null: false
|
t.integer "mentionee_id", null: false
|
||||||
@@ -522,6 +525,7 @@ ActiveRecord::Schema[8.1].define(version: 2025_10_15_123003) do
|
|||||||
add_foreign_key "conversation_messages", "conversations"
|
add_foreign_key "conversation_messages", "conversations"
|
||||||
add_foreign_key "conversations", "users"
|
add_foreign_key "conversations", "users"
|
||||||
add_foreign_key "events", "collections"
|
add_foreign_key "events", "collections"
|
||||||
|
add_foreign_key "integrations", "users", column: "owner_id"
|
||||||
add_foreign_key "mentions", "users", column: "mentionee_id"
|
add_foreign_key "mentions", "users", column: "mentionee_id"
|
||||||
add_foreign_key "mentions", "users", column: "mentioner_id"
|
add_foreign_key "mentions", "users", column: "mentioner_id"
|
||||||
add_foreign_key "notification_bundles", "users"
|
add_foreign_key "notification_bundles", "users"
|
||||||
|
|||||||
+64
-28
@@ -133,6 +133,16 @@ columns:
|
|||||||
default_function:
|
default_function:
|
||||||
collation:
|
collation:
|
||||||
comment:
|
comment:
|
||||||
|
- !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column
|
||||||
|
auto_increment:
|
||||||
|
name: setup_status
|
||||||
|
cast_type: *7
|
||||||
|
sql_type_metadata: *8
|
||||||
|
'null': true
|
||||||
|
default:
|
||||||
|
default_function:
|
||||||
|
collation:
|
||||||
|
comment:
|
||||||
- *9
|
- *9
|
||||||
action_text_rich_texts:
|
action_text_rich_texts:
|
||||||
- !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column
|
- !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column
|
||||||
@@ -534,34 +544,10 @@ columns:
|
|||||||
collation:
|
collation:
|
||||||
comment:
|
comment:
|
||||||
- *20
|
- *20
|
||||||
closure_reasons:
|
|
||||||
- *5
|
|
||||||
- *6
|
|
||||||
- !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column
|
|
||||||
auto_increment:
|
|
||||||
name: label
|
|
||||||
cast_type: *7
|
|
||||||
sql_type_metadata: *8
|
|
||||||
'null': true
|
|
||||||
default:
|
|
||||||
default_function:
|
|
||||||
collation:
|
|
||||||
comment:
|
|
||||||
- *9
|
|
||||||
closures:
|
closures:
|
||||||
- *23
|
- *23
|
||||||
- *5
|
- *5
|
||||||
- *6
|
- *6
|
||||||
- !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column
|
|
||||||
auto_increment:
|
|
||||||
name: reason
|
|
||||||
cast_type: *7
|
|
||||||
sql_type_metadata: *8
|
|
||||||
'null': false
|
|
||||||
default:
|
|
||||||
default_function:
|
|
||||||
collation:
|
|
||||||
comment:
|
|
||||||
- *9
|
- *9
|
||||||
- *25
|
- *25
|
||||||
collection_publications:
|
collection_publications:
|
||||||
@@ -875,6 +861,40 @@ columns:
|
|||||||
default_function:
|
default_function:
|
||||||
collation:
|
collation:
|
||||||
comment:
|
comment:
|
||||||
|
integrations:
|
||||||
|
- *5
|
||||||
|
- !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column
|
||||||
|
auto_increment:
|
||||||
|
name: data
|
||||||
|
cast_type: *15
|
||||||
|
sql_type_metadata: *16
|
||||||
|
'null': true
|
||||||
|
default:
|
||||||
|
default_function:
|
||||||
|
collation:
|
||||||
|
comment:
|
||||||
|
- *6
|
||||||
|
- !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column
|
||||||
|
auto_increment:
|
||||||
|
name: owner_id
|
||||||
|
cast_type: *3
|
||||||
|
sql_type_metadata: *4
|
||||||
|
'null': false
|
||||||
|
default:
|
||||||
|
default_function:
|
||||||
|
collation:
|
||||||
|
comment:
|
||||||
|
- !ruby/object:ActiveRecord::ConnectionAdapters::SQLite3::Column
|
||||||
|
auto_increment:
|
||||||
|
name: type
|
||||||
|
cast_type: *7
|
||||||
|
sql_type_metadata: *8
|
||||||
|
'null': true
|
||||||
|
default:
|
||||||
|
default_function:
|
||||||
|
collation:
|
||||||
|
comment:
|
||||||
|
- *9
|
||||||
mentions:
|
mentions:
|
||||||
- *5
|
- *5
|
||||||
- *6
|
- *6
|
||||||
@@ -1466,7 +1486,6 @@ primary_keys:
|
|||||||
card_not_nows: id
|
card_not_nows: id
|
||||||
cards: id
|
cards: id
|
||||||
closers_filters:
|
closers_filters:
|
||||||
closure_reasons: id
|
|
||||||
closures: id
|
closures: id
|
||||||
collection_publications: id
|
collection_publications: id
|
||||||
collections: id
|
collections: id
|
||||||
@@ -1480,6 +1499,7 @@ primary_keys:
|
|||||||
events: id
|
events: id
|
||||||
filters: id
|
filters: id
|
||||||
filters_tags:
|
filters_tags:
|
||||||
|
integrations: id
|
||||||
mentions: id
|
mentions: id
|
||||||
notification_bundles: id
|
notification_bundles: id
|
||||||
notifications: id
|
notifications: id
|
||||||
@@ -1520,7 +1540,6 @@ data_sources:
|
|||||||
card_not_nows: true
|
card_not_nows: true
|
||||||
cards: true
|
cards: true
|
||||||
closers_filters: true
|
closers_filters: true
|
||||||
closure_reasons: true
|
|
||||||
closures: true
|
closures: true
|
||||||
collection_publications: true
|
collection_publications: true
|
||||||
collections: true
|
collections: true
|
||||||
@@ -1534,6 +1553,7 @@ data_sources:
|
|||||||
events: true
|
events: true
|
||||||
filters: true
|
filters: true
|
||||||
filters_tags: true
|
filters_tags: true
|
||||||
|
integrations: true
|
||||||
mentions: true
|
mentions: true
|
||||||
notification_bundles: true
|
notification_bundles: true
|
||||||
notifications: true
|
notifications: true
|
||||||
@@ -2063,7 +2083,6 @@ indexes:
|
|||||||
nulls_not_distinct:
|
nulls_not_distinct:
|
||||||
comment:
|
comment:
|
||||||
valid: true
|
valid: true
|
||||||
closure_reasons: []
|
|
||||||
closures:
|
closures:
|
||||||
- !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition
|
- !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition
|
||||||
table: closures
|
table: closures
|
||||||
@@ -2451,6 +2470,23 @@ indexes:
|
|||||||
nulls_not_distinct:
|
nulls_not_distinct:
|
||||||
comment:
|
comment:
|
||||||
valid: true
|
valid: true
|
||||||
|
integrations:
|
||||||
|
- !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition
|
||||||
|
table: integrations
|
||||||
|
name: index_integrations_on_owner_id
|
||||||
|
unique: false
|
||||||
|
columns:
|
||||||
|
- owner_id
|
||||||
|
lengths: {}
|
||||||
|
orders: {}
|
||||||
|
opclasses: {}
|
||||||
|
where:
|
||||||
|
type:
|
||||||
|
using:
|
||||||
|
include:
|
||||||
|
nulls_not_distinct:
|
||||||
|
comment:
|
||||||
|
valid: true
|
||||||
mentions:
|
mentions:
|
||||||
- !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition
|
- !ruby/object:ActiveRecord::ConnectionAdapters::IndexDefinition
|
||||||
table: mentions
|
table: mentions
|
||||||
@@ -3197,4 +3233,4 @@ indexes:
|
|||||||
nulls_not_distinct:
|
nulls_not_distinct:
|
||||||
comment:
|
comment:
|
||||||
valid: true
|
valid: true
|
||||||
version: 20251015123003
|
version: 20251015205212
|
||||||
|
|||||||
+13
-1
@@ -10,12 +10,23 @@
|
|||||||
#
|
#
|
||||||
# It's strongly recommended that you check this file into your version control system.
|
# It's strongly recommended that you check this file into your version control system.
|
||||||
|
|
||||||
ActiveRecord::Schema[8.1].define(version: 2025_09_24_190729) do
|
ActiveRecord::Schema[8.1].define(version: 2025_10_07_112917) do
|
||||||
create_table "identities", force: :cascade do |t|
|
create_table "identities", force: :cascade do |t|
|
||||||
t.datetime "created_at", null: false
|
t.datetime "created_at", null: false
|
||||||
t.datetime "updated_at", null: false
|
t.datetime "updated_at", null: false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
create_table "magic_links", force: :cascade do |t|
|
||||||
|
t.string "code"
|
||||||
|
t.datetime "created_at", null: false
|
||||||
|
t.datetime "expires_at"
|
||||||
|
t.integer "membership_id", null: false
|
||||||
|
t.datetime "updated_at", null: false
|
||||||
|
t.index ["code"], name: "index_magic_links_on_code", unique: true
|
||||||
|
t.index ["expires_at"], name: "index_magic_links_on_expires_at"
|
||||||
|
t.index ["membership_id"], name: "index_magic_links_on_membership_id"
|
||||||
|
end
|
||||||
|
|
||||||
create_table "memberships", force: :cascade do |t|
|
create_table "memberships", force: :cascade do |t|
|
||||||
t.string "account_name", null: false
|
t.string "account_name", null: false
|
||||||
t.datetime "created_at", null: false
|
t.datetime "created_at", null: false
|
||||||
@@ -29,5 +40,6 @@ ActiveRecord::Schema[8.1].define(version: 2025_09_24_190729) do
|
|||||||
t.index ["user_tenant", "user_id"], name: "index_memberships_on_user_tenant_and_user_id"
|
t.index ["user_tenant", "user_id"], name: "index_memberships_on_user_tenant_and_user_id"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
add_foreign_key "magic_links", "memberships"
|
||||||
add_foreign_key "memberships", "identities"
|
add_foreign_key "memberships", "identities"
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -9,11 +9,9 @@ class Cards::ClosuresControllerTest < ActionDispatch::IntegrationTest
|
|||||||
card = cards(:logo)
|
card = cards(:logo)
|
||||||
|
|
||||||
assert_changes -> { card.reload.closed? }, from: false, to: true do
|
assert_changes -> { card.reload.closed? }, from: false, to: true do
|
||||||
post card_closure_path(card, reason: "Scope too big")
|
post card_closure_path(card)
|
||||||
assert_card_container_rerendered(card)
|
assert_card_container_rerendered(card)
|
||||||
end
|
end
|
||||||
|
|
||||||
assert_equal "Scope too big", card.closure.reason
|
|
||||||
end
|
end
|
||||||
|
|
||||||
test "destroy" do
|
test "destroy" do
|
||||||
|
|||||||
Vendored
+1
-2
@@ -1,4 +1,3 @@
|
|||||||
shipping:
|
shipping:
|
||||||
card: shipping
|
card: shipping
|
||||||
user: kevin
|
user: kevin
|
||||||
reason: Closed
|
|
||||||
@@ -22,7 +22,7 @@ class Card::Eventable::SystemCommenterTest < ActiveSupport::TestCase
|
|||||||
end
|
end
|
||||||
|
|
||||||
test "card_closed" do
|
test "card_closed" do
|
||||||
assert_system_comment "Closed as ‘Done’ by David" do
|
assert_system_comment "Marked as “Done” by David" do
|
||||||
@card.close
|
@card.close
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user