Compare commits
12 Commits
update-tut
...
remove-zoo
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
62ef25e511 | ||
|
|
b82aaf77ff | ||
|
|
e08dd36d68 | ||
|
|
95e9a70c4b | ||
|
|
e3acdb4d0e | ||
|
|
96b31b71cf | ||
|
|
da8e187430 | ||
|
|
4c49a5db03 | ||
|
|
35303cb570 | ||
|
|
1127f09263 | ||
|
|
19b1e75384 | ||
|
|
93a4ce462d |
@@ -11,6 +11,7 @@ $body-color: #4A4A4A;
|
|||||||
$primary: #6F89FF;
|
$primary: #6F89FF;
|
||||||
$blue: #0092ff;
|
$blue: #0092ff;
|
||||||
$red: #F9002B;
|
$red: #F9002B;
|
||||||
|
$dark-red: #CE004A;
|
||||||
$green: #51B61B;
|
$green: #51B61B;
|
||||||
$teal: #32C498;
|
$teal: #32C498;
|
||||||
$purple: #5139EE;
|
$purple: #5139EE;
|
||||||
|
|||||||
@@ -69,6 +69,13 @@ label {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.cast-me {
|
||||||
|
span:last-child {
|
||||||
|
background-color: $dark-red;
|
||||||
|
color: $white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
&.disabled {
|
&.disabled {
|
||||||
span:last-child {
|
span:last-child {
|
||||||
background-color: $gray-500 !important;
|
background-color: $gray-500 !important;
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ class AccountsController < ApplicationController
|
|||||||
|
|
||||||
if sign_in(user)
|
if sign_in(user)
|
||||||
TrackAnalyticsJob.perform_later(user, user.primary_account, :track_guest_sign_up, user_agent: request.user_agent, user_ip: request.remote_ip)
|
TrackAnalyticsJob.perform_later(user, user.primary_account, :track_guest_sign_up, user_agent: request.user_agent, user_ip: request.remote_ip)
|
||||||
SubmitHubspotFormJob.perform_later(user.first_name, user.last_name, user.email, account.name, i_m_interested_in: user.interested_product_name)
|
SubmitHubspotFormJob.perform_later(first_name: user.first_name, last_name: user.last_name, email: user.email, company: account.name, i_m_interested_in: user.interested_product_name, form_guid: ENV["HUBSPOT_FORM_GUID"])
|
||||||
redirect_to signed_in_root_path
|
redirect_to signed_in_root_path
|
||||||
else
|
else
|
||||||
redirect_to new_session_path, alert: t(".notice")
|
redirect_to new_session_path, alert: t(".notice")
|
||||||
|
|||||||
61
app/controllers/admin/casting_submissions_controller.rb
Normal file
61
app/controllers/admin/casting_submissions_controller.rb
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
class Admin::CastingSubmissionsController < Admin::ApplicationController
|
||||||
|
before_action :set_casting_submission, only: [:edit, :update, :show, :complete]
|
||||||
|
before_action :build_casting_submission, only: [:new, :create]
|
||||||
|
before_action :set_accounts, only: %i[new create edit]
|
||||||
|
|
||||||
|
def index
|
||||||
|
@casting_submissions = casting_submissions.order_by_recent.paginate(page: params[:page])
|
||||||
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
@casting_submission.attributes = casting_submission_params
|
||||||
|
|
||||||
|
if @casting_submission.save
|
||||||
|
redirect_to [:admin, :casting_submissions], notice: t(".notice")
|
||||||
|
else
|
||||||
|
render :new
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
if @casting_submission.update(casting_submission_params)
|
||||||
|
redirect_to [:admin, :casting_submissions], notice: t(".notice")
|
||||||
|
else
|
||||||
|
render :edit
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def complete
|
||||||
|
if @casting_submission.update(interviewed_at: Time.zone.now)
|
||||||
|
redirect_to [:admin, :casting_submissions], notice: t(".notice")
|
||||||
|
else
|
||||||
|
redirect_to [:admin, :casting_submissions], notice: t(".alert")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def set_accounts
|
||||||
|
@accounts = accounts
|
||||||
|
end
|
||||||
|
|
||||||
|
def casting_submission_params
|
||||||
|
params.require(:casting_submission).permit(:casting_call_id, :performer_name, :interview_date, :zoom_meeting_url, :interview_recording)
|
||||||
|
end
|
||||||
|
|
||||||
|
def casting_submissions
|
||||||
|
policy_scope CastingSubmission
|
||||||
|
end
|
||||||
|
|
||||||
|
def set_casting_submission
|
||||||
|
@casting_submission = authorize policy_scope(CastingSubmission).find(params[:id])
|
||||||
|
end
|
||||||
|
|
||||||
|
def accounts
|
||||||
|
policy_scope Account
|
||||||
|
end
|
||||||
|
|
||||||
|
def build_casting_submission
|
||||||
|
@casting_submission = authorize policy_scope(CastingSubmission).build
|
||||||
|
end
|
||||||
|
end
|
||||||
75
app/controllers/casting_calls_controller.rb
Normal file
75
app/controllers/casting_calls_controller.rb
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
class CastingCallsController < ApplicationController
|
||||||
|
layout "project"
|
||||||
|
|
||||||
|
before_action :set_project
|
||||||
|
before_action :build_casting_call, only: [:new, :create]
|
||||||
|
before_action :set_casting_call, only: [:show, :edit, :update, :cancel]
|
||||||
|
|
||||||
|
def index
|
||||||
|
@casting_calls = casting_calls.order_by_recent.paginate(page: params[:page])
|
||||||
|
end
|
||||||
|
|
||||||
|
def new
|
||||||
|
end
|
||||||
|
|
||||||
|
def create
|
||||||
|
@casting_call.attributes = casting_call_params_with_email
|
||||||
|
|
||||||
|
if @casting_call.save
|
||||||
|
log_create_analytics
|
||||||
|
redirect_to [@project, :casting_calls], notice: t(".notice")
|
||||||
|
else
|
||||||
|
render :new
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def show
|
||||||
|
render layout: 'application'
|
||||||
|
end
|
||||||
|
|
||||||
|
def edit
|
||||||
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
if @casting_call.update(casting_call_params)
|
||||||
|
redirect_to [@project, :casting_calls], notice: t(".notice")
|
||||||
|
else
|
||||||
|
render :edit
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def cancel
|
||||||
|
@casting_call.update(cancelled_at: Time.zone.now)
|
||||||
|
redirect_to [@project, :casting_calls], notice: t(".notice")
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def casting_call_params
|
||||||
|
params.require(:casting_call).permit(:title, :description, :project_description, :interview_instructions, :interview_requirements, :questions)
|
||||||
|
end
|
||||||
|
|
||||||
|
def casting_call_params_with_email
|
||||||
|
casting_call_params.merge(user_email: Current.user.email)
|
||||||
|
end
|
||||||
|
|
||||||
|
def set_project
|
||||||
|
@project = policy_scope(Project).find(params[:project_id])
|
||||||
|
end
|
||||||
|
|
||||||
|
def set_casting_call
|
||||||
|
@casting_call = authorize casting_calls.find(params[:id])
|
||||||
|
end
|
||||||
|
|
||||||
|
def casting_calls
|
||||||
|
authorize policy_scope(@project.casting_calls)
|
||||||
|
end
|
||||||
|
|
||||||
|
def build_casting_call
|
||||||
|
@casting_call = authorize @project.casting_calls.build
|
||||||
|
end
|
||||||
|
|
||||||
|
def log_create_analytics
|
||||||
|
TrackAnalyticsJob.perform_later(Current.user, Current.account, :track_create_casting_call, user_agent: request.user_agent, user_ip: request.remote_ip)
|
||||||
|
end
|
||||||
|
end
|
||||||
30
app/controllers/casting_submission_downloads_controller.rb
Normal file
30
app/controllers/casting_submission_downloads_controller.rb
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
class CastingSubmissionDownloadsController < ApplicationController
|
||||||
|
include ProjectContext
|
||||||
|
|
||||||
|
before_action :set_project, only: [:create]
|
||||||
|
before_action :set_casting_submission, only: :create
|
||||||
|
|
||||||
|
include ProjectLayout
|
||||||
|
|
||||||
|
def create
|
||||||
|
download = @project.downloads.create!(name: @casting_submission.zip_file_name, release_type: "CastingSubmission")
|
||||||
|
|
||||||
|
other_downloads_in_progress = @project.downloads.unfinished_desc_order.offset(1)
|
||||||
|
|
||||||
|
if other_downloads_in_progress.any?
|
||||||
|
in_progress_downloads_details = render_to_string "_other_pending_downloads", locals: { downloads: other_downloads_in_progress, release_type: "CastingSubmission" }, :layout => false
|
||||||
|
ProjectsChannel.broadcast_download_generation_update(download, in_progress_downloads_details)
|
||||||
|
else
|
||||||
|
ProjectsChannel.broadcast_download_generation_update(download, I18n.t("casting_submission_downloads.download.pending", release_type: "CastingSubmission"))
|
||||||
|
end
|
||||||
|
|
||||||
|
GenerateCastingSubmissionFilesZipJob.perform_later(@project, download, @casting_submission)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def set_casting_submission
|
||||||
|
authorize(Download)
|
||||||
|
@casting_submission = policy_scope(@project.casting_submissions).find(params[:casting_submission_id])
|
||||||
|
end
|
||||||
|
end
|
||||||
30
app/controllers/casting_submissions_controller.rb
Normal file
30
app/controllers/casting_submissions_controller.rb
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
class CastingSubmissionsController < ApplicationController
|
||||||
|
before_action :set_project
|
||||||
|
before_action :set_casting_submission, only: [:show]
|
||||||
|
|
||||||
|
include ProjectLayout
|
||||||
|
|
||||||
|
def index
|
||||||
|
@casting_submissions = casting_submissions.completed.order_by_recent.paginate(page: params[:page])
|
||||||
|
end
|
||||||
|
|
||||||
|
def show
|
||||||
|
@casting_call = @casting_submission.casting_call
|
||||||
|
@files = @casting_submission.files.order("created_at DESC").paginate(page: params[:files_page])
|
||||||
|
render layout: 'application'
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def set_project
|
||||||
|
@project = policy_scope(Project).find(params[:project_id])
|
||||||
|
end
|
||||||
|
|
||||||
|
def set_casting_submission
|
||||||
|
@casting_submission = authorize casting_submissions.find(params[:id])
|
||||||
|
end
|
||||||
|
|
||||||
|
def casting_submissions
|
||||||
|
authorize policy_scope(CastingSubmission)
|
||||||
|
end
|
||||||
|
end
|
||||||
14
app/controllers/public/casting_calls_controller.rb
Normal file
14
app/controllers/public/casting_calls_controller.rb
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
class Public::CastingCallsController < Public::BaseController
|
||||||
|
skip_after_action :verify_authorized
|
||||||
|
before_action :set_casting_call, only: [:show]
|
||||||
|
|
||||||
|
def show
|
||||||
|
render layout: 'application'
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def set_casting_call
|
||||||
|
@casting_call = CastingCall.find_by_token(params[:token])
|
||||||
|
end
|
||||||
|
end
|
||||||
25
app/controllers/public/casting_submissions_controller.rb
Normal file
25
app/controllers/public/casting_submissions_controller.rb
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
class Public::CastingSubmissionsController < Public::BaseController
|
||||||
|
skip_after_action :verify_authorized
|
||||||
|
before_action :set_casting_submission, only: [:show, :update]
|
||||||
|
|
||||||
|
def show
|
||||||
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
if @casting_submission.update(casting_submission_params)
|
||||||
|
redirect_to casting_submission_url(token: @casting_submission.token), notice: t(".notice")
|
||||||
|
else
|
||||||
|
render :show
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def set_casting_submission
|
||||||
|
@casting_submission = CastingSubmission.find_by_token(params[:token])
|
||||||
|
end
|
||||||
|
|
||||||
|
def casting_submission_params
|
||||||
|
params.require(:casting_submission).permit(files: [])
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -19,7 +19,7 @@ class TaskRequestsController < ApplicationController
|
|||||||
if @task_request.save
|
if @task_request.save
|
||||||
log_create_analytics
|
log_create_analytics
|
||||||
taskme_url = url_for([:admin, @task_request])
|
taskme_url = url_for([:admin, @task_request])
|
||||||
SubmitHubspotTaskRequestFormJob.perform_later(@task_request.user_email, taskme_url)
|
SubmitHubspotFormJob.perform_later(email: @task_request.user_email, taskme_url: taskme_url, form_guid: ENV["HUBSPOT_TASK_REQUEST_FORM_GUID"])
|
||||||
else
|
else
|
||||||
render :new
|
render :new
|
||||||
end
|
end
|
||||||
|
|||||||
43
app/jobs/generate_casting_submission_files_zip_job.rb
Normal file
43
app/jobs/generate_casting_submission_files_zip_job.rb
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
class GenerateCastingSubmissionFilesZipJob < ApplicationJob
|
||||||
|
queue_as :default
|
||||||
|
include Rails.application.routes.url_helpers
|
||||||
|
include ActionView::Helpers::UrlHelper
|
||||||
|
|
||||||
|
before_perform do |job|
|
||||||
|
@project = job.arguments.first
|
||||||
|
@download = job.arguments.second
|
||||||
|
@casting_submission = job.arguments.third
|
||||||
|
@download.update!(status: :pending)
|
||||||
|
end
|
||||||
|
|
||||||
|
def perform(project, download, casting_submission)
|
||||||
|
::CastingSubmissionFilesCollectionService.new(casting_submission.files, @download.name).build do |dir, files|
|
||||||
|
zipfile_name = "#{dir}/#{@download.name}.zip"
|
||||||
|
Zip::File.open(zipfile_name, Zip::File::CREATE) do |zipfile|
|
||||||
|
files.each do |attachment|
|
||||||
|
zipfile.add(attachment, File.join("#{dir}/", attachment))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
@download.file.attach(io: File.open(zipfile_name), filename: @download.name)
|
||||||
|
end
|
||||||
|
rescue StandardError => e
|
||||||
|
Raven.extra_context(
|
||||||
|
message: "Failed to generate download for project (##{project.id})",
|
||||||
|
release_type: "CastingSubmission"
|
||||||
|
)
|
||||||
|
|
||||||
|
@download.failure!
|
||||||
|
ProjectsChannel.broadcast_download_generation_update(@download, I18n.t("casting_submission_downloads.download.failure"))
|
||||||
|
end
|
||||||
|
|
||||||
|
after_perform do |job|
|
||||||
|
if @download.pending? && @download.file.attached?
|
||||||
|
@download.success!
|
||||||
|
|
||||||
|
downloads_folder_link = link_to("Files > Downloads", project_downloads_path(I18n.locale, @project))
|
||||||
|
download_button = link_to("Download", rails_blob_path(@download.file, disposition: "attachment", only_path: true), class: "btn btn-success", target: :_blank)
|
||||||
|
ProjectsChannel.broadcast_download_generation_update(@download, I18n.t("casting_submission_downloads.download.success", downloads_folder_link: downloads_folder_link, download_button: download_button, release_type: "Casting Submission"))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -1,19 +1,11 @@
|
|||||||
class SubmitHubspotFormJob < ApplicationJob
|
class SubmitHubspotFormJob < ApplicationJob
|
||||||
queue_as :default
|
queue_as :default
|
||||||
|
|
||||||
def perform(first_name, last_name, email, company_name, additional_params = {})
|
def perform(params = {})
|
||||||
hubspot_form_guid = ENV["HUBSPOT_FORM_GUID"]
|
return unless params[:form_guid].present?
|
||||||
return unless hubspot_form_guid.present?
|
|
||||||
|
|
||||||
submission_params = {
|
form = Hubspot::Form.new("guid" => params[:form_guid])
|
||||||
first_name: first_name,
|
is_form_sumitted = form.submit(params.except(:form_guid))
|
||||||
last_name: last_name,
|
|
||||||
email: email,
|
|
||||||
company: company_name
|
|
||||||
}.merge(additional_params)
|
|
||||||
|
|
||||||
form = Hubspot::Form.new("guid" => hubspot_form_guid)
|
|
||||||
is_form_sumitted = form.submit(submission_params)
|
|
||||||
|
|
||||||
raise StandardError.new "Failed to submit the hubspot form data: #{is_form_sumitted}" unless is_form_sumitted
|
raise StandardError.new "Failed to submit the hubspot form data: #{is_form_sumitted}" unless is_form_sumitted
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,18 +0,0 @@
|
|||||||
class SubmitHubspotTaskRequestFormJob < ApplicationJob
|
|
||||||
queue_as :default
|
|
||||||
|
|
||||||
def perform(user_email, taskme_url)
|
|
||||||
hubspot_task_request_form_guid = ENV["HUBSPOT_TASK_REQUEST_FORM_GUID"]
|
|
||||||
return unless hubspot_task_request_form_guid.present?
|
|
||||||
|
|
||||||
submission_params = {
|
|
||||||
email: user_email,
|
|
||||||
taskme_url: taskme_url
|
|
||||||
}
|
|
||||||
|
|
||||||
form = Hubspot::Form.new("guid" => hubspot_task_request_form_guid)
|
|
||||||
is_form_sumitted = form.submit(submission_params)
|
|
||||||
|
|
||||||
raise StandardError.new "Failed to submit the task request hubspot form data: #{is_form_sumitted}" unless is_form_sumitted
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@@ -4,6 +4,8 @@ class Account < ApplicationRecord
|
|||||||
has_many :account_auths
|
has_many :account_auths
|
||||||
has_many :users, through: :account_auths
|
has_many :users, through: :account_auths
|
||||||
has_many :projects, dependent: :destroy
|
has_many :projects, dependent: :destroy
|
||||||
|
has_many :casting_calls, through: :projects
|
||||||
|
has_many :casting_submissions, through: :projects
|
||||||
has_many :videos, through: :projects
|
has_many :videos, through: :projects
|
||||||
has_many :contract_templates, through: :projects
|
has_many :contract_templates, through: :projects
|
||||||
|
|
||||||
@@ -59,6 +61,8 @@ class Account < ApplicationRecord
|
|||||||
MedicalRelease.where(project: projects),
|
MedicalRelease.where(project: projects),
|
||||||
MiscRelease.where(project: projects),
|
MiscRelease.where(project: projects),
|
||||||
MatchingRequest.where(project: projects),
|
MatchingRequest.where(project: projects),
|
||||||
|
CastingCall.where(project: projects),
|
||||||
|
self.casting_submissions,
|
||||||
self
|
self
|
||||||
])).sum(:byte_size).to_f
|
])).sum(:byte_size).to_f
|
||||||
end
|
end
|
||||||
@@ -87,6 +91,10 @@ class Account < ApplicationRecord
|
|||||||
ENV["TASKME_ENABLED"] && (plan_uid.to_s == "me_suite" || plan_uid.to_s == "taskme")
|
ENV["TASKME_ENABLED"] && (plan_uid.to_s == "me_suite" || plan_uid.to_s == "taskme")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def castme_enabled?
|
||||||
|
plan_uid.to_s == "me_suite" || plan_uid.to_s == "castme"
|
||||||
|
end
|
||||||
|
|
||||||
def plan_name
|
def plan_name
|
||||||
case plan_uid.to_s
|
case plan_uid.to_s
|
||||||
when "deliverme"
|
when "deliverme"
|
||||||
@@ -97,6 +105,8 @@ class Account < ApplicationRecord
|
|||||||
"ReleaseME"
|
"ReleaseME"
|
||||||
when "taskme"
|
when "taskme"
|
||||||
"TaskME"
|
"TaskME"
|
||||||
|
when "castme"
|
||||||
|
"CastME"
|
||||||
when "me_suite"
|
when "me_suite"
|
||||||
"ME Suite"
|
"ME Suite"
|
||||||
end
|
end
|
||||||
|
|||||||
18
app/models/casting_call.rb
Normal file
18
app/models/casting_call.rb
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
class CastingCall < ApplicationRecord
|
||||||
|
belongs_to :project
|
||||||
|
has_many :casting_submissions, dependent: :destroy
|
||||||
|
|
||||||
|
has_secure_token
|
||||||
|
|
||||||
|
def status
|
||||||
|
if cancelled?
|
||||||
|
"Cancelled"
|
||||||
|
else
|
||||||
|
"Active"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def cancelled?
|
||||||
|
self.cancelled_at.present?
|
||||||
|
end
|
||||||
|
end
|
||||||
15
app/models/casting_submission.rb
Normal file
15
app/models/casting_submission.rb
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
class CastingSubmission < ApplicationRecord
|
||||||
|
belongs_to :casting_call
|
||||||
|
has_many_attached :files
|
||||||
|
has_one_attached :interview_recording
|
||||||
|
|
||||||
|
has_secure_token
|
||||||
|
|
||||||
|
validates :performer_name, presence: true
|
||||||
|
|
||||||
|
scope :completed, -> { where.not(interviewed_at: nil) }
|
||||||
|
|
||||||
|
def zip_file_name
|
||||||
|
"#{self.casting_call.title.parameterize}_#{self.performer_name.parameterize}_#{Time.now.strftime('%Y-%m-%d_%H-%M-%S')}"
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -15,6 +15,8 @@ class Project < ApplicationRecord
|
|||||||
has_many :talent_releases, dependent: :destroy
|
has_many :talent_releases, dependent: :destroy
|
||||||
has_many :medical_releases, dependent: :destroy
|
has_many :medical_releases, dependent: :destroy
|
||||||
has_many :misc_releases, dependent: :destroy
|
has_many :misc_releases, dependent: :destroy
|
||||||
|
has_many :casting_calls, dependent: :destroy
|
||||||
|
has_many :casting_submissions, through: :casting_calls
|
||||||
has_many :videos, dependent: :destroy
|
has_many :videos, dependent: :destroy
|
||||||
has_many :imports, dependent: :destroy
|
has_many :imports, dependent: :destroy
|
||||||
has_many :contract_templates, dependent: :destroy
|
has_many :contract_templates, dependent: :destroy
|
||||||
|
|||||||
25
app/policies/casting_call_policy.rb
Normal file
25
app/policies/casting_call_policy.rb
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
class CastingCallPolicy < ApplicationPolicy
|
||||||
|
def index?
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
def show?
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
def create?
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy?
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
def update?
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
def cancel?
|
||||||
|
true
|
||||||
|
end
|
||||||
|
end
|
||||||
29
app/policies/casting_submission_policy.rb
Normal file
29
app/policies/casting_submission_policy.rb
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
class CastingSubmissionPolicy < ApplicationPolicy
|
||||||
|
def index?
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
def show?
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
def create?
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy?
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
def update?
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
def complete?
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
def download?
|
||||||
|
true
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -40,4 +40,8 @@ class ProjectPolicy < ApplicationPolicy
|
|||||||
def show_task_results?
|
def show_task_results?
|
||||||
show?
|
show?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def show_casting_submission_results?
|
||||||
|
show?
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
24
app/services/casting_submission_files_collection_service.rb
Normal file
24
app/services/casting_submission_files_collection_service.rb
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
class CastingSubmissionFilesCollectionService
|
||||||
|
def initialize(files, folder_name)
|
||||||
|
@files = files
|
||||||
|
@folder_name = folder_name
|
||||||
|
end
|
||||||
|
|
||||||
|
def build
|
||||||
|
Dir.mktmpdir { |dir|
|
||||||
|
files.each do |file|
|
||||||
|
open("#{dir}/#{file.filename}", 'wb') do |tmp_file|
|
||||||
|
tmp_file << open(file.service_url.to_s).read
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
read_files = Dir.entries("#{dir}/").select { |f| !File.directory? f }
|
||||||
|
raise StandardError.new "Files not found." unless read_files.any?
|
||||||
|
yield(dir, read_files)
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
attr_reader :files, :folder_name
|
||||||
|
end
|
||||||
@@ -170,6 +170,24 @@ class Analytics
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def track_create_casting_call(user_agent:, user_ip:)
|
||||||
|
if analytics_enabled?
|
||||||
|
identify
|
||||||
|
track(
|
||||||
|
{
|
||||||
|
user_id: user.id,
|
||||||
|
event: "Casting call created",
|
||||||
|
properties: {
|
||||||
|
account: account.try(:name),
|
||||||
|
account_id: account.try(:id),
|
||||||
|
user_agent: user_agent,
|
||||||
|
ip: user_ip,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
attr_reader :user, :account, :backend
|
attr_reader :user, :account, :backend
|
||||||
|
|||||||
@@ -10,6 +10,9 @@
|
|||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<%= link_to fa_icon("tasks fw", text: "Task Requests"), [:admin, :task_requests], class: class_string("nav-link", "active" => controller_name == "task_requests") %>
|
<%= link_to fa_icon("tasks fw", text: "Task Requests"), [:admin, :task_requests], class: class_string("nav-link", "active" => controller_name == "task_requests") %>
|
||||||
</li>
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<%= link_to fa_icon("video-camera fw", text: "Casting Submissions"), [:admin, :casting_submissions], class: class_string("nav-link", "active" => controller_name == "casting_submissions") %>
|
||||||
|
</li>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<%= link_to fa_icon("bug fw", text: "Errors"), "https://sentry.io/bigmedia/", class: "nav-link", target: :_blank %>
|
<%= link_to fa_icon("bug fw", text: "Errors"), "https://sentry.io/bigmedia/", class: "nav-link", target: :_blank %>
|
||||||
</li>
|
</li>
|
||||||
|
|||||||
@@ -0,0 +1,26 @@
|
|||||||
|
<tr id="<%= dom_id(casting_submission) %>">
|
||||||
|
<td>
|
||||||
|
<%= casting_submission.casting_call.project.account.name.titleize %>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<%= casting_submission.casting_call.title.titleize %>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<%= casting_submission.performer_name %>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<%= casting_submission.interview_date %>
|
||||||
|
</td>
|
||||||
|
<td class="text-right">
|
||||||
|
<div class="btn-group">
|
||||||
|
<%= button_tag "Manage", class: "btn btn-light btn-sm dropdown-toggle border", data: { toggle: "dropdown", boundary: "window" }, aria: { haspopup: true, expanded: false } %>
|
||||||
|
<div class="dropdown-menu dropdown-menu-right">
|
||||||
|
<%= link_to fa_icon("video-camera", text: "View"), casting_submission_url(token: casting_submission.token), target: "_blank", class: "dropdown-item" %>
|
||||||
|
<%= link_to fa_icon("pencil", text: "Edit"), [:edit, :admin, casting_submission], class: "dropdown-item" %>
|
||||||
|
<% unless casting_submission.interviewed_at.present? %>
|
||||||
|
<%= link_to fa_icon("check", text: "Complete"), [:complete, :admin, casting_submission], method: :post, class: "dropdown-item" %>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
30
app/views/admin/casting_submissions/_form.html.erb
Normal file
30
app/views/admin/casting_submissions/_form.html.erb
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
<%= errors_summary_for casting_submission %>
|
||||||
|
|
||||||
|
<%= bootstrap_form_with model: model, local: true do |form| %>
|
||||||
|
<%= form.text_field :performer_name, required: true %>
|
||||||
|
<%= form.grouped_collection_select(:casting_call_id, @accounts, :casting_calls, :name, :id, :title, { prompt: "Select a Casting Call", required: true, class: "form-control custom-select" }) %>
|
||||||
|
<%= form.text_field :interview_date, class: "datepicker-control" %>
|
||||||
|
<%= form.text_field :zoom_meeting_url %>
|
||||||
|
|
||||||
|
<% unless casting_submission.new_record? %>
|
||||||
|
<%= form.file_field :interview_recording, accept: "video/*", data: { direct_upload_url: rails_direct_uploads_url, aws_bucket: ENV['AWS_BUCKET'], aws_access_key_id: ENV['AWS_ACCESS_KEY_ID'], signer_url: multipart_signatures_url } %>
|
||||||
|
|
||||||
|
<% if casting_submission.interview_recording.attached? %>
|
||||||
|
<p>
|
||||||
|
<%= link_to casting_submission.interview_recording do %>
|
||||||
|
<%= fa_icon "file-text-o" %> <%= casting_submission.interview_recording.filename %>
|
||||||
|
<% end %>
|
||||||
|
<span class="text-muted"><%= fa_icon "long-arrow-left" %> <em>Current interview recording</em></span>
|
||||||
|
</p>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<div class="row align-items-center text-center mt-4">
|
||||||
|
<%= link_to t("shared.cancel"), [:admin, :casting_submissions], class: "col-3 text-reset" %>
|
||||||
|
<div class="col-9">
|
||||||
|
<%= form.submit class: class_string("btn btn-block", ["btn-success", "btn-primary"] => casting_submission.new_record?), data: { disable_with: t("shared.disable_with") } %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
6
app/views/admin/casting_submissions/edit.html.erb
Normal file
6
app/views/admin/casting_submissions/edit.html.erb
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<div class="card shadow-sm">
|
||||||
|
<%= card_header text: "Edit Casting Submission", close_action_path: [:admin, :casting_submissions] %>
|
||||||
|
<div class="card-body">
|
||||||
|
<%= render "form", model: [:admin, @casting_submission], casting_submission: @casting_submission %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
32
app/views/admin/casting_submissions/index.html.erb
Normal file
32
app/views/admin/casting_submissions/index.html.erb
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
<div class="d-flex flex-row justify-content-between align-items-center mb-3">
|
||||||
|
<% if policy(CastingCall).new? %>
|
||||||
|
<%= link_to fa_icon("plus", text: t(".actions.new")), [:new, :admin, :casting_submission], class: "btn btn-primary mb-3" %>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="border bg-white rounded shadow-sm pb-3 table-responsive">
|
||||||
|
<table class="table table-striped tr-px-4 align-all-middle">
|
||||||
|
<thead class="thead-light">
|
||||||
|
<tr>
|
||||||
|
<th>Account Name</th>
|
||||||
|
<th>Casting Call Request</th>
|
||||||
|
<th>Perfomer's Name</th>
|
||||||
|
<th>Interview Date</th>
|
||||||
|
<th></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody id="users">
|
||||||
|
<% if @casting_submissions.any? %>
|
||||||
|
<%= render @casting_submissions %>
|
||||||
|
<% else %>
|
||||||
|
<tr>
|
||||||
|
<td colspan="20" class="py-4 text-center text-muted"><%= t(".empty") %></td>
|
||||||
|
</tr>
|
||||||
|
<% end %>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="casting_submissions_pagination" class="mt-3">
|
||||||
|
<%= will_paginate @casting_submissions %>
|
||||||
|
</div>
|
||||||
6
app/views/admin/casting_submissions/new.html.erb
Normal file
6
app/views/admin/casting_submissions/new.html.erb
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<div class="card shadow-sm">
|
||||||
|
<%= card_header text: t(".heading"), close_action_path: [:admin, :casting_submissions] %>
|
||||||
|
<div class="card-body">
|
||||||
|
<%= render "form", model: [:admin, @casting_submission], casting_submission: @casting_submission, casting_calls: @casting_calls %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@@ -43,6 +43,12 @@
|
|||||||
<%= product_wordmark :deliver_me, class: class_string("d-inline-block", "disabled" => !Current.account.deliverme_enabled?) %>
|
<%= product_wordmark :deliver_me, class: class_string("d-inline-block", "disabled" => !Current.account.deliverme_enabled?) %>
|
||||||
<% end %>
|
<% end %>
|
||||||
</li>
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<%= link_to [project, :casting_calls], class: class_string("nav-link", "active" => controller_name == "casting_calls") do %>
|
||||||
|
<%= lock_icon_for(Current.account, :castme) %>
|
||||||
|
<%= product_wordmark :cast_me, class: class_string("d-inline-block", "disabled" => !Current.account.castme_enabled?) %>
|
||||||
|
<% end %>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
<hr class="divider-light mx-n4">
|
<hr class="divider-light mx-n4">
|
||||||
|
|||||||
28
app/views/casting_calls/_casting_call.html.erb
Normal file
28
app/views/casting_calls/_casting_call.html.erb
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<%= casting_call.created_at.strftime('%D') %>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<%= casting_call.title %>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<%= casting_call.status %>
|
||||||
|
</td>
|
||||||
|
<td class="text-right">
|
||||||
|
<div class="btn-group">
|
||||||
|
<%= button_tag t(".actions.manage"), class: "btn btn-light btn-sm dropdown-toggle border", data: { toggle: "dropdown", boundary: "window" }, aria: { haspopup: true, expanded: false } %>
|
||||||
|
<div class="dropdown-menu dropdown-menu-right">
|
||||||
|
<%= link_to fa_icon("link fw", text: "Copy Audition URL"), casting_call_url(casting_call.token), class: "dropdown-item", data: { behavior: "clipboard" } %>
|
||||||
|
<% if policy(casting_call).show? %>
|
||||||
|
<%= link_to fa_icon("tasks fw", text: "View"), [casting_call.project, casting_call], class: "dropdown-item", target: '_blank' %>
|
||||||
|
<% end %>
|
||||||
|
<% if policy(casting_call).edit? %>
|
||||||
|
<%= link_to fa_icon("pencil fw", text: "Edit"), [:edit, casting_call.project, casting_call], class: "dropdown-item" %>
|
||||||
|
<% end %>
|
||||||
|
<% if policy(casting_call).cancel? && !casting_call.cancelled? %>
|
||||||
|
<%= link_to fa_icon("ban fw", text: "Cancel"), [:cancel, casting_call.project, casting_call], class: "dropdown-item", method: :post %>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
24
app/views/casting_calls/_form.html.erb
Normal file
24
app/views/casting_calls/_form.html.erb
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
<%= errors_summary_for casting_call %>
|
||||||
|
|
||||||
|
<%= bootstrap_form_with model: model, url: [@project, @casting_call, show_chat: true], local: true do |form| %>
|
||||||
|
<div class="alert alert-info text-center text-md-left">
|
||||||
|
<%= fa_icon "info-circle" %>
|
||||||
|
<strong><%= t '.info_message' %></strong>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<%= form.text_field :title %>
|
||||||
|
<%= form.text_area :description %>
|
||||||
|
<%= form.text_area :project_description %>
|
||||||
|
<%= field_set_tag t(".headings.chatbot") do %>
|
||||||
|
<%= form.text_area :interview_instructions, rows: 6 %>
|
||||||
|
<%= form.text_area :questions, rows: 8 %>
|
||||||
|
<%= form.text_area :interview_requirements, rows: 6 %>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<div class="row align-items-center text-center mt-4">
|
||||||
|
<%= link_to t("shared.cancel"), [project, :casting_calls], class: "col-3 text-reset" %>
|
||||||
|
<div class="col-9">
|
||||||
|
<%= form.submit class: class_string("btn btn-block", ["btn-success", "btn-primary"] => casting_call.new_record?), data: { disable_with: t("shared.disable_with") } %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
6
app/views/casting_calls/edit.html.erb
Normal file
6
app/views/casting_calls/edit.html.erb
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<div class="card shadow-sm">
|
||||||
|
<%= card_header text: t(".heading"), close_action_path: [@project, :casting_calls] %>
|
||||||
|
<div class="card-body">
|
||||||
|
<%= render "form", model: [@project, @casting_call], casting_call: @casting_call, project: @project %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
37
app/views/casting_calls/index.html.erb
Normal file
37
app/views/casting_calls/index.html.erb
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
<%= product_wordmark :cast_me, class: "small mb-3" %>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-12">
|
||||||
|
<div class="d-md-flex d-sm-flex flex-sm-column flex-md-row flex-md-wrap mb-3">
|
||||||
|
<% if policy(CastingCall).new? %>
|
||||||
|
<%= link_to fa_icon("plus", text: t(".actions.new")), [:new, @project, :casting_call], class: "btn btn-primary mb-2" %>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="border bg-white rounded shadow-sm pb-3 table-responsive">
|
||||||
|
<table class="table table-striped tr-px-4 align-all-middle">
|
||||||
|
<thead class="thead-light">
|
||||||
|
<tr>
|
||||||
|
<th><%= t(".table_headers.casting_call_created_on") %></th>
|
||||||
|
<th><%= t(".table_headers.casting_call_title") %></th>
|
||||||
|
<th><%= t(".table_headers.casting_call_status") %></th>
|
||||||
|
<th></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody id="casting_calls">
|
||||||
|
<% if @casting_calls.any? %>
|
||||||
|
<%= render @casting_calls %>
|
||||||
|
<% else %>
|
||||||
|
<tr>
|
||||||
|
<td colspan="20" class="py-4 text-center text-muted"><%= t(".empty") %></td>
|
||||||
|
</tr>
|
||||||
|
<% end %>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="casting_calls_pagination" class="mt-3">
|
||||||
|
<%= will_paginate @casting_calls %>
|
||||||
|
</div>
|
||||||
6
app/views/casting_calls/new.html.erb
Normal file
6
app/views/casting_calls/new.html.erb
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<div class="card shadow-sm">
|
||||||
|
<%= card_header text: t(".heading"), close_action_path: [@project, :casting_calls] %>
|
||||||
|
<div class="card-body">
|
||||||
|
<%= render "form", model: [@project, @casting_call], casting_call: @casting_call, project: @project %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
38
app/views/casting_calls/show.html.erb
Normal file
38
app/views/casting_calls/show.html.erb
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
<% content_for :header do %>
|
||||||
|
<header class="container-fluid py-3 border-bottom sticky-top bg-light">
|
||||||
|
<div class="row align-items-center justify-content-center">
|
||||||
|
<div class="col-4 text-center">
|
||||||
|
<%= product_wordmark(:cast_me, class: 'navbar-brand') %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<div class="card shadow-sm">
|
||||||
|
<%= card_header text: @casting_call.title, close_action_path: [@project, :casting_calls] %>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-6 col-sm-12">
|
||||||
|
<dl>
|
||||||
|
<%= description_list_pair_for @casting_call, :title, append: ":" %>
|
||||||
|
<%= description_list_pair_for @casting_call, :description, append: ":" %>
|
||||||
|
<%= description_list_pair_for @casting_call, :project_description, append: ":" %>
|
||||||
|
<%= description_list_pair_for @casting_call, :created_at, append: ":" %>
|
||||||
|
</dl>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6 col-sm-12">
|
||||||
|
<dl>
|
||||||
|
<%= description_list_pair_for @casting_call, :status, append: ":" %>
|
||||||
|
<%= description_list_pair_for @casting_call, :interview_instructions, append: ":" %>
|
||||||
|
<%= description_list_pair_for @casting_call, :interview_requirements, append: ":" %>
|
||||||
|
<%= description_list_pair_for @casting_call, :questions, append: ":" %>
|
||||||
|
</dl>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<% unless @casting_call.cancelled? %>
|
||||||
|
<div class="row align-items-center justify-content-center mt-3">
|
||||||
|
<%= link_to "Schedule an Audition", ENV["CASTME_AUDITION_BOOKING_URL"], target: "_blank", class: "btn btn-primary" %>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
<p>Your <%= release_type.titleize %> files are being prepared for download. You will be notified when it's ready.
|
||||||
|
</p>
|
||||||
|
<p class="mt-3">The following downloads are also in progress:</p>
|
||||||
|
<ul>
|
||||||
|
<% downloads.each do |download| %>
|
||||||
|
<% if download.release_type == "reports"%>
|
||||||
|
<li><%= download.release_type.titleize %> (as of <%= time_ago_in_words(download.created_at) %> ago)
|
||||||
|
</li>
|
||||||
|
<% elsif download.release_type == "CastingSubmission"%>
|
||||||
|
<li><%= download.release_type.titleize %> files (as of <%= time_ago_in_words(download.created_at) %> ago)
|
||||||
|
</li>
|
||||||
|
<% else %>
|
||||||
|
<li><%= download.release_type.titleize %> contracts (as of <%= time_ago_in_words(download.created_at) %> ago)
|
||||||
|
</li>
|
||||||
|
<% end %>
|
||||||
|
<% end %>
|
||||||
|
</ul>
|
||||||
27
app/views/casting_submissions/_casting_submission.html.erb
Normal file
27
app/views/casting_submissions/_casting_submission.html.erb
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
<tr id="<%= dom_id(casting_submission) %>">
|
||||||
|
<td>
|
||||||
|
<%= casting_submission.casting_call.project.account.name.titleize %>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<%= casting_submission.casting_call.title&.titleize %>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<%= casting_submission.performer_name %>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<%= casting_submission.interviewed_at %>
|
||||||
|
</td>
|
||||||
|
<td class="text-right">
|
||||||
|
<div class="btn-group">
|
||||||
|
<%= button_tag "Manage", class: "btn btn-light btn-sm dropdown-toggle border", data: { toggle: "dropdown", boundary: "window" }, aria: { haspopup: true, expanded: false } %>
|
||||||
|
<div class="dropdown-menu dropdown-menu-right">
|
||||||
|
<% if policy(CastingSubmission).show? %>
|
||||||
|
<%= link_to fa_icon("video-camera", text: "View"), [@project, casting_submission], target: "_blank", class: "dropdown-item" %>
|
||||||
|
<% end %>
|
||||||
|
<% if policy(CastingSubmission).download? %>
|
||||||
|
<%= link_to fa_icon("download", text: "Download"), [@project, :casting_submission_downloads, casting_submission_id: casting_submission.id], method: :post, remote: true, class: "dropdown-item" %>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
12
app/views/casting_submissions/_file.html.erb
Normal file
12
app/views/casting_submissions/_file.html.erb
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
<li class="my-2" id="<%= dom_id(file) %>">
|
||||||
|
<% if file.variable? %>
|
||||||
|
<%= link_to image_tag(file.variant(resize_and_pad: [300, 300, background: "#F7F8F9"]), class: "bg-light img-thumbnail img-fluid"), file, target: "_blank" %>
|
||||||
|
<% else %>
|
||||||
|
<div class="border rounded bg-light text-muted d-flex justify-content-center align-items-center fix-h-and-w">
|
||||||
|
<%= link_to file, target: "_blank" do %>
|
||||||
|
<%= fa_icon("file", style: "font-size: 2rem") %>
|
||||||
|
<div class="mt-2"><%= file.filename %></div>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
</li>
|
||||||
14
app/views/casting_submissions/_files_section.html.erb
Normal file
14
app/views/casting_submissions/_files_section.html.erb
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
<div class="overflow-auto mh-30">
|
||||||
|
<ul class="list-unstyled d-flex flex-column align-items-center text-center" id="casting_submission_file_list_<%= casting_submission.id %>">
|
||||||
|
<% if files.present? %>
|
||||||
|
<%= render partial: "casting_submissions/file", collection: files %>
|
||||||
|
<% else %>
|
||||||
|
<li class="my-3">
|
||||||
|
Files will appear here.
|
||||||
|
</li>
|
||||||
|
<% end %>
|
||||||
|
</ul>
|
||||||
|
<div class="d-flex mt-2 justify-content-center" id="casting_submission_files_pagination_<%= casting_submission.id %>">
|
||||||
|
<%= will_paginate(files, param_name: 'files_page', params: { active_files_tab: casting_submission.id }) if files.present? %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
15
app/views/casting_submissions/_video.html.erb
Normal file
15
app/views/casting_submissions/_video.html.erb
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<% if casting_submission.interview_recording.present? %>
|
||||||
|
<div id="casting_submission_video" class="embed-responsive-item"></div>
|
||||||
|
<% else %>
|
||||||
|
<div id="casting_submission_video" class="embed-responsive-item">
|
||||||
|
<table class="w-100 h-100 bg-secondary">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td class="text-center align-middle text-white">
|
||||||
|
Video player will appear here when the interview recording is available.
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
26
app/views/casting_submissions/index.html.erb
Normal file
26
app/views/casting_submissions/index.html.erb
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
<div class="border bg-white rounded shadow-sm pb-3 table-responsive">
|
||||||
|
<table class="table table-striped tr-px-4 align-all-middle">
|
||||||
|
<thead class="thead-light">
|
||||||
|
<tr>
|
||||||
|
<th>Account Name</th>
|
||||||
|
<th>Casting Call Request</th>
|
||||||
|
<th>Perfomer's Name</th>
|
||||||
|
<th>Interviewed At</th>
|
||||||
|
<th></th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody id="users">
|
||||||
|
<% if @casting_submissions.any? %>
|
||||||
|
<%= render @casting_submissions %>
|
||||||
|
<% else %>
|
||||||
|
<tr>
|
||||||
|
<td colspan="20" class="py-4 text-center text-muted"><%= t(".empty") %></td>
|
||||||
|
</tr>
|
||||||
|
<% end %>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="casting_submissions_pagination" class="mt-3">
|
||||||
|
<%= will_paginate @casting_submissions %>
|
||||||
|
</div>
|
||||||
79
app/views/casting_submissions/show.html.erb
Normal file
79
app/views/casting_submissions/show.html.erb
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
<% content_for :header do %>
|
||||||
|
<header class="container-fluid py-3 border-bottom sticky-top bg-light">
|
||||||
|
<div class="row align-items-center justify-content-center">
|
||||||
|
<div class="col-4 text-center">
|
||||||
|
<%= product_wordmark(:cast_me, class: 'navbar-brand') %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-lg-8 col-md-12 mb-3">
|
||||||
|
<div class="card shadow-sm">
|
||||||
|
<div class="card-header">
|
||||||
|
<div class="d-flex justify-content-start flex-column">
|
||||||
|
<h1 class="h2 mb-1"><%= @casting_submission.performer_name %></h1>
|
||||||
|
<h1 class="h6 mb-1"><%= @casting_call.title %></h1>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="card-body p-0">
|
||||||
|
<div class="embed-responsive embed-responsive-16by9">
|
||||||
|
<%= render partial: 'casting_submissions/video', locals: { casting_submission: @casting_submission } %>
|
||||||
|
<% if @casting_submission.interview_recording.present? %>
|
||||||
|
<%= javascript_tag nonce: true do %>
|
||||||
|
new Clappr.Player({
|
||||||
|
parentId: '#casting_submission_video',
|
||||||
|
source: "<%= rails_blob_url(@casting_submission.interview_recording, host: AppHost.new.domain_with_port) %>",
|
||||||
|
width: '100%',
|
||||||
|
height: '100%',
|
||||||
|
mute: true,
|
||||||
|
autoPlay: true,
|
||||||
|
hlsMinimumDvrSize: 1
|
||||||
|
});
|
||||||
|
<% end %>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-lg-4 col-md-12 mb-3">
|
||||||
|
<div class="card shadow-sm mb-3">
|
||||||
|
<div class="card-header">
|
||||||
|
<ul class="nav nav-tabs card-header-tabs">
|
||||||
|
<li class="nav-item">
|
||||||
|
<%= link_to "Home", "#home", class: class_string("nav-link", "active" => !params[:active_tab].present?), data: { toggle: "tab" } %>
|
||||||
|
</li>
|
||||||
|
<li class="nav-item">
|
||||||
|
<%= link_to "Files", "#files", class: class_string("nav-link", "active" => params[:active_tab] == "files"), data: { toggle: "tab" } %>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="card-body p-3">
|
||||||
|
<div class="tab-content">
|
||||||
|
<div class="<%= class_string("tab-pane fade show", "active" => !params[:active_tab].present?) %>" id="home">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-12">
|
||||||
|
<dl>
|
||||||
|
<%= description_list_pair_for @casting_call, :title, append: ":" %>
|
||||||
|
<%= description_list_pair_for @casting_call, :status, append: ":" %>
|
||||||
|
<%= description_list_pair_for @casting_call, :created_at, append: ":" %>
|
||||||
|
<%= description_list_pair_for @casting_call, :description, append: ":" %>
|
||||||
|
<%= description_list_pair_for @casting_call, :project_description, append: ":" %>
|
||||||
|
<%= description_list_pair_for @casting_call, :interview_instructions, append: ":" %>
|
||||||
|
<%= description_list_pair_for @casting_call, :interview_requirements, append: ":" %>
|
||||||
|
<%= description_list_pair_for @casting_call, :questions, append: ":" %>
|
||||||
|
</dl>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="<%= class_string("tab-pane fade show", "active" => params[:active_tab] == 'files') %>" id="files">
|
||||||
|
<div class="tab-pane fade show active" id="files_casting_submission_<%= @casting_submission.id %>">
|
||||||
|
<%= render partial: 'casting_submissions/files_section', locals: { casting_submission: @casting_submission, files: @files } %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@@ -21,6 +21,11 @@
|
|||||||
<%= link_to t("projects.show.tasks"), [@project, :tasks], class: "text-decoration-none text-reset stretched-link" %>
|
<%= link_to t("projects.show.tasks"), [@project, :tasks], class: "text-decoration-none text-reset stretched-link" %>
|
||||||
<% end %>
|
<% end %>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
<% if policy(Project).show_casting_submission_results? %>
|
||||||
|
<%= render "folder_card" do %>
|
||||||
|
<%= link_to t("projects.show.casting_submissions"), [@project, :casting_submissions], class: "text-decoration-none text-reset stretched-link" %>
|
||||||
|
<% end %>
|
||||||
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<hr/>
|
<hr/>
|
||||||
|
|||||||
29
app/views/public/casting_calls/show.html.erb
Normal file
29
app/views/public/casting_calls/show.html.erb
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
<% content_for :header do %>
|
||||||
|
<header class="container-fluid py-3 border-bottom sticky-top bg-light">
|
||||||
|
<div class="row align-items-center justify-content-center">
|
||||||
|
<div class="col-4 text-center">
|
||||||
|
<%= product_wordmark(:cast_me, class: 'navbar-brand') %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<div class="card shadow-sm">
|
||||||
|
<%= card_header text: @casting_call.title %>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12">
|
||||||
|
<dl>
|
||||||
|
<%= description_list_pair_for @casting_call, :title, append: ":" %>
|
||||||
|
<%= description_list_pair_for @casting_call, :description, append: ":" %>
|
||||||
|
<%= description_list_pair_for @casting_call, :project_description, append: ":" %>
|
||||||
|
</dl>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<% unless @casting_call.cancelled? %>
|
||||||
|
<div class="row align-items-center justify-content-center mt-3">
|
||||||
|
<%= link_to "Schedule an Audition", ENV["CASTME_AUDITION_BOOKING_URL"], target: "_blank", class: "btn btn-primary" %>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
51
app/views/public/casting_submissions/show.html.erb
Normal file
51
app/views/public/casting_submissions/show.html.erb
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
<div class="card shadow-sm">
|
||||||
|
<%= card_header text: "Casting submission details" %>
|
||||||
|
<div class="card-body">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-lg-12">
|
||||||
|
<dl>
|
||||||
|
<%= description_list_pair_for @casting_submission, :performer_name, append: ":" %>
|
||||||
|
<%= description_list_pair_for @casting_submission, :interview_date, append: ":" %>
|
||||||
|
</dl>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<h6>INTERVIEW FILES:</h6>
|
||||||
|
<hr/>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-lg-12">
|
||||||
|
<div class="card shadow-sm">
|
||||||
|
<%= card_header text: t(".heading") %>
|
||||||
|
<div class="card-body">
|
||||||
|
<%= errors_summary_for @casting_submission %>
|
||||||
|
<%= bootstrap_form_with model: @casting_submission, url: casting_submission_path(token: @casting_submission.token), local: true do |form| %>
|
||||||
|
<div class="field d-none">
|
||||||
|
<%= form.label :files %>
|
||||||
|
<%= form.file_field :files, disable: true, direct_upload: true, multiple: true, id: "casting_call_interivew_files", hide_label: true %>
|
||||||
|
<% @casting_submission.files.each do |file| %>
|
||||||
|
<% unless file.persisted? %>
|
||||||
|
<%= hidden_field_tag "#{@casting_submission.model_name.param_key}[files][]", file.signed_id %>
|
||||||
|
<% end %>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="dropzone field border-dashed"
|
||||||
|
data-accepted-files="audio/*,image/*,video/*"
|
||||||
|
data-behavior="dropzone"
|
||||||
|
data-file-input-id="casting_call_interivew_files"
|
||||||
|
data-existing-files="<%= mock_photos_json(@casting_submission.files) %>"
|
||||||
|
data-placeholder="<%= dropzone_placeholder_message_for(@casting_submission) %>"
|
||||||
|
data-submit-button="#submit_folder"></div>
|
||||||
|
|
||||||
|
<div class="mt-5">
|
||||||
|
<%= form.button t(".update"), class: "btn btn-block btn-lg btn-success", data: { disable_with: t("shared.disable_with") } %>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row align-items-center justify-content-center mt-3">
|
||||||
|
<%= link_to "Start Interview", @casting_submission.zoom_meeting_url, target: "_blank", class: "btn btn-primary" %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
15
app/views/shared/_initiate_hubspot_chat.html.erb
Normal file
15
app/views/shared/_initiate_hubspot_chat.html.erb
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<% if params[:show_chat] %>
|
||||||
|
<%= javascript_include_tag "//js.hs-scripts.com/7344617.js", defer: "defer", async: true, id: "hs-script-loader" %>
|
||||||
|
<%= javascript_tag nonce: true do %>
|
||||||
|
function onConversationsAPIReady() {
|
||||||
|
window.HubSpotConversations.widget.load({ widgetOpen: true });
|
||||||
|
window.HubSpotConversations.widget.open();
|
||||||
|
}
|
||||||
|
if (window.HubSpotConversations) {
|
||||||
|
onConversationsAPIReady();
|
||||||
|
} else {
|
||||||
|
window.hsConversationsOnReady = [onConversationsAPIReady];
|
||||||
|
}
|
||||||
|
<% end %>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
@@ -1,15 +1,2 @@
|
|||||||
<% if params[:show_chat] %>
|
<%= render "shared/initiate_hubspot_chat" %>
|
||||||
<%= javascript_include_tag "//js.hs-scripts.com/7344617.js", defer: "defer", async: true, id: "hs-script-loader" %>
|
|
||||||
<%= javascript_tag nonce: true do %>
|
|
||||||
function onConversationsAPIReady() {
|
|
||||||
window.HubSpotConversations.widget.load({ widgetOpen: true });
|
|
||||||
window.HubSpotConversations.widget.open();
|
|
||||||
}
|
|
||||||
if (window.HubSpotConversations) {
|
|
||||||
onConversationsAPIReady();
|
|
||||||
} else {
|
|
||||||
window.hsConversationsOnReady = [onConversationsAPIReady];
|
|
||||||
}
|
|
||||||
<% end %>
|
|
||||||
<% end %>
|
|
||||||
<p class="alert alert-success p-3 lead text-center"><%= t '.success_message' %></p>
|
<p class="alert alert-success p-3 lead text-center"><%= t '.success_message' %></p>
|
||||||
@@ -70,6 +70,9 @@ en:
|
|||||||
person_phone: Phone
|
person_phone: Phone
|
||||||
person_photo: Photo
|
person_photo: Photo
|
||||||
signed_on: Date
|
signed_on: Date
|
||||||
|
casting_call:
|
||||||
|
interview_instructions: Welcome message
|
||||||
|
interview_requirements: Goodbye message
|
||||||
location_release:
|
location_release:
|
||||||
person_company: Company
|
person_company: Company
|
||||||
person_email: Email
|
person_email: Email
|
||||||
@@ -97,6 +100,22 @@ en:
|
|||||||
application:
|
application:
|
||||||
header:
|
header:
|
||||||
sign_out: Sign Out
|
sign_out: Sign Out
|
||||||
|
casting_submissions:
|
||||||
|
complete:
|
||||||
|
notice: The casting submission has been completed
|
||||||
|
create:
|
||||||
|
notice: The casting submission has been created
|
||||||
|
index:
|
||||||
|
actions:
|
||||||
|
new: Create Casting Submission
|
||||||
|
empty: Casting submissions will appear here
|
||||||
|
mark_as_completed:
|
||||||
|
alert: Failed to mark casting submission as completed
|
||||||
|
notice: The casting submission has been marked as completed
|
||||||
|
new:
|
||||||
|
heading: New Casting Submission
|
||||||
|
update:
|
||||||
|
notice: The casting submission has been updated
|
||||||
task_requests:
|
task_requests:
|
||||||
index:
|
index:
|
||||||
empty: Task requests will appear here
|
empty: Task requests will appear here
|
||||||
@@ -228,6 +247,42 @@ en:
|
|||||||
bulk_taggings:
|
bulk_taggings:
|
||||||
new_bulk_tag_modal:
|
new_bulk_tag_modal:
|
||||||
submit: Add
|
submit: Add
|
||||||
|
casting_calls:
|
||||||
|
cancel:
|
||||||
|
notice: The casting call request has been cancelled successfully
|
||||||
|
casting_call:
|
||||||
|
actions:
|
||||||
|
manage: Manage
|
||||||
|
create:
|
||||||
|
notice: The casting call request has been created successfully.
|
||||||
|
edit:
|
||||||
|
heading: Edit Casting Call
|
||||||
|
form:
|
||||||
|
headings:
|
||||||
|
chatbot: Chatbot Instructions
|
||||||
|
info_message: After submitting this casting call request, you'll be connected via chat with a ME Suite representative.
|
||||||
|
index:
|
||||||
|
actions:
|
||||||
|
new: Create Casting Call
|
||||||
|
empty: Casting calls will appear here
|
||||||
|
table_headers:
|
||||||
|
casting_call_created_on: Created On
|
||||||
|
casting_call_status: Status
|
||||||
|
casting_call_title: Casting Title
|
||||||
|
new:
|
||||||
|
heading: New Casting Call
|
||||||
|
update:
|
||||||
|
notice: The casting call request has been updated
|
||||||
|
casting_submission_downloads:
|
||||||
|
download:
|
||||||
|
failure: Your download could not be generated.
|
||||||
|
pending: "Your %{release_type} files are being prepared for download. You will be notified when it's ready."
|
||||||
|
success: "Your %{release_type} files are ready. Download now, or retrieve later in the %{downloads_folder_link} folder. %{download_button}"
|
||||||
|
casting_submissions:
|
||||||
|
index:
|
||||||
|
empty: Casting Submission results will appear here.
|
||||||
|
show:
|
||||||
|
empty: Casting Submission files and recorded meeetings will appear here.
|
||||||
contract_downloads:
|
contract_downloads:
|
||||||
download:
|
download:
|
||||||
failure: Your download could not be generated.
|
failure: Your download could not be generated.
|
||||||
@@ -361,6 +416,10 @@ en:
|
|||||||
notice: The release has been updated
|
notice: The release has been updated
|
||||||
helpers:
|
helpers:
|
||||||
help:
|
help:
|
||||||
|
casting_call:
|
||||||
|
interview_instructions: This is the first message the chatbot, BiGGiE, will send. Please include all information and instructions you wish the person to read prior to starting the casting interview.
|
||||||
|
interview_requirements: Please enter a final message and include any post-interview instructions (for example, submitting a headshot, additional photos, videos, etc).
|
||||||
|
questions: Please list, one-by-one, all of the questions you wish the chatbot, BiGGiE, to ask the person.
|
||||||
contract_template:
|
contract_template:
|
||||||
fee: Leave at $0.00 for no-fee
|
fee: Leave at $0.00 for no-fee
|
||||||
guardian_clause: Leave blank if not required for this contract
|
guardian_clause: Leave blank if not required for this contract
|
||||||
@@ -419,6 +478,13 @@ en:
|
|||||||
person_last_name: Last name
|
person_last_name: Last name
|
||||||
person_name: Name
|
person_name: Name
|
||||||
person_phone: Phone number
|
person_phone: Phone number
|
||||||
|
casting_call:
|
||||||
|
description: Casting search description
|
||||||
|
interview_instructions: Welcome message
|
||||||
|
interview_requirements: Goodbye message
|
||||||
|
project_description: Project description
|
||||||
|
questions: Questions
|
||||||
|
title: Casting search title
|
||||||
location_release:
|
location_release:
|
||||||
address_city: City
|
address_city: City
|
||||||
address_country: Country
|
address_country: Country
|
||||||
@@ -668,6 +734,8 @@ en:
|
|||||||
broadcast:
|
broadcast:
|
||||||
create: Create Live Stream
|
create: Create Live Stream
|
||||||
update: Save Changes
|
update: Save Changes
|
||||||
|
casting_submission:
|
||||||
|
create: Create Casting Submission
|
||||||
contract_template:
|
contract_template:
|
||||||
create: Create Release Template
|
create: Create Release Template
|
||||||
directory:
|
directory:
|
||||||
@@ -931,6 +999,7 @@ en:
|
|||||||
show:
|
show:
|
||||||
acquired_media_release: Acquired Media Releases (%{count})
|
acquired_media_release: Acquired Media Releases (%{count})
|
||||||
appearance_release: Appearance Releases (%{count})
|
appearance_release: Appearance Releases (%{count})
|
||||||
|
casting_submissions: Casting Submissions
|
||||||
downloads: Downloads
|
downloads: Downloads
|
||||||
location_release: Location Releases (%{count})
|
location_release: Location Releases (%{count})
|
||||||
material_release: Material Releases (%{count})
|
material_release: Material Releases (%{count})
|
||||||
@@ -993,6 +1062,12 @@ en:
|
|||||||
broadcasts:
|
broadcasts:
|
||||||
show:
|
show:
|
||||||
alert: That broadcast is no longer available
|
alert: That broadcast is no longer available
|
||||||
|
casting_submissions:
|
||||||
|
show:
|
||||||
|
heading: Files
|
||||||
|
update: Upload
|
||||||
|
update:
|
||||||
|
notice: Your files have been uploaded successfully
|
||||||
location_releases:
|
location_releases:
|
||||||
create:
|
create:
|
||||||
notice: Your release has been signed. Thank you!
|
notice: Your release has been signed. Thank you!
|
||||||
@@ -1169,6 +1244,7 @@ en:
|
|||||||
ago: ago
|
ago: ago
|
||||||
back: Back
|
back: Back
|
||||||
cancel: Cancel
|
cancel: Cancel
|
||||||
|
cast_me: Cast
|
||||||
clear: Clear
|
clear: Clear
|
||||||
close: Close
|
close: Close
|
||||||
csv: CSV
|
csv: CSV
|
||||||
|
|||||||
@@ -272,6 +272,8 @@ es:
|
|||||||
broadcast:
|
broadcast:
|
||||||
create: Create Live Stream (ES)
|
create: Create Live Stream (ES)
|
||||||
update: Save Changes (ES)
|
update: Save Changes (ES)
|
||||||
|
casting_submission:
|
||||||
|
create: Create casting submission (ES)
|
||||||
create: 'Crear %{model}'
|
create: 'Crear %{model}'
|
||||||
update: 'Actualizar %{model}'
|
update: 'Actualizar %{model}'
|
||||||
location_releases:
|
location_releases:
|
||||||
|
|||||||
@@ -32,6 +32,9 @@ Rails.application.routes.draw do
|
|||||||
resource :masquerade, only: :create
|
resource :masquerade, only: :create
|
||||||
end
|
end
|
||||||
resources :task_requests, only: [:index, :edit, :update, :show]
|
resources :task_requests, only: [:index, :edit, :update, :show]
|
||||||
|
resources :casting_submissions do
|
||||||
|
post :complete, on: :member
|
||||||
|
end
|
||||||
|
|
||||||
root to: "accounts#index", as: :signed_in_root
|
root to: "accounts#index", as: :signed_in_root
|
||||||
end
|
end
|
||||||
@@ -66,6 +69,7 @@ Rails.application.routes.draw do
|
|||||||
resource :contract_downloads, only: [:create]
|
resource :contract_downloads, only: [:create]
|
||||||
resources :downloads, only: [:index, :destroy]
|
resources :downloads, only: [:index, :destroy]
|
||||||
resource :report_downloads, only: [:create]
|
resource :report_downloads, only: [:create]
|
||||||
|
resource :casting_submission_downloads, only: [:create]
|
||||||
resources :videos, only: [:index, :new, :create, :edit, :update] do
|
resources :videos, only: [:index, :new, :create, :edit, :update] do
|
||||||
collection do
|
collection do
|
||||||
get :landing
|
get :landing
|
||||||
@@ -105,7 +109,13 @@ Rails.application.routes.draw do
|
|||||||
post :cancel
|
post :cancel
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
resources :casting_calls, except: :destroy do
|
||||||
|
member do
|
||||||
|
post :cancel
|
||||||
|
end
|
||||||
|
end
|
||||||
resources :tasks, only: :index
|
resources :tasks, only: :index
|
||||||
|
resources :casting_submissions, only: [:index, :show]
|
||||||
end
|
end
|
||||||
resource :profile, only: [:show, :update]
|
resource :profile, only: [:show, :update]
|
||||||
resources :videos, only: [] do
|
resources :videos, only: [] do
|
||||||
@@ -134,6 +144,8 @@ Rails.application.routes.draw do
|
|||||||
resources :broadcasts, param: :token, only: [:show, :update] do
|
resources :broadcasts, param: :token, only: [:show, :update] do
|
||||||
resource :zoom_meeting, only: [:show]
|
resource :zoom_meeting, only: [:show]
|
||||||
end
|
end
|
||||||
|
resources :casting_calls, param: :token, only: [:show]
|
||||||
|
resources :casting_submissions, param: :token, only: [:show, :update]
|
||||||
end
|
end
|
||||||
|
|
||||||
RELEASES = [:acquired_media_releases, :appearance_releases, :talent_releases, :material_releases, :location_releases]
|
RELEASES = [:acquired_media_releases, :appearance_releases, :talent_releases, :material_releases, :location_releases]
|
||||||
|
|||||||
17
db/migrate/20200626044744_create_casting_calls.rb
Normal file
17
db/migrate/20200626044744_create_casting_calls.rb
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
class CreateCastingCalls < ActiveRecord::Migration[6.0]
|
||||||
|
def change
|
||||||
|
create_table :casting_calls do |t|
|
||||||
|
t.references :project
|
||||||
|
t.string :title
|
||||||
|
t.string :user_email
|
||||||
|
t.text :description
|
||||||
|
t.text :project_description
|
||||||
|
t.text :interview_instructions
|
||||||
|
t.text :interview_requirements
|
||||||
|
t.text :questions
|
||||||
|
t.datetime :cancelled_at
|
||||||
|
|
||||||
|
t.timestamps
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
12
db/migrate/20200701121237_create_casting_call_interviews.rb
Normal file
12
db/migrate/20200701121237_create_casting_call_interviews.rb
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
class CreateCastingCallInterviews < ActiveRecord::Migration[6.0]
|
||||||
|
def change
|
||||||
|
create_table :casting_call_interviews do |t|
|
||||||
|
t.references :casting_call, foreign_key: true
|
||||||
|
t.string :performer_name
|
||||||
|
t.string :zoom_meeting_url
|
||||||
|
t.datetime :interview_date
|
||||||
|
|
||||||
|
t.timestamps
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
6
db/migrate/20200706193123_add_token_to_casting_calls.rb
Normal file
6
db/migrate/20200706193123_add_token_to_casting_calls.rb
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
class AddTokenToCastingCalls < ActiveRecord::Migration[6.0]
|
||||||
|
def change
|
||||||
|
add_column :casting_calls, :token, :string
|
||||||
|
add_index :casting_calls, :token, unique: true
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
class AddTokenToCastingCallInterviews < ActiveRecord::Migration[6.0]
|
||||||
|
def change
|
||||||
|
add_column :casting_call_interviews, :token, :string
|
||||||
|
add_index :casting_call_interviews, :token, unique: true
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
class AddInterviewedAtToCastingCallInterview < ActiveRecord::Migration[6.0]
|
||||||
|
def change
|
||||||
|
add_column :casting_call_interviews, :interviewed_at, :datetime
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
class RenameCastingCallInterviewsToCastingSubmissions < ActiveRecord::Migration[6.0]
|
||||||
|
def change
|
||||||
|
rename_table :casting_call_interviews, :casting_submissions
|
||||||
|
end
|
||||||
|
end
|
||||||
150
db/structure.sql
150
db/structure.sql
@@ -555,6 +555,82 @@ CREATE SEQUENCE public.broadcasts_id_seq
|
|||||||
ALTER SEQUENCE public.broadcasts_id_seq OWNED BY public.broadcasts.id;
|
ALTER SEQUENCE public.broadcasts_id_seq OWNED BY public.broadcasts.id;
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: casting_calls; Type: TABLE; Schema: public; Owner: -
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE TABLE public.casting_calls (
|
||||||
|
id bigint NOT NULL,
|
||||||
|
project_id bigint,
|
||||||
|
title character varying,
|
||||||
|
user_email character varying,
|
||||||
|
description text,
|
||||||
|
project_description text,
|
||||||
|
interview_instructions text,
|
||||||
|
interview_requirements text,
|
||||||
|
questions text,
|
||||||
|
cancelled_at timestamp without time zone,
|
||||||
|
created_at timestamp(6) without time zone NOT NULL,
|
||||||
|
updated_at timestamp(6) without time zone NOT NULL,
|
||||||
|
token character varying
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: casting_calls_id_seq; Type: SEQUENCE; Schema: public; Owner: -
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE SEQUENCE public.casting_calls_id_seq
|
||||||
|
START WITH 1
|
||||||
|
INCREMENT BY 1
|
||||||
|
NO MINVALUE
|
||||||
|
NO MAXVALUE
|
||||||
|
CACHE 1;
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: casting_calls_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
|
||||||
|
--
|
||||||
|
|
||||||
|
ALTER SEQUENCE public.casting_calls_id_seq OWNED BY public.casting_calls.id;
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: casting_submissions; Type: TABLE; Schema: public; Owner: -
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE TABLE public.casting_submissions (
|
||||||
|
id bigint NOT NULL,
|
||||||
|
casting_call_id bigint,
|
||||||
|
performer_name character varying,
|
||||||
|
zoom_meeting_url character varying,
|
||||||
|
interview_date timestamp without time zone,
|
||||||
|
created_at timestamp(6) without time zone NOT NULL,
|
||||||
|
updated_at timestamp(6) without time zone NOT NULL,
|
||||||
|
token character varying,
|
||||||
|
interviewed_at timestamp without time zone
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: casting_submissions_id_seq; Type: SEQUENCE; Schema: public; Owner: -
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE SEQUENCE public.casting_submissions_id_seq
|
||||||
|
START WITH 1
|
||||||
|
INCREMENT BY 1
|
||||||
|
NO MINVALUE
|
||||||
|
NO MAXVALUE
|
||||||
|
CACHE 1;
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: casting_submissions_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
|
||||||
|
--
|
||||||
|
|
||||||
|
ALTER SEQUENCE public.casting_submissions_id_seq OWNED BY public.casting_submissions.id;
|
||||||
|
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Name: composers; Type: TABLE; Schema: public; Owner: -
|
-- Name: composers; Type: TABLE; Schema: public; Owner: -
|
||||||
--
|
--
|
||||||
@@ -1963,6 +2039,20 @@ ALTER TABLE ONLY public.broadcast_recordings ALTER COLUMN id SET DEFAULT nextval
|
|||||||
ALTER TABLE ONLY public.broadcasts ALTER COLUMN id SET DEFAULT nextval('public.broadcasts_id_seq'::regclass);
|
ALTER TABLE ONLY public.broadcasts ALTER COLUMN id SET DEFAULT nextval('public.broadcasts_id_seq'::regclass);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: casting_calls id; Type: DEFAULT; Schema: public; Owner: -
|
||||||
|
--
|
||||||
|
|
||||||
|
ALTER TABLE ONLY public.casting_calls ALTER COLUMN id SET DEFAULT nextval('public.casting_calls_id_seq'::regclass);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: casting_submissions id; Type: DEFAULT; Schema: public; Owner: -
|
||||||
|
--
|
||||||
|
|
||||||
|
ALTER TABLE ONLY public.casting_submissions ALTER COLUMN id SET DEFAULT nextval('public.casting_submissions_id_seq'::regclass);
|
||||||
|
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Name: composers id; Type: DEFAULT; Schema: public; Owner: -
|
-- Name: composers id; Type: DEFAULT; Schema: public; Owner: -
|
||||||
--
|
--
|
||||||
@@ -2284,6 +2374,22 @@ ALTER TABLE ONLY public.broadcasts
|
|||||||
ADD CONSTRAINT broadcasts_pkey PRIMARY KEY (id);
|
ADD CONSTRAINT broadcasts_pkey PRIMARY KEY (id);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: casting_calls casting_calls_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||||
|
--
|
||||||
|
|
||||||
|
ALTER TABLE ONLY public.casting_calls
|
||||||
|
ADD CONSTRAINT casting_calls_pkey PRIMARY KEY (id);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: casting_submissions casting_submissions_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||||
|
--
|
||||||
|
|
||||||
|
ALTER TABLE ONLY public.casting_submissions
|
||||||
|
ADD CONSTRAINT casting_submissions_pkey PRIMARY KEY (id);
|
||||||
|
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Name: composers composers_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
-- Name: composers composers_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||||
--
|
--
|
||||||
@@ -2701,6 +2807,34 @@ CREATE INDEX index_broadcasts_on_project_id ON public.broadcasts USING btree (pr
|
|||||||
CREATE UNIQUE INDEX index_broadcasts_on_token ON public.broadcasts USING btree (token);
|
CREATE UNIQUE INDEX index_broadcasts_on_token ON public.broadcasts USING btree (token);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: index_casting_calls_on_project_id; Type: INDEX; Schema: public; Owner: -
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE INDEX index_casting_calls_on_project_id ON public.casting_calls USING btree (project_id);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: index_casting_calls_on_token; Type: INDEX; Schema: public; Owner: -
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE UNIQUE INDEX index_casting_calls_on_token ON public.casting_calls USING btree (token);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: index_casting_submissions_on_casting_call_id; Type: INDEX; Schema: public; Owner: -
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE INDEX index_casting_submissions_on_casting_call_id ON public.casting_submissions USING btree (casting_call_id);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: index_casting_submissions_on_token; Type: INDEX; Schema: public; Owner: -
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE UNIQUE INDEX index_casting_submissions_on_token ON public.casting_submissions USING btree (token);
|
||||||
|
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Name: index_composers_on_music_release_id; Type: INDEX; Schema: public; Owner: -
|
-- Name: index_composers_on_music_release_id; Type: INDEX; Schema: public; Owner: -
|
||||||
--
|
--
|
||||||
@@ -3298,6 +3432,14 @@ ALTER TABLE ONLY public.bookmarks
|
|||||||
ADD CONSTRAINT fk_rails_15735b7db8 FOREIGN KEY (video_id) REFERENCES public.videos(id);
|
ADD CONSTRAINT fk_rails_15735b7db8 FOREIGN KEY (video_id) REFERENCES public.videos(id);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: casting_submissions fk_rails_1583f69fbb; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||||
|
--
|
||||||
|
|
||||||
|
ALTER TABLE ONLY public.casting_submissions
|
||||||
|
ADD CONSTRAINT fk_rails_1583f69fbb FOREIGN KEY (casting_call_id) REFERENCES public.casting_calls(id);
|
||||||
|
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Name: acquired_media_releases fk_rails_15b450b040; Type: FK CONSTRAINT; Schema: public; Owner: -
|
-- Name: acquired_media_releases fk_rails_15b450b040; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||||
--
|
--
|
||||||
@@ -3902,6 +4044,12 @@ INSERT INTO "schema_migrations" (version) VALUES
|
|||||||
('20200619134853'),
|
('20200619134853'),
|
||||||
('20200622180507'),
|
('20200622180507'),
|
||||||
('20200625144713'),
|
('20200625144713'),
|
||||||
('20200702152130');
|
('20200626044744'),
|
||||||
|
('20200701121237'),
|
||||||
|
('20200702152130'),
|
||||||
|
('20200706193123'),
|
||||||
|
('20200706230803'),
|
||||||
|
('20200707070522'),
|
||||||
|
('20200714175331');
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -54,14 +54,16 @@ RSpec.describe AccountsController, type: :controller do
|
|||||||
end
|
end
|
||||||
|
|
||||||
it "enqueues hubspot form submission job" do
|
it "enqueues hubspot form submission job" do
|
||||||
|
ENV["HUBSPOT_FORM_GUID"] = "form_guid"
|
||||||
expect {
|
expect {
|
||||||
post :create, params: params
|
post :create, params: params
|
||||||
}.to have_enqueued_job(SubmitHubspotFormJob).with(
|
}.to have_enqueued_job(SubmitHubspotFormJob).with(
|
||||||
"John",
|
first_name: "John",
|
||||||
"Doe",
|
last_name: "Doe",
|
||||||
"test_user+1@test.com",
|
email: "test_user+1@test.com",
|
||||||
"Test Dev account",
|
company: "Test Dev account",
|
||||||
i_m_interested_in: "DirectME"
|
i_m_interested_in: "DirectME",
|
||||||
|
form_guid: "form_guid"
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
114
spec/controllers/admin/casting_submissions_controller_spec.rb
Normal file
114
spec/controllers/admin/casting_submissions_controller_spec.rb
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
require "rails_helper"
|
||||||
|
|
||||||
|
RSpec.describe Admin::CastingSubmissionsController, type: :controller do
|
||||||
|
|
||||||
|
let!(:current_user) { create(:user, :admin) }
|
||||||
|
|
||||||
|
before do
|
||||||
|
sign_in(current_user)
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#index" do
|
||||||
|
it "returns a successful response" do
|
||||||
|
get :index
|
||||||
|
|
||||||
|
expect(response).to be_successful
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#new" do
|
||||||
|
it "returns a successful response" do
|
||||||
|
get :new
|
||||||
|
|
||||||
|
expect(response).to be_successful
|
||||||
|
end
|
||||||
|
|
||||||
|
it "assigns user, accounts" do
|
||||||
|
get :new
|
||||||
|
|
||||||
|
expect(assigns(:casting_submission)).not_to be_nil
|
||||||
|
expect(assigns(:accounts)).to eq Account.all
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#create" do
|
||||||
|
it "does create a new record" do
|
||||||
|
expect {
|
||||||
|
post :create, params: { casting_submission: casting_submission_params }
|
||||||
|
}.to change(CastingSubmission, :count)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#edit" do
|
||||||
|
let(:casting_submission) { create(:casting_submission) }
|
||||||
|
|
||||||
|
it "returns a successful response" do
|
||||||
|
get :edit, params: { id: casting_submission }
|
||||||
|
|
||||||
|
expect(response).to be_successful
|
||||||
|
end
|
||||||
|
|
||||||
|
it "assigns casting submission" do
|
||||||
|
get :edit, params: { id: casting_submission }
|
||||||
|
|
||||||
|
expect(assigns(:casting_submission)).to eq casting_submission
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#update" do
|
||||||
|
let(:casting_submission) { create(:casting_submission) }
|
||||||
|
|
||||||
|
it "redirects to casting submissions page" do
|
||||||
|
patch :update, params: { id: casting_submission, casting_submission: update_params }
|
||||||
|
|
||||||
|
expect(response).to be_redirect
|
||||||
|
expect(response).to redirect_to admin_casting_submissions_path
|
||||||
|
end
|
||||||
|
|
||||||
|
it "sets a flash notice" do
|
||||||
|
patch :update, params: { id: casting_submission, casting_submission: update_params }
|
||||||
|
|
||||||
|
expect(flash.notice).to eq "The casting submission has been updated"
|
||||||
|
end
|
||||||
|
|
||||||
|
it "updates casting submission" do
|
||||||
|
patch :update, params: { id: casting_submission, casting_submission: update_params }
|
||||||
|
|
||||||
|
expect(casting_submission.reload.zoom_meeting_url).to eq new_zoom_meeting_url
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#complete" do
|
||||||
|
let(:casting_submission) { create(:casting_submission) }
|
||||||
|
|
||||||
|
it "sets interviewed_at on casting submission" do
|
||||||
|
expect(casting_submission.interviewed_at).to be_nil
|
||||||
|
|
||||||
|
post :complete, params: { id: casting_submission }
|
||||||
|
|
||||||
|
expect(casting_submission.reload.interviewed_at).not_to be_nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def casting_submission_params
|
||||||
|
casting_call = create(:casting_call)
|
||||||
|
|
||||||
|
attributes_for(:casting_submission).except(:interviewed_at).merge(casting_call_id: casting_call.id)
|
||||||
|
end
|
||||||
|
|
||||||
|
def update_params
|
||||||
|
{
|
||||||
|
zoom_meeting_url: new_zoom_meeting_url
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
def new_zoom_meeting_url
|
||||||
|
"https://s01web.zoom.us/j/11111?pwd=Ab123Cq34"
|
||||||
|
end
|
||||||
|
|
||||||
|
def invalid_meeting_url_flash_error
|
||||||
|
t 'casting_submissions.validation_errors.invalid_meeting_url'
|
||||||
|
end
|
||||||
|
end
|
||||||
120
spec/controllers/casting_calls_controller_spec.rb
Normal file
120
spec/controllers/casting_calls_controller_spec.rb
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
RSpec.describe CastingCallsController, type: :controller do
|
||||||
|
render_views
|
||||||
|
|
||||||
|
let(:user) { create(:user) }
|
||||||
|
let(:account) { user.primary_account }
|
||||||
|
let(:project) { create(:project, account: user.primary_account) }
|
||||||
|
|
||||||
|
before do
|
||||||
|
sign_in user
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#index" do
|
||||||
|
it "responds successfully" do
|
||||||
|
get :index, params: { project_id: project }
|
||||||
|
|
||||||
|
expect(response).to be_successful
|
||||||
|
end
|
||||||
|
|
||||||
|
it "renders content" do
|
||||||
|
create(:casting_call, project: project)
|
||||||
|
|
||||||
|
get :index, params: { project_id: project }
|
||||||
|
|
||||||
|
expect(response.body).to have_link "Create Casting Call"
|
||||||
|
expect(response.body).to have_content "Active"
|
||||||
|
end
|
||||||
|
|
||||||
|
context "when there are many records" do
|
||||||
|
it "paginates the table" do
|
||||||
|
create_list(:casting_call, 20, project: project)
|
||||||
|
|
||||||
|
get :index, params: { project_id: project }
|
||||||
|
|
||||||
|
expect(response.body).to have_link("2", href: project_casting_calls_path(project, page: 2))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#new" do
|
||||||
|
it "responds successfully" do
|
||||||
|
get :new, params: { project_id: project }
|
||||||
|
|
||||||
|
expect(response).to be_successful
|
||||||
|
expect(assigns(:casting_call)).to be_a_new(CastingCall)
|
||||||
|
expect(response).to render_template(:new)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#create" do
|
||||||
|
it "does create a new record" do
|
||||||
|
expect {
|
||||||
|
post :create, params: { project_id: project.id, casting_call: casting_call_params }
|
||||||
|
}.to change(CastingCall, :count)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "logs an event" do
|
||||||
|
expect {
|
||||||
|
post :create, params: { project_id: project.id, casting_call: casting_call_params }
|
||||||
|
}.to have_enqueued_job(TrackAnalyticsJob).with(user, account, :track_create_casting_call, user_agent: "Rails Testing", user_ip: "0.0.0.0")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#update" do
|
||||||
|
let!(:casting_call) { create(:casting_call, project: project, description: "My description" ) }
|
||||||
|
|
||||||
|
it "updates casting call request" do
|
||||||
|
patch :update, params: { project_id: project.id, id: casting_call.id, casting_call: update_params }
|
||||||
|
|
||||||
|
expect(casting_call.reload.description).to eq("This is updated description")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#show" do
|
||||||
|
let!(:casting_call) { create(:casting_call, project: project, description: "Casting Call Request") }
|
||||||
|
|
||||||
|
it "responds successfully" do
|
||||||
|
get :show, params: { project_id: project.id, id: casting_call.id }
|
||||||
|
|
||||||
|
expect(response).to be_successful
|
||||||
|
expect(assigns(:casting_call)).to eq(casting_call)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "renders content" do
|
||||||
|
get :show, params: { project_id: project.id, id: casting_call.id }
|
||||||
|
|
||||||
|
expect(response.body).to have_content "Casting Call Request"
|
||||||
|
expect(response.body).to have_content "Active"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#cancel" do
|
||||||
|
let!(:casting_call) { create(:casting_call, project: project, description: "Casting Call to be Cancelled") }
|
||||||
|
|
||||||
|
it "responds with redirect" do
|
||||||
|
post :cancel, params: { project_id: project.id, id: casting_call.id }
|
||||||
|
|
||||||
|
expect(response).to be_redirect
|
||||||
|
expect(response).to redirect_to(project_casting_calls_path(project))
|
||||||
|
expect(flash.notice).not_to be_nil
|
||||||
|
end
|
||||||
|
|
||||||
|
it "updates the status to 'Cancelled'" do
|
||||||
|
expect {
|
||||||
|
post :cancel, params: { project_id: project.id, id: casting_call.id }
|
||||||
|
}.to change { casting_call.reload.status }.from("Active").to("Cancelled")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def casting_call_params
|
||||||
|
attributes_for(:casting_call).except(:status, :user_email)
|
||||||
|
end
|
||||||
|
|
||||||
|
def update_params
|
||||||
|
{ description: "This is updated description" }
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
require "rails_helper"
|
||||||
|
|
||||||
|
RSpec.describe CastingSubmissionDownloadsController, type: :controller do
|
||||||
|
render_views
|
||||||
|
|
||||||
|
let(:current_user) { create(:user) }
|
||||||
|
let(:project) { create(:project, :discovery_client, account: current_user.primary_account) }
|
||||||
|
let(:casting_call) { create(:casting_call, project: project, title: "My Title") }
|
||||||
|
let(:casting_submission) { create(:casting_submission, casting_call: casting_call, performer_name: "John Doe") }
|
||||||
|
|
||||||
|
before do
|
||||||
|
sign_in current_user
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#create" do
|
||||||
|
it "enqueues zip file generation job" do
|
||||||
|
expect {
|
||||||
|
post :create, params: { project_id: project.id, casting_submission_id: casting_submission.id }, format: :js
|
||||||
|
}.to have_enqueued_job(GenerateCastingSubmissionFilesZipJob)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "creates a download record with 'not_started' status" do
|
||||||
|
expect {
|
||||||
|
post :create, params: { project_id: project.id, casting_submission_id: casting_submission.id }, format: :js
|
||||||
|
}.to change(Download, :count).by(1)
|
||||||
|
|
||||||
|
expect(Download.last.status).to eq('not_started')
|
||||||
|
end
|
||||||
|
|
||||||
|
context "When there is no existing job" do
|
||||||
|
it "shows a notification to user" do
|
||||||
|
allow(ProjectsChannel).to receive(:broadcast_download_generation_update).with(be_kind_of(Download), I18n.t("casting_submission_downloads.download.pending", release_type: "CastingSubmission"))
|
||||||
|
|
||||||
|
post :create, params: { project_id: project.id, casting_submission_id: casting_submission.id }, format: :js
|
||||||
|
|
||||||
|
expect(ProjectsChannel).to have_received(:broadcast_download_generation_update).with(be_kind_of(Download), I18n.t("casting_submission_downloads.download.pending", release_type: "CastingSubmission"))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "When there are existing jobs" do
|
||||||
|
let(:appearance_release_download) { create(:download, project_id: project.id, name: "#{project.name.parameterize}_appearance-releases") }
|
||||||
|
let(:acquired_media_release_download) { create(:download, project_id: project.id, name: "#{project.name.parameterize}_acquired-media-releases", release_type: "AcquiredMediaRelease") }
|
||||||
|
|
||||||
|
before do
|
||||||
|
allow(Download).to receive_message_chain(:unfinished_desc_order, :offset).and_return([acquired_media_release_download, appearance_release_download])
|
||||||
|
allow(ProjectsChannel).to receive(:broadcast_download_generation_update)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "shows names of other contracts in the notification, which are in progress" do
|
||||||
|
broadcast_message = "<p>Your Casting Submission files are being prepared for download. You will be notified when it's ready.\n</p>\n<p class=\"mt-3\">The following downloads are also in progress:</p> \n<ul>\n <li>Acquired Media Release contracts (as of less than a minute ago)\n </li>\n <li>Appearance Release contracts (as of less than a minute ago)\n </li>\n</ul>\n"
|
||||||
|
|
||||||
|
post :create, params: { project_id: project.id, casting_submission_id: casting_submission.id }, format: :js
|
||||||
|
|
||||||
|
expect(ProjectsChannel).to have_received(:broadcast_download_generation_update).with(be_kind_of(Download), broadcast_message)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
44
spec/controllers/casting_submissions_controller_spec.rb
Normal file
44
spec/controllers/casting_submissions_controller_spec.rb
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
require "rails_helper"
|
||||||
|
|
||||||
|
RSpec.describe CastingSubmissionsController, type: :controller do
|
||||||
|
render_views
|
||||||
|
|
||||||
|
let(:user) { create(:user) }
|
||||||
|
let(:account) { user.primary_account }
|
||||||
|
let(:project) { create(:project, account: user.primary_account) }
|
||||||
|
let(:casting_call) { create(:casting_call, project: project, title: "My Interview") }
|
||||||
|
|
||||||
|
before do
|
||||||
|
sign_in(user)
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#index" do
|
||||||
|
it "returns a successful response" do
|
||||||
|
get :index, params: { project_id: project }
|
||||||
|
|
||||||
|
expect(response).to be_successful
|
||||||
|
end
|
||||||
|
|
||||||
|
it "only shows completed submissions" do
|
||||||
|
create(:casting_submission, casting_call: casting_call, interviewed_at: Time.zone.now, performer_name: "John Doe")
|
||||||
|
create(:casting_submission, casting_call: casting_call, interviewed_at: nil, performer_name: "Jane Doe")
|
||||||
|
|
||||||
|
get :index, params: { project_id: project }
|
||||||
|
|
||||||
|
expect(response.body).to have_content("John Doe")
|
||||||
|
expect(response.body).not_to have_content("Jane Doe")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#show" do
|
||||||
|
let!(:casting_submission) { create(:casting_submission, :with_files, casting_call: casting_call, interviewed_at: Time.zone.now, performer_name: "Jane Doe") }
|
||||||
|
|
||||||
|
it "shows files of casting submission" do
|
||||||
|
get :show, params: { project_id: project, id: casting_submission.id }
|
||||||
|
|
||||||
|
expect(response.body).to have_content(casting_submission.performer_name)
|
||||||
|
expect(response.body).to have_content(casting_submission.casting_call.title)
|
||||||
|
expect(response.body).to have_content(casting_submission.casting_call.project_description)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
25
spec/controllers/public/casting_calls_controller_spec.rb
Normal file
25
spec/controllers/public/casting_calls_controller_spec.rb
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
RSpec.describe Public::CastingCallsController, type: :controller do
|
||||||
|
render_views
|
||||||
|
|
||||||
|
describe "#show" do
|
||||||
|
let(:casting_call) { create(:casting_call) }
|
||||||
|
|
||||||
|
it "responds successfully" do
|
||||||
|
get :show, params: { token: casting_call.token }
|
||||||
|
|
||||||
|
expect(response).to be_successful
|
||||||
|
expect(assigns(:casting_call)).to eq(casting_call)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "shows casting call details" do
|
||||||
|
get :show, params: { token: casting_call.token }
|
||||||
|
|
||||||
|
expect(response.body).to have_content(casting_call.title)
|
||||||
|
expect(response.body).to have_content(casting_call.description)
|
||||||
|
expect(response.body).to have_content(casting_call.project_description)
|
||||||
|
expect(response.body).to have_link("Schedule an Audition")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
44
spec/controllers/public/casting_submissions_controller.rb
Normal file
44
spec/controllers/public/casting_submissions_controller.rb
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
RSpec.describe Public::CastingSubmissionsController, type: :controller do
|
||||||
|
render_views
|
||||||
|
|
||||||
|
describe "#show" do
|
||||||
|
let(:casting_submission) { create(:casting_submission) }
|
||||||
|
|
||||||
|
it "responds successfully" do
|
||||||
|
get :show, params: { token: casting_submission.token }
|
||||||
|
|
||||||
|
expect(response).to be_successful
|
||||||
|
expect(assigns(:casting_submission)).to eq(casting_submission)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "shows casting call interview details" do
|
||||||
|
get :show, params: { token: casting_submission.token }
|
||||||
|
|
||||||
|
expect(response.body).to have_content(casting_submission.performer_name)
|
||||||
|
expect(response.body).to have_content(casting_submission.interview_date)
|
||||||
|
expect(response.body).to have_link("Start Interview")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "#update" do
|
||||||
|
let(:casting_submission) { create(:casting_submission) }
|
||||||
|
|
||||||
|
it "responds successfully" do
|
||||||
|
patch :update, params: { token: casting_submission.token, casting_submission: casting_submission_params }
|
||||||
|
|
||||||
|
expect(response).to redirect_to casting_submission_url(token: casting_submission.token)
|
||||||
|
expect(flash.notice).to be_present
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def casting_submission_params
|
||||||
|
path = Rails.root.join("spec", "fixtures", "files", "contract.pdf")
|
||||||
|
file = Rack::Test::UploadedFile.new(path, "application/pdf")
|
||||||
|
|
||||||
|
{ files: [file]}
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -71,7 +71,7 @@ RSpec.describe TaskRequestsController, type: :controller do
|
|||||||
it "submits data to hubspot form" do
|
it "submits data to hubspot form" do
|
||||||
expect {
|
expect {
|
||||||
post :create, params: { project_id: project.id, task_request: task_request_params }
|
post :create, params: { project_id: project.id, task_request: task_request_params }
|
||||||
}.to have_enqueued_job(SubmitHubspotTaskRequestFormJob)
|
}.to have_enqueued_job(SubmitHubspotFormJob)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
16
spec/factories/casting_calls.rb
Normal file
16
spec/factories/casting_calls.rb
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
FactoryBot.define do
|
||||||
|
factory :casting_call do
|
||||||
|
association :project
|
||||||
|
user_email 'test@email.com'
|
||||||
|
title 'Casting Call Title'
|
||||||
|
description "Casting call description"
|
||||||
|
project_description "Casting call project description"
|
||||||
|
interview_instructions "Interview instructions"
|
||||||
|
interview_requirements "Interview requirements"
|
||||||
|
questions "Questions"
|
||||||
|
|
||||||
|
trait :cancelled do
|
||||||
|
cancelled_at { Time.zone.now }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
17
spec/factories/casting_submissions.rb
Normal file
17
spec/factories/casting_submissions.rb
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
FactoryBot.define do
|
||||||
|
factory :casting_submission do
|
||||||
|
association :casting_call
|
||||||
|
performer_name 'John Doe'
|
||||||
|
zoom_meeting_url 'https://us04web.zoom.us/j/1111111111?pwd=aDZCS1dzZ2lWdDZJcHBhVnNIclB4QT03'
|
||||||
|
interview_date { 10.days.from_now }
|
||||||
|
interviewed_at { nil }
|
||||||
|
|
||||||
|
trait :with_files do
|
||||||
|
files { [Rack::Test::UploadedFile.new('spec/fixtures/files/location_photo.png', 'image/png')] }
|
||||||
|
end
|
||||||
|
|
||||||
|
trait :with_interview_recording do
|
||||||
|
interview_recording { Rack::Test::UploadedFile.new('spec/fixtures/files/video_file.mp4', 'video/mp4') }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
129
spec/features/admin_managing_casting_submissions_spec.rb
Normal file
129
spec/features/admin_managing_casting_submissions_spec.rb
Normal file
@@ -0,0 +1,129 @@
|
|||||||
|
require "rails_helper"
|
||||||
|
|
||||||
|
feature "Admin managing casting submissions" do
|
||||||
|
let(:current_user) { create(:user, admin: true, email: "user@test.com") }
|
||||||
|
let(:project) { create(:project, account: current_user.primary_account, name: "Test Project") }
|
||||||
|
|
||||||
|
before do
|
||||||
|
sign_in current_user
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario "when creating new casting call interview - interview recording field is not visible" do
|
||||||
|
visit admin_casting_submissions_path
|
||||||
|
|
||||||
|
click_on create_casting_submission_button
|
||||||
|
|
||||||
|
expect(page).to have_content new_casting_submission_heading
|
||||||
|
expect(page).not_to have_field interview_recording_field
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario "admin can upload interview recording video when editing casting call interview" do
|
||||||
|
cc = create(:casting_call)
|
||||||
|
cci = create(:casting_submission, casting_call: cc)
|
||||||
|
|
||||||
|
expect(CastingSubmission.last.interview_recording).not_to be_attached
|
||||||
|
|
||||||
|
visit edit_admin_casting_submission_path(cci)
|
||||||
|
|
||||||
|
expect(page).to have_content edit_casting_submission_heading
|
||||||
|
expect(page).to have_field interview_recording_field
|
||||||
|
expect(page).not_to have_content current_interview_recording_label
|
||||||
|
attach_file interview_recording_field, Rails.root.join(file_fixture('video_file.mp4'))
|
||||||
|
click_on update_casting_submission_button
|
||||||
|
expect(page).to have_content casting_submission_updated_message
|
||||||
|
expect(CastingSubmission.last.interview_recording).to be_attached
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario "when editing casting call interview with already uploaded interview video, interview recording file name link is shown below file field" do
|
||||||
|
cc = create(:casting_call)
|
||||||
|
cci = create(:casting_submission, :with_interview_recording, casting_call: cc)
|
||||||
|
|
||||||
|
expect(CastingSubmission.last.interview_recording).to be_attached
|
||||||
|
|
||||||
|
visit edit_admin_casting_submission_path(cci)
|
||||||
|
|
||||||
|
expect(page).to have_content edit_casting_submission_heading
|
||||||
|
expect(page).to have_content current_interview_recording_label
|
||||||
|
expect(page).to have_link CastingSubmission.last.interview_recording.attachment.blob.filename.to_s
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario "when admin opens view page for casting submission, it does not fail if zoom meeting URL is invalid" do
|
||||||
|
cc = create(:casting_call)
|
||||||
|
cci = create(:casting_submission, casting_call: cc, zoom_meeting_url: "anything")
|
||||||
|
|
||||||
|
visit admin_casting_submissions_path
|
||||||
|
|
||||||
|
click_on manage_button
|
||||||
|
click_link view_link
|
||||||
|
|
||||||
|
expect(page).to have_content casting_submission_details_header
|
||||||
|
expect(page).to have_content interview_files_label
|
||||||
|
expect(page).to have_content cci.performer_name
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def create_casting_submission_button
|
||||||
|
t 'admin.casting_submissions.index.actions.new'
|
||||||
|
end
|
||||||
|
|
||||||
|
def new_casting_submission_heading
|
||||||
|
t 'admin.casting_submissions.new.heading'
|
||||||
|
end
|
||||||
|
|
||||||
|
def edit_casting_submission_heading
|
||||||
|
'Edit Casting Submission'
|
||||||
|
end
|
||||||
|
|
||||||
|
def update_casting_submission_button
|
||||||
|
'Update Casting submission'
|
||||||
|
end
|
||||||
|
|
||||||
|
def submit_casting_submission_form
|
||||||
|
t 'helpers.submit.casting_submission.create'
|
||||||
|
end
|
||||||
|
|
||||||
|
def zoom_meeting_url_invalid_error
|
||||||
|
t 'casting_submissions.validation_errors.invalid_meeting_url'
|
||||||
|
end
|
||||||
|
|
||||||
|
def performer_name_field
|
||||||
|
'casting_submission[performer_name]'
|
||||||
|
end
|
||||||
|
|
||||||
|
def zoom_meeting_url_field
|
||||||
|
'casting_submission[zoom_meeting_url]'
|
||||||
|
end
|
||||||
|
|
||||||
|
def casting_call_field
|
||||||
|
'casting_submission[casting_call_id]'
|
||||||
|
end
|
||||||
|
|
||||||
|
def casting_submission_updated_message
|
||||||
|
t 'admin.casting_submissions.update.notice'
|
||||||
|
end
|
||||||
|
|
||||||
|
def interview_recording_field
|
||||||
|
'casting_submission[interview_recording]'
|
||||||
|
end
|
||||||
|
|
||||||
|
def current_interview_recording_label
|
||||||
|
'Current interview recording'
|
||||||
|
end
|
||||||
|
|
||||||
|
def manage_button
|
||||||
|
'Manage'
|
||||||
|
end
|
||||||
|
|
||||||
|
def view_link
|
||||||
|
'View'
|
||||||
|
end
|
||||||
|
|
||||||
|
def casting_submission_details_header
|
||||||
|
'Casting submission details'
|
||||||
|
end
|
||||||
|
|
||||||
|
def interview_files_label
|
||||||
|
'INTERVIEW FILES:'
|
||||||
|
end
|
||||||
|
end
|
||||||
155
spec/features/user_managing_casting_calls_spec.rb
Normal file
155
spec/features/user_managing_casting_calls_spec.rb
Normal file
@@ -0,0 +1,155 @@
|
|||||||
|
require "rails_helper"
|
||||||
|
|
||||||
|
feature "User managing casting calls" do
|
||||||
|
let(:current_user) { create(:user) }
|
||||||
|
let(:project) { create(:project, account: current_user.primary_account) }
|
||||||
|
|
||||||
|
before :each do
|
||||||
|
sign_in current_user
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario "casting calls table is visible" do
|
||||||
|
visit project_casting_calls_path(project)
|
||||||
|
|
||||||
|
expect(page).to have_content "Created On"
|
||||||
|
expect(page).to have_content "Title"
|
||||||
|
expect(page).to have_content "Status"
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario "sees list of casting calls" do
|
||||||
|
visit project_casting_calls_path(project)
|
||||||
|
|
||||||
|
expect(page).to have_content no_casting_calls_label
|
||||||
|
|
||||||
|
casting_call = create(:casting_call, project: project)
|
||||||
|
|
||||||
|
visit project_casting_calls_path(project)
|
||||||
|
|
||||||
|
expect(page).not_to have_content no_casting_calls_label
|
||||||
|
|
||||||
|
expect(page).to have_content casting_call.created_at.try(:strftime, '%D')
|
||||||
|
expect(page).to have_content casting_call.title
|
||||||
|
expect(page).to have_content casting_call.status
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario "can create casting call requests" do
|
||||||
|
visit project_casting_calls_path(project)
|
||||||
|
|
||||||
|
expect(page).to have_content no_casting_calls_label
|
||||||
|
click_on add_new_casting_call_label
|
||||||
|
|
||||||
|
fill_in title_field, with: "Casting Title"
|
||||||
|
fill_in description_field, with: "Description"
|
||||||
|
fill_in project_description_field, with: "Project Description"
|
||||||
|
fill_in interview_instructions_field, with: "Welcome Message"
|
||||||
|
fill_in interview_requirements_field, with: "Goodbye Message"
|
||||||
|
fill_in questions_field, with: "Questions"
|
||||||
|
|
||||||
|
click_on "Create Casting call"
|
||||||
|
|
||||||
|
expect(page).to have_content("The casting call request has been created successfully.")
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario "can update casting call requests" do
|
||||||
|
create(:casting_call, title: "Title", project: project)
|
||||||
|
visit project_casting_calls_path(project)
|
||||||
|
|
||||||
|
click_on manage_button
|
||||||
|
click_on "Edit"
|
||||||
|
|
||||||
|
fill_in title_field, with: "New Title"
|
||||||
|
|
||||||
|
click_on "Update Casting call"
|
||||||
|
|
||||||
|
expect(page).to have_content("The casting call request has been updated")
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario "can cancel a casting call request" do
|
||||||
|
create(:casting_call, title: "Title", project: project)
|
||||||
|
visit project_casting_calls_path(project)
|
||||||
|
|
||||||
|
click_on manage_button
|
||||||
|
click_on "Cancel"
|
||||||
|
|
||||||
|
expect(page).to have_content("The casting call request has been cancelled")
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario "can open casting call details" do
|
||||||
|
cc = create(:casting_call, title: "Dummy title", project: project)
|
||||||
|
|
||||||
|
visit project_casting_calls_path(project)
|
||||||
|
|
||||||
|
click_on manage_button
|
||||||
|
click_on view_button
|
||||||
|
|
||||||
|
expect(page).to have_content cc.title
|
||||||
|
expect(page).to have_content cc.description
|
||||||
|
expect(page).to have_content cc.project_description
|
||||||
|
expect(page).to have_content cc.created_at
|
||||||
|
expect(page).to have_content cc.status
|
||||||
|
expect(page).to have_content cc.interview_instructions
|
||||||
|
expect(page).to have_content cc.interview_requirements
|
||||||
|
expect(page).to have_content cc.questions
|
||||||
|
end
|
||||||
|
|
||||||
|
context "when signed out" do
|
||||||
|
scenario "user opens public accessible casting call URL" do
|
||||||
|
cc = create(:casting_call, title: "Dummy title", project: project)
|
||||||
|
|
||||||
|
sign_out
|
||||||
|
public_url = "/casting_calls/#{cc.token}"
|
||||||
|
visit public_url
|
||||||
|
|
||||||
|
expect(page).to have_content cc.title
|
||||||
|
expect(page).to have_content cc.description
|
||||||
|
expect(page).to have_content cc.project_description
|
||||||
|
expect(page).not_to have_content cc.created_at
|
||||||
|
expect(page).not_to have_content cc.status
|
||||||
|
expect(page).not_to have_content cc.interview_instructions
|
||||||
|
expect(page).not_to have_content cc.interview_requirements
|
||||||
|
expect(page).not_to have_content cc.questions
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def no_casting_calls_label
|
||||||
|
"Casting calls will appear here"
|
||||||
|
end
|
||||||
|
|
||||||
|
def manage_button
|
||||||
|
t "casting_calls.casting_call.actions.manage"
|
||||||
|
end
|
||||||
|
|
||||||
|
def view_button
|
||||||
|
'View'
|
||||||
|
end
|
||||||
|
|
||||||
|
def add_new_casting_call_label
|
||||||
|
t "casting_calls.index.actions.new"
|
||||||
|
end
|
||||||
|
|
||||||
|
def title_field
|
||||||
|
t "helpers.label.casting_call.title"
|
||||||
|
end
|
||||||
|
|
||||||
|
def description_field
|
||||||
|
t "helpers.label.casting_call.description"
|
||||||
|
end
|
||||||
|
|
||||||
|
def project_description_field
|
||||||
|
t "helpers.label.casting_call.project_description"
|
||||||
|
end
|
||||||
|
|
||||||
|
def interview_instructions_field
|
||||||
|
t "helpers.label.casting_call.interview_instructions"
|
||||||
|
end
|
||||||
|
|
||||||
|
def interview_requirements_field
|
||||||
|
t "helpers.label.casting_call.interview_requirements"
|
||||||
|
end
|
||||||
|
|
||||||
|
def questions_field
|
||||||
|
t "helpers.label.casting_call.questions"
|
||||||
|
end
|
||||||
|
end
|
||||||
60
spec/jobs/generate_casting_submission_files_zip_job_spec.rb
Normal file
60
spec/jobs/generate_casting_submission_files_zip_job_spec.rb
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
require "rails_helper"
|
||||||
|
|
||||||
|
describe GenerateCastingSubmissionFilesZipJob do
|
||||||
|
let(:project) { create(:project) }
|
||||||
|
let(:download) { create(:download, project: project, release_type: "CastingSubmission", name: "my-title_john-doe") }
|
||||||
|
let(:casting_call) { create(:casting_call, project: project, title: "My Title") }
|
||||||
|
let(:casting_submission) { create(:casting_submission, casting_call: casting_call, performer_name: "John Doe") }
|
||||||
|
|
||||||
|
before do
|
||||||
|
dir = Rails.root.join("spec", "fixtures", "files")
|
||||||
|
files = ["contract.pdf", "AppearanceRelease.pdf"]
|
||||||
|
# Attachments in the test environment do not persist to cloud storage
|
||||||
|
# Therefore we want to stub calls to `open` with a cloud storage URL
|
||||||
|
allow_any_instance_of(CastingSubmissionFilesCollectionService).to receive(:open).and_return(StringIO.new("file data"))
|
||||||
|
allow_any_instance_of(CastingSubmissionFilesCollectionService).to receive(:build).and_yield(dir, files)
|
||||||
|
end
|
||||||
|
|
||||||
|
describe ".perform_later" do
|
||||||
|
it "enqueues a background job for generating zip file" do
|
||||||
|
expect {
|
||||||
|
GenerateCastingSubmissionFilesZipJob.perform_later(project, download, casting_submission)
|
||||||
|
}.to have_enqueued_job
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe ".perform_now" do
|
||||||
|
it "updates a download record and creates attachment for it" do
|
||||||
|
GenerateCastingSubmissionFilesZipJob.perform_now(project, download, casting_submission)
|
||||||
|
|
||||||
|
expect(download.project).to eq project
|
||||||
|
expect(download.release_type).to eq "CastingSubmission"
|
||||||
|
expect(download.name).to eq "my-title_john-doe"
|
||||||
|
expect(download.status).to eq "success"
|
||||||
|
expect(download.file).to be_attached
|
||||||
|
end
|
||||||
|
|
||||||
|
context "When there are errors" do
|
||||||
|
let(:error) { StandardError.new("Casting Submission files not found.") }
|
||||||
|
|
||||||
|
before do
|
||||||
|
allow(ProjectsChannel).to receive(:broadcast_download_generation_update).with(download, I18n.t("casting_submission_downloads.download.failure"))
|
||||||
|
allow_any_instance_of(CastingSubmissionFilesCollectionService).to receive(:build).and_raise(StandardError, "Casting Submission files not found.")
|
||||||
|
end
|
||||||
|
|
||||||
|
it "updates status to 'failure' and sends user a notification" do
|
||||||
|
GenerateCastingSubmissionFilesZipJob.perform_now(project, download, casting_submission)
|
||||||
|
|
||||||
|
expect(download.status).to eq "failure"
|
||||||
|
expect(ProjectsChannel).to have_received(:broadcast_download_generation_update).with(download, I18n.t("casting_submission_downloads.download.failure"))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
after do
|
||||||
|
# Delete the file created in fixture.
|
||||||
|
# Or the tests will fail on next run due to already existing files in existing zip.
|
||||||
|
path = Rails.root.join("spec", "fixtures", "files")
|
||||||
|
File.delete("#{path}/my-title_john-doe.zip") if File.exists? "#{path}/my-title_john-doe.zip"
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -11,7 +11,7 @@ RSpec.describe SubmitHubspotFormJob, type: :job do
|
|||||||
allow(Hubspot::Form).to receive(:new).and_return(form)
|
allow(Hubspot::Form).to receive(:new).and_return(form)
|
||||||
allow(form).to receive(:submit).and_return(true)
|
allow(form).to receive(:submit).and_return(true)
|
||||||
|
|
||||||
SubmitHubspotFormJob.perform_now("John", "Doe", "email@test.com", "My Account")
|
SubmitHubspotFormJob.perform_now(first_name: "John", last_name: "Doe", email: "email@test.com", company: "My Account", form_guid: ENV["HUBSPOT_FORM_GUID"])
|
||||||
|
|
||||||
expect(Hubspot::Form).to have_received(:new).with("guid" => "hubspot_form_guid")
|
expect(Hubspot::Form).to have_received(:new).with("guid" => "hubspot_form_guid")
|
||||||
expect(form).to have_received(:submit).with(
|
expect(form).to have_received(:submit).with(
|
||||||
@@ -27,7 +27,7 @@ RSpec.describe SubmitHubspotFormJob, type: :job do
|
|||||||
allow(Hubspot::Form).to receive(:new).and_return(form)
|
allow(Hubspot::Form).to receive(:new).and_return(form)
|
||||||
allow(form).to receive(:submit).and_return(true)
|
allow(form).to receive(:submit).and_return(true)
|
||||||
|
|
||||||
SubmitHubspotFormJob.perform_now("John", "Doe", "email@test.com", "My Account", additional_param_one: "Foo", additional_param_two: "Bar")
|
SubmitHubspotFormJob.perform_now(first_name: "John", last_name: "Doe", email: "email@test.com", company: "My Account", form_guid: ENV["HUBSPOT_FORM_GUID"], additional_param_one: "Foo", additional_param_two: "Bar")
|
||||||
|
|
||||||
expect(form).to have_received(:submit).with(
|
expect(form).to have_received(:submit).with(
|
||||||
first_name: "John",
|
first_name: "John",
|
||||||
@@ -35,7 +35,7 @@ RSpec.describe SubmitHubspotFormJob, type: :job do
|
|||||||
email: "email@test.com",
|
email: "email@test.com",
|
||||||
company: "My Account",
|
company: "My Account",
|
||||||
additional_param_one: "Foo",
|
additional_param_one: "Foo",
|
||||||
additional_param_two: "Bar",
|
additional_param_two: "Bar"
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -46,7 +46,7 @@ RSpec.describe SubmitHubspotFormJob, type: :job do
|
|||||||
allow(Hubspot::Form).to receive(:new).and_return(form)
|
allow(Hubspot::Form).to receive(:new).and_return(form)
|
||||||
allow(form).to receive(:submit)
|
allow(form).to receive(:submit)
|
||||||
|
|
||||||
SubmitHubspotFormJob.perform_now("John", "Doe", "email@test.com", "My Account")
|
SubmitHubspotFormJob.perform_now(first_name: "John", last_name: "Doe", email: "email@test.com", company: "My Account", form_guid: ENV["HUBSPOT_FORM_GUID"])
|
||||||
|
|
||||||
expect(form).not_to have_received(:submit)
|
expect(form).not_to have_received(:submit)
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,36 +0,0 @@
|
|||||||
require 'rails_helper'
|
|
||||||
|
|
||||||
RSpec.describe SubmitHubspotTaskRequestFormJob, type: :job do
|
|
||||||
describe '#perform_now' do
|
|
||||||
before do
|
|
||||||
ENV["HUBSPOT_TASK_REQUEST_FORM_GUID"] = "hubspot_task_request_form_guid"
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'submits to the Hubspot API with the right params' do
|
|
||||||
form = double(:form)
|
|
||||||
allow(Hubspot::Form).to receive(:new).and_return(form)
|
|
||||||
allow(form).to receive(:submit).and_return(true)
|
|
||||||
|
|
||||||
SubmitHubspotTaskRequestFormJob.perform_now("email@test.com", "https://example.com/admin/task_requests/1")
|
|
||||||
|
|
||||||
expect(Hubspot::Form).to have_received(:new).with("guid" => "hubspot_task_request_form_guid")
|
|
||||||
expect(form).to have_received(:submit).with(
|
|
||||||
email: "email@test.com",
|
|
||||||
taskme_url: "https://example.com/admin/task_requests/1"
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'when HUBSPOT_TASK_REQUEST_FORM_GUID is not available' do
|
|
||||||
it 'does not submit to the API' do
|
|
||||||
ENV["HUBSPOT_TASK_REQUEST_FORM_GUID"] = nil
|
|
||||||
form = double(:form)
|
|
||||||
allow(Hubspot::Form).to receive(:new).and_return(form)
|
|
||||||
allow(form).to receive(:submit)
|
|
||||||
|
|
||||||
SubmitHubspotTaskRequestFormJob.perform_now("email@test.com", "https://example.com/admin/task_requests/1")
|
|
||||||
|
|
||||||
expect(form).not_to have_received(:submit)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@@ -135,7 +135,9 @@ RSpec.describe Account do
|
|||||||
MedicalRelease,
|
MedicalRelease,
|
||||||
MiscRelease,
|
MiscRelease,
|
||||||
MatchingRequest,
|
MatchingRequest,
|
||||||
ActionMailbox::InboundEmail # This is Rails model, we are not using it and it is NOT added to the Account#storage_total calculation
|
ActionMailbox::InboundEmail, # This is Rails model, we are not using it and it is NOT added to the Account#storage_total calculation
|
||||||
|
CastingCall,
|
||||||
|
CastingSubmission
|
||||||
]
|
]
|
||||||
Rails.application.eager_load!
|
Rails.application.eager_load!
|
||||||
ActiveRecord::Base.descendants.each do |model|
|
ActiveRecord::Base.descendants.each do |model|
|
||||||
|
|||||||
11
spec/models/casting_call_spec.rb
Normal file
11
spec/models/casting_call_spec.rb
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
RSpec.describe CastingCall, type: :model do
|
||||||
|
describe "associations" do
|
||||||
|
it { is_expected.to belong_to(:project) }
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "validations" do
|
||||||
|
it { is_expected.to have_secure_token(:token) }
|
||||||
|
end
|
||||||
|
end
|
||||||
14
spec/models/casting_submission_spec.rb
Normal file
14
spec/models/casting_submission_spec.rb
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
RSpec.describe CastingSubmission, type: :model do
|
||||||
|
subject { build(:casting_submission) }
|
||||||
|
|
||||||
|
describe "associations" do
|
||||||
|
it { is_expected.to belong_to(:casting_call) }
|
||||||
|
it { is_expected.to have_secure_token(:token) }
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "validations" do
|
||||||
|
it { is_expected.to validate_presence_of(:performer_name) }
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -19,6 +19,7 @@ RSpec.describe Project, type: :model do
|
|||||||
it { is_expected.to have_many(:broadcasts).dependent(:destroy) }
|
it { is_expected.to have_many(:broadcasts).dependent(:destroy) }
|
||||||
it { is_expected.to have_many(:downloads).dependent(:destroy) }
|
it { is_expected.to have_many(:downloads).dependent(:destroy) }
|
||||||
it { is_expected.to have_many(:zoom_meetings).dependent(:destroy) }
|
it { is_expected.to have_many(:zoom_meetings).dependent(:destroy) }
|
||||||
|
it { is_expected.to have_many(:casting_calls).dependent(:destroy) }
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "nested attributes" do
|
describe "nested attributes" do
|
||||||
|
|||||||
91
spec/policies/casting_call_policy_spec.rb
Normal file
91
spec/policies/casting_call_policy_spec.rb
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
require "rails_helper"
|
||||||
|
|
||||||
|
describe CastingCallPolicy do
|
||||||
|
subject { described_class }
|
||||||
|
|
||||||
|
let(:user_context) { build(:user_context, user: user, account: user.primary_account) }
|
||||||
|
|
||||||
|
context "for an associate" do
|
||||||
|
let(:user) { create(:user, :associate, admin: false) }
|
||||||
|
|
||||||
|
permissions :index? do
|
||||||
|
it { is_expected.to permit(user_context, subject) }
|
||||||
|
end
|
||||||
|
|
||||||
|
permissions :create? do
|
||||||
|
it { is_expected.to permit(user_context, subject) }
|
||||||
|
end
|
||||||
|
|
||||||
|
permissions :show? do
|
||||||
|
it { is_expected.to permit(user_context, subject) }
|
||||||
|
end
|
||||||
|
|
||||||
|
permissions :destroy? do
|
||||||
|
it { is_expected.to permit(user_context, subject) }
|
||||||
|
end
|
||||||
|
|
||||||
|
permissions :update? do
|
||||||
|
it { is_expected.to permit(user_context, subject) }
|
||||||
|
end
|
||||||
|
|
||||||
|
permissions :cancel? do
|
||||||
|
it { is_expected.to permit(user_context, subject) }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "for a project manager" do
|
||||||
|
let(:user) { create(:user, :manager, admin: false) }
|
||||||
|
|
||||||
|
permissions :index? do
|
||||||
|
it { is_expected.to permit(user_context, subject) }
|
||||||
|
end
|
||||||
|
|
||||||
|
permissions :create? do
|
||||||
|
it { is_expected.to permit(user_context, subject) }
|
||||||
|
end
|
||||||
|
|
||||||
|
permissions :show? do
|
||||||
|
it { is_expected.to permit(user_context, subject) }
|
||||||
|
end
|
||||||
|
|
||||||
|
permissions :destroy? do
|
||||||
|
it { is_expected.to permit(user_context, subject) }
|
||||||
|
end
|
||||||
|
|
||||||
|
permissions :update? do
|
||||||
|
it { is_expected.to permit(user_context, subject) }
|
||||||
|
end
|
||||||
|
|
||||||
|
permissions :cancel? do
|
||||||
|
it { is_expected.to permit(user_context, subject) }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "for account managers" do
|
||||||
|
let(:user) { create(:user, :account_manager, admin: false) }
|
||||||
|
|
||||||
|
permissions :index? do
|
||||||
|
it { is_expected.to permit(user_context, subject) }
|
||||||
|
end
|
||||||
|
|
||||||
|
permissions :create? do
|
||||||
|
it { is_expected.to permit(user_context, subject) }
|
||||||
|
end
|
||||||
|
|
||||||
|
permissions :show? do
|
||||||
|
it { is_expected.to permit(user_context, subject) }
|
||||||
|
end
|
||||||
|
|
||||||
|
permissions :destroy? do
|
||||||
|
it { is_expected.to permit(user_context, subject) }
|
||||||
|
end
|
||||||
|
|
||||||
|
permissions :update? do
|
||||||
|
it { is_expected.to permit(user_context, subject) }
|
||||||
|
end
|
||||||
|
|
||||||
|
permissions :cancel? do
|
||||||
|
it { is_expected.to permit(user_context, subject) }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
Reference in New Issue
Block a user