Compare commits

..

2 Commits

Author SHA1 Message Date
Senad Uka
9a29f1d13a Usptream sync castme 2020-07-29 05:15:44 +00:00
Senad Uka
4f1ebb27d0 Upstream sync 2020-07-27 10:18:49 +00:00
15 changed files with 335 additions and 28 deletions

View File

@@ -40,7 +40,16 @@ class Admin::CastingSubmissionsController < Admin::ApplicationController
end end
def casting_submission_params def casting_submission_params
params.require(:casting_submission).permit(:casting_call_id, :performer_name, :interview_date, :zoom_meeting_url, :interview_recording) params.require(:casting_submission).permit(
:casting_call_id, :performer_name, :interview_date,
:zoom_meeting_url, :interview_recording, :time_elapsed_1,
:time_elapsed_2, :time_elapsed_3, :time_elapsed_4, :time_elapsed_5,
:time_elapsed_6, :time_elapsed_7, :time_elapsed_8, :time_elapsed_9,
:time_elapsed_10, :time_elapsed_11, :time_elapsed_12, :time_elapsed_13,
:time_elapsed_14, :time_elapsed_15, :note_1 , :note_2 , :note_3 , :note_4,
:note_5, :note_6, :note_7, :note_8, :note_9, :note_10, :note_11, :note_12, :note_13,
:note_14, :note_15
)
end end
def casting_submissions def casting_submissions

View File

@@ -4,6 +4,7 @@ class CastingCallsController < ApplicationController
before_action :set_project before_action :set_project
before_action :build_casting_call, only: [:new, :create] before_action :build_casting_call, only: [:new, :create]
before_action :set_casting_call, only: [:show, :edit, :update, :cancel] before_action :set_casting_call, only: [:show, :edit, :update, :cancel]
before_action :show_splash_screen, only: :index
def index def index
@casting_calls = casting_calls.order_by_recent.paginate(page: params[:page]) @casting_calls = casting_calls.order_by_recent.paginate(page: params[:page])
@@ -45,6 +46,10 @@ class CastingCallsController < ApplicationController
private private
def show_splash_screen
render :splash if casting_calls.count.zero?
end
def casting_call_params def casting_call_params
params.require(:casting_call).permit(:title, :description, :project_description, :interview_instructions, :interview_requirements, :questions) params.require(:casting_call).permit(:title, :description, :project_description, :interview_instructions, :interview_requirements, :questions)
end end

View File

@@ -11,6 +11,8 @@ class CastingSubmissionsController < ApplicationController
def show def show
@casting_call = @casting_submission.casting_call @casting_call = @casting_submission.casting_call
@files = @casting_submission.files.order("created_at DESC").paginate(page: params[:files_page]) @files = @casting_submission.files.order("created_at DESC").paginate(page: params[:files_page])
@markers = @casting_submission.markers
render layout: 'application' render layout: 'application'
end end

View File

@@ -3,6 +3,8 @@ class CastingSubmission < ApplicationRecord
has_many_attached :files has_many_attached :files
has_one_attached :interview_recording has_one_attached :interview_recording
NUMBER_OF_MARKER_FIELDS = 15
has_secure_token has_secure_token
validates :performer_name, presence: true validates :performer_name, presence: true
@@ -12,4 +14,12 @@ class CastingSubmission < ApplicationRecord
def zip_file_name def zip_file_name
"#{self.casting_call.title.parameterize}_#{self.performer_name.parameterize}_#{Time.now.strftime('%Y-%m-%d_%H-%M-%S')}" "#{self.casting_call.title.parameterize}_#{self.performer_name.parameterize}_#{Time.now.strftime('%Y-%m-%d_%H-%M-%S')}"
end end
def markers
(1..NUMBER_OF_MARKER_FIELDS).map do |n|
if public_send("time_elapsed_#{n}").present?
OpenStruct.new(id: n, time_elapsed: public_send("time_elapsed_#{n}"), note: public_send("note_#{n}") )
end
end.compact
end
end end

View File

@@ -20,6 +20,7 @@
<% unless casting_submission.interviewed_at.present? %> <% unless casting_submission.interviewed_at.present? %>
<%= link_to fa_icon("check", text: "Complete"), [:complete, :admin, casting_submission], method: :post, class: "dropdown-item" %> <%= link_to fa_icon("check", text: "Complete"), [:complete, :admin, casting_submission], method: :post, class: "dropdown-item" %>
<% end %> <% end %>
<%= link_to fa_icon("link fw", text: "Copy URL"), casting_submission_url(token: casting_submission.token), class: "dropdown-item", data: { behavior: "clipboard" } %>
</div> </div>
</div> </div>
</td> </td>

View File

@@ -7,7 +7,7 @@
<%= form.text_field :zoom_meeting_url %> <%= form.text_field :zoom_meeting_url %>
<% unless casting_submission.new_record? %> <% 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 } %> <%= form.file_field :interview_recording, accept: "video/mp4", 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? %> <% if casting_submission.interview_recording.attached? %>
<p> <p>
@@ -17,8 +17,15 @@
<span class="text-muted"><%= fa_icon "long-arrow-left" %> <em>Current interview recording</em></span> <span class="text-muted"><%= fa_icon "long-arrow-left" %> <em>Current interview recording</em></span>
</p> </p>
<% end %> <% end %>
<hr>
<%= card_field_set_tag t(".casting_submission_markers.heading") do %>
<% (1..CastingSubmission::NUMBER_OF_MARKER_FIELDS).each do |n| %>
<div class="form-row">
<%= form.number_field "time_elapsed_#{n}", wrapper_class: "col-md-6", label: "Elapsed Time #{n} (in seconds)" %>
<%= form.text_area "note_#{n}", wrapper_class: "col-md-6", label: "Note #{n}" %>
</div>
<% end %>
<% end %>
<% end %> <% end %>
<div class="row align-items-center text-center mt-4"> <div class="row align-items-center text-center mt-4">

View File

@@ -0,0 +1,58 @@
<div class="d-flex flex-row">
<div class="d-flex flex-column">
<%= product_wordmark :cast_me, prefix: t('.headings.welcome'), class: "h2" %>
<p class="text-muted"><%= t '.headings.subtitle' %>
</div>
<%= link_to t(".actions.book_demo"), 'https://meetings.hubspot.com/bray2', class: "btn btn-primary border align-self-center h-50 ml-auto mr-2 pb-2", target: '_blank' %>
<% if policy(CastingCall).new? %>
<%= link_to t(".actions.create_casting_call"), [:new, @project, :casting_call], class: "btn btn-success border align-self-center h-50 pb-2" %>
<% end %>
</div>
<hr>
<div class="pt-2">
<div class="row">
<div class="col">
<div class="card-body p-0">
<div class="embed-responsive embed-responsive-16by9">
<div class="embed-responsive-item">
<table class="w-100 h-100 bg-secondary">
<tbody>
<tr>
<td class="text-center align-middle text-white">
Video tutorial will be available soon
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<div class="col">
<div class="row">
<div class="col">
<h3><%= t '.headings.how_it_works' %></h3>
<ol>
<li><%= t '.list_items.enter_information' %></li>
<li><%= t '.list_items.enter_questions' %></li>
<li><%= t '.list_items.copy_and_paste_submission_link' %></li>
<li><%= t '.list_items.wait_for_the_submission_video' %></li>
</ol>
</div>
</div>
<div class="row">
<div class="col">
<h3><%= t '.headings.benefits' %></h3>
<ul class="fa-ul ml-5">
<%= content_tag(:li, fa_icon("check li", text: t('.list_items.fewer_team_members_needed'))) %>
<%= content_tag(:li, fa_icon("check li", text: t('.list_items.fewer_resources_needed'))) %>
<%= content_tag(:li, fa_icon("check li", text: t('.list_items.more_time_spent_with_quality_candidates'))) %>
</ul>
</div>
</div>
</div>
</div>
</div>

View File

@@ -22,14 +22,27 @@
<%= render partial: 'casting_submissions/video', locals: { casting_submission: @casting_submission } %> <%= render partial: 'casting_submissions/video', locals: { casting_submission: @casting_submission } %>
<% if @casting_submission.interview_recording.present? %> <% if @casting_submission.interview_recording.present? %>
<%= javascript_tag nonce: true do %> <%= javascript_tag nonce: true do %>
new Clappr.Player({ var markerData = <%= raw @markers.to_json %>;
parentId: '#casting_submission_video',
source: "<%= rails_blob_url(@casting_submission.interview_recording, host: AppHost.new.domain_with_port) %>", var player = new Clappr.Player({
width: '100%', parentId: '#casting_submission_video',
height: '100%', source: "<%= rails_blob_url(@casting_submission.interview_recording, host: AppHost.new.domain_with_port) %>",
mute: true, plugins: {
autoPlay: true, core: [ClapprMarkersPlugin]
hlsMinimumDvrSize: 1 },
markersPlugin: {},
width: '100%',
height: '100%',
mute: true,
autoPlay: true,
hlsMinimumDvrSize: 1
});
markerData.forEach(function(marker, index) {
var markers = player.getPlugin("markers-plugin");
var marker = new ClapprMarkersPlugin.StandardMarker(Number(marker.table.time_elapsed), marker.table.note)
markers.addMarker(marker);
}); });
<% end %> <% end %>
<% end %> <% end %>

View File

@@ -105,6 +105,9 @@ en:
notice: The casting submission has been completed notice: The casting submission has been completed
create: create:
notice: The casting submission has been created notice: The casting submission has been created
form:
casting_submission_markers:
heading: Markers
index: index:
actions: actions:
new: Create Casting Submission new: Create Casting Submission
@@ -271,6 +274,23 @@ en:
casting_call_title: Casting Title casting_call_title: Casting Title
new: new:
heading: New Casting Call heading: New Casting Call
splash:
actions:
book_demo: Schedule a Demo
create_casting_call: Create Casting Call
headings:
benefits: Benefits
how_it_works: How It Works
subtitle: The media industry's first automated casting bot
welcome: Welcome to
list_items:
copy_and_paste_submission_link: Copy and paste the submission link wherever you want
enter_information: Enter information about the role and project
enter_questions: Enter the questions you want the Chatbot to ask
fewer_resources_needed: Fewer resources needed for first round of casting search
fewer_team_members_needed: Fewer team members needed to cast large projects
more_time_spent_with_quality_candidates: More time spent with quality casting candidates
wait_for_the_submission_video: Wait for the casting bot to deliver you casting submission videos
update: update:
notice: The casting call request has been updated notice: The casting call request has been updated
casting_submission_downloads: casting_submission_downloads:

View File

@@ -76,6 +76,26 @@ es:
share_stream: Share live stream link with clients share_stream: Share live stream link with clients
stream_from_mobile_app: Stream from ME Suite Mobile app, or via a professional camera stream_from_mobile_app: Stream from ME Suite Mobile app, or via a professional camera
stream_multiple_cameras: Stream multiple cameras at one time stream_multiple_cameras: Stream multiple cameras at one time
casting_calls:
index:
empty: Casting calls will appear here (ES)
splash:
actions:
book_demo: Schedule a Demo (ES)
create_casting_call: Create Casting Call (ES)
headings:
benefits: Benefits (ES)
how_it_works: How It Works (ES)
subtitle: The media industry's first automated casting bot (ES)
welcome: Welcome to (ES)
list_items:
copy_and_paste_submission_link: Copy and paste the submission link wherever you want (ES)
enter_information: Enter information about the role and project (ES)
enter_questions: Enter the questions you want the Chatbot to ask (ES)
fewer_resources_needed: Fewer resources needed for first round of casting search (ES)
fewer_team_members_needed: Fewer team members needed to cast large projects (ES)
more_time_spent_with_quality_candidates: More time spent with quality casting candidates (ES)
wait_for_the_submission_video: Wait for the casting bot to deliver you casting submission videos (ES)
contract_templates: contract_templates:
blank_contracts: blank_contracts:
create: create:

View File

@@ -0,0 +1,35 @@
class AddMarkersToCastingSubmissions < ActiveRecord::Migration[6.0]
def change
add_column :casting_submissions, :time_elapsed_1, :integer
add_column :casting_submissions, :time_elapsed_2, :integer
add_column :casting_submissions, :time_elapsed_3, :integer
add_column :casting_submissions, :time_elapsed_4, :integer
add_column :casting_submissions, :time_elapsed_5, :integer
add_column :casting_submissions, :time_elapsed_6, :integer
add_column :casting_submissions, :time_elapsed_7, :integer
add_column :casting_submissions, :time_elapsed_8, :integer
add_column :casting_submissions, :time_elapsed_9, :integer
add_column :casting_submissions, :time_elapsed_10, :integer
add_column :casting_submissions, :time_elapsed_11, :integer
add_column :casting_submissions, :time_elapsed_12, :integer
add_column :casting_submissions, :time_elapsed_13, :integer
add_column :casting_submissions, :time_elapsed_14, :integer
add_column :casting_submissions, :time_elapsed_15, :integer
add_column :casting_submissions, :note_1, :text
add_column :casting_submissions, :note_2, :text
add_column :casting_submissions, :note_3, :text
add_column :casting_submissions, :note_4, :text
add_column :casting_submissions, :note_5, :text
add_column :casting_submissions, :note_6, :text
add_column :casting_submissions, :note_7, :text
add_column :casting_submissions, :note_8, :text
add_column :casting_submissions, :note_9, :text
add_column :casting_submissions, :note_10, :text
add_column :casting_submissions, :note_11, :text
add_column :casting_submissions, :note_12, :text
add_column :casting_submissions, :note_13, :text
add_column :casting_submissions, :note_14, :text
add_column :casting_submissions, :note_15, :text
end
end

View File

@@ -9,6 +9,20 @@ SET xmloption = content;
SET client_min_messages = warning; SET client_min_messages = warning;
SET row_security = off; SET row_security = off;
--
-- Name: plpgsql; Type: EXTENSION; Schema: -; Owner: -
--
CREATE EXTENSION IF NOT EXISTS plpgsql WITH SCHEMA pg_catalog;
--
-- Name: EXTENSION plpgsql; Type: COMMENT; Schema: -; Owner: -
--
COMMENT ON EXTENSION plpgsql IS 'PL/pgSQL procedural language';
-- --
-- Name: fuzzystrmatch; Type: EXTENSION; Schema: -; Owner: - -- Name: fuzzystrmatch; Type: EXTENSION; Schema: -; Owner: -
-- --
@@ -317,8 +331,8 @@ CREATE TABLE public.appearance_releases (
person_last_name character varying, person_last_name character varying,
guardian_first_name character varying, guardian_first_name character varying,
guardian_last_name character varying, guardian_last_name character varying,
identifier character varying,
guardian_email character varying, guardian_email character varying,
identifier character varying,
person_address_street2 character varying, person_address_street2 character varying,
person_address_city character varying, person_address_city character varying,
person_address_state character varying, person_address_state character varying,
@@ -608,7 +622,37 @@ CREATE TABLE public.casting_submissions (
created_at timestamp(6) without time zone NOT NULL, created_at timestamp(6) without time zone NOT NULL,
updated_at timestamp(6) without time zone NOT NULL, updated_at timestamp(6) without time zone NOT NULL,
token character varying, token character varying,
interviewed_at timestamp without time zone interviewed_at timestamp without time zone,
time_elapsed_1 integer,
time_elapsed_2 integer,
time_elapsed_3 integer,
time_elapsed_4 integer,
time_elapsed_5 integer,
time_elapsed_6 integer,
time_elapsed_7 integer,
time_elapsed_8 integer,
time_elapsed_9 integer,
time_elapsed_10 integer,
time_elapsed_11 integer,
time_elapsed_12 integer,
time_elapsed_13 integer,
time_elapsed_14 integer,
time_elapsed_15 integer,
note_1 text,
note_2 text,
note_3 text,
note_4 text,
note_5 text,
note_6 text,
note_7 text,
note_8 text,
note_9 text,
note_10 text,
note_11 text,
note_12 text,
note_13 text,
note_14 text,
note_15 text
); );
@@ -728,6 +772,15 @@ CREATE SEQUENCE public.contract_templates_id_seq
ALTER SEQUENCE public.contract_templates_id_seq OWNED BY public.contract_templates.id; ALTER SEQUENCE public.contract_templates_id_seq OWNED BY public.contract_templates.id;
--
-- Name: data_migrations; Type: TABLE; Schema: public; Owner: -
--
CREATE TABLE public.data_migrations (
version character varying NOT NULL
);
-- --
-- Name: directories; Type: TABLE; Schema: public; Owner: - -- Name: directories; Type: TABLE; Schema: public; Owner: -
-- --
@@ -1469,7 +1522,6 @@ CREATE TABLE public.settings (
-- --
CREATE SEQUENCE public.settings_id_seq CREATE SEQUENCE public.settings_id_seq
AS integer
START WITH 1 START WITH 1
INCREMENT BY 1 INCREMENT BY 1
NO MINVALUE NO MINVALUE
@@ -1505,7 +1557,6 @@ CREATE TABLE public.taggings (
-- --
CREATE SEQUENCE public.taggings_id_seq CREATE SEQUENCE public.taggings_id_seq
AS integer
START WITH 1 START WITH 1
INCREMENT BY 1 INCREMENT BY 1
NO MINVALUE NO MINVALUE
@@ -1536,7 +1587,6 @@ CREATE TABLE public.tags (
-- --
CREATE SEQUENCE public.tags_id_seq CREATE SEQUENCE public.tags_id_seq
AS integer
START WITH 1 START WITH 1
INCREMENT BY 1 INCREMENT BY 1
NO MINVALUE NO MINVALUE
@@ -1897,9 +1947,9 @@ CREATE TABLE public.zoom_meetings (
api_meeting_id character varying, api_meeting_id character varying,
created_at timestamp(6) without time zone NOT NULL, created_at timestamp(6) without time zone NOT NULL,
updated_at timestamp(6) without time zone NOT NULL, updated_at timestamp(6) without time zone NOT NULL,
status integer DEFAULT 0,
zoom_user_id bigint, zoom_user_id bigint,
project_id bigint, project_id bigint
status integer DEFAULT 0
); );
@@ -2406,6 +2456,14 @@ ALTER TABLE ONLY public.contract_templates
ADD CONSTRAINT contract_templates_pkey PRIMARY KEY (id); ADD CONSTRAINT contract_templates_pkey PRIMARY KEY (id);
--
-- Name: data_migrations data_migrations_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY public.data_migrations
ADD CONSTRAINT data_migrations_pkey PRIMARY KEY (version);
-- --
-- Name: directories directories_pkey; Type: CONSTRAINT; Schema: public; Owner: - -- Name: directories directories_pkey; Type: CONSTRAINT; Schema: public; Owner: -
-- --
@@ -4050,6 +4108,7 @@ INSERT INTO "schema_migrations" (version) VALUES
('20200706193123'), ('20200706193123'),
('20200706230803'), ('20200706230803'),
('20200707070522'), ('20200707070522'),
('20200714175331'); ('20200714175331'),
('20200722193459');

View File

@@ -18,7 +18,7 @@ RSpec.describe CastingCallsController, type: :controller do
expect(response).to be_successful expect(response).to be_successful
end end
it "renders content" do it "renders content if there are existing broadcasts" do
create(:casting_call, project: project) create(:casting_call, project: project)
get :index, params: { project_id: project } get :index, params: { project_id: project }
@@ -36,6 +36,18 @@ RSpec.describe CastingCallsController, type: :controller do
expect(response.body).to have_link("2", href: project_casting_calls_path(project, page: 2)) expect(response.body).to have_link("2", href: project_casting_calls_path(project, page: 2))
end end
end end
context "when there are no records" do
it "renders splash screen" do
CastingCall.destroy_all
get :index, params: { project_id: project }
expect(response.body).not_to have_content no_casting_calls_message
expect(response.body).to have_link create_casting_call
expect(response.body).to have_link schedule_demo
end
end
end end
describe "#new" do describe "#new" do
@@ -117,4 +129,16 @@ RSpec.describe CastingCallsController, type: :controller do
def update_params def update_params
{ description: "This is updated description" } { description: "This is updated description" }
end end
def no_casting_calls_message
t 'casting_calls.index.empty'
end
def create_casting_call
t 'casting_calls.splash.actions.create_casting_call'
end
def schedule_demo
t 'casting_calls.splash.actions.book_demo'
end
end end

View File

@@ -61,6 +61,17 @@ feature "Admin managing casting submissions" do
expect(page).to have_content cci.performer_name expect(page).to have_content cci.performer_name
end end
scenario "admin can see copy url" 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
expect(page).to have_content "Copy URL"
end
private private
def create_casting_submission_button def create_casting_submission_button

View File

@@ -1,14 +1,15 @@
require "rails_helper" require "rails_helper"
feature "User managing casting calls" do feature "User managing casting calls" do
let(:current_user) { create(:user) } let(:current_user) { create(:user, :manager) }
let(:project) { create(:project, account: current_user.primary_account) } let(:project) { create(:project, members: current_user, account: current_user.primary_account) }
before :each do before :each do
sign_in current_user sign_in current_user
end end
scenario "casting calls table is visible" do scenario "casting calls table is visible if there are existing casting calls" do
create(:casting_call, project: project)
visit project_casting_calls_path(project) visit project_casting_calls_path(project)
expect(page).to have_content "Created On" expect(page).to have_content "Created On"
@@ -16,11 +17,14 @@ feature "User managing casting calls" do
expect(page).to have_content "Status" expect(page).to have_content "Status"
end end
scenario "sees list of casting calls" do scenario "splash page is shown if there are no existing records" do
visit project_casting_calls_path(project) visit project_casting_calls_path(project)
expect(page).to have_content no_casting_calls_label expect(page).to have_content schedule_demo
expect(page).to have_content create_casting_call
end
scenario "sees list of casting calls" do
casting_call = create(:casting_call, project: project) casting_call = create(:casting_call, project: project)
visit project_casting_calls_path(project) visit project_casting_calls_path(project)
@@ -35,7 +39,6 @@ feature "User managing casting calls" do
scenario "can create casting call requests" do scenario "can create casting call requests" do
visit project_casting_calls_path(project) visit project_casting_calls_path(project)
expect(page).to have_content no_casting_calls_label
click_on add_new_casting_call_label click_on add_new_casting_call_label
fill_in title_field, with: "Casting Title" fill_in title_field, with: "Casting Title"
@@ -92,6 +95,28 @@ feature "User managing casting calls" do
expect(page).to have_content cc.questions expect(page).to have_content cc.questions
end end
context 'When the user is associate' do
let(:current_user) { create(:user, :associate) }
it 'does show button to create new casting call' do
visit project_casting_calls_path(project)
expect(page).to have_content schedule_demo
expect(page).to have_content create_casting_call
end
end
context 'When the user is account manager' do
let(:current_user) { create(:user, :account_manager) }
it 'does show button to create new casting call' do
visit project_casting_calls_path(project)
expect(page).to have_content schedule_demo
expect(page).to have_content create_casting_call
end
end
context "when signed out" do context "when signed out" do
scenario "user opens public accessible casting call URL" do scenario "user opens public accessible casting call URL" do
cc = create(:casting_call, title: "Dummy title", project: project) cc = create(:casting_call, title: "Dummy title", project: project)
@@ -114,7 +139,7 @@ feature "User managing casting calls" do
private private
def no_casting_calls_label def no_casting_calls_label
"Casting calls will appear here" t 'casting_calls.index.empty'
end end
def manage_button def manage_button
@@ -152,4 +177,12 @@ feature "User managing casting calls" do
def questions_field def questions_field
t "helpers.label.casting_call.questions" t "helpers.label.casting_call.questions"
end end
def create_casting_call
t 'casting_calls.splash.actions.create_casting_call'
end
def schedule_demo
t 'casting_calls.splash.actions.book_demo'
end
end end