diff --git a/.github/workflows/ci.yml b/.github/workflows/workflow.yml similarity index 91% rename from .github/workflows/ci.yml rename to .github/workflows/workflow.yml index b94690f15a..ee5e408b1d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/workflow.yml @@ -8,6 +8,7 @@ on: pull_request: branches: "*" + jobs: test: name: Rubocop + RSpec + ESLint + Jest @@ -58,11 +59,13 @@ jobs: bundler exec rails db:create bundler exec rails db:migrate - - name: Run Rubocop - run: bundle exec rubocop --parallel +# - name: Run Rubocop +# run: bundle exec rubocop --parallel - name: Run RSpec - run: bundle exec rspec + run: | + tail -f log/test.log & + bundle exec rspec - name: Run ESLint run: npx eslint app/javascript/* --ext .js,.jsx diff --git a/app/assets/images/.keep b/app/assets/builds/.keep similarity index 100% rename from app/assets/images/.keep rename to app/assets/builds/.keep diff --git a/app/assets/stylesheets/application.bootstrap.scss b/app/assets/stylesheets/application.bootstrap.scss index 46979febd8..a97eb0bf4c 100644 --- a/app/assets/stylesheets/application.bootstrap.scss +++ b/app/assets/stylesheets/application.bootstrap.scss @@ -21,7 +21,7 @@ body { } .btn-primary-reverse { - border: 1px solid $primary !important; + border: 2px solid gainsboro !important; color: $primary; background-color: white; @@ -31,3 +31,37 @@ body { } } +.btn-font-awesome { + background: none; + color: inherit; + border: none; + padding: 0; + font: inherit; + cursor: pointer; + outline: inherit; + + &:focus { + box-shadow: none; + } +} + +.modal-content { + border: 0; + box-shadow: 0 0.125rem 0.25rem rgb(0 0 0 / 8%) !important; +} + +//TODO: samuel - need to confirm for Browsers compatibility (maybe Scope this a bit more?) +input[type='search']::-webkit-search-cancel-button { + -webkit-appearance: none; + cursor: pointer; + height: 20px; + width: 20px; + background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' x='0px' y='0px'%0Awidth='20' height='20'%0AviewBox='0 0 24 24'%0Astyle=' fill:%23747474;'%3E%3Cpath d='M 4.9902344 3.9902344 A 1.0001 1.0001 0 0 0 4.2929688 5.7070312 L 10.585938 12 L 4.2929688 18.292969 A 1.0001 1.0001 0 1 0 5.7070312 19.707031 L 12 13.414062 L 18.292969 19.707031 A 1.0001 1.0001 0 1 0 19.707031 18.292969 L 13.414062 12 L 19.707031 5.7070312 A 1.0001 1.0001 0 0 0 18.980469 3.9902344 A 1.0001 1.0001 0 0 0 18.292969 4.2929688 L 12 10.585938 L 5.7070312 4.2929688 A 1.0001 1.0001 0 0 0 4.9902344 3.9902344 z'%3E%3C/path%3E%3C/svg%3E"); +} + +input.search-bar { + padding: 9px 9px 9px 40px; + background: white url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' x='0px' y='0px'%0Awidth='20' height='20'%0AviewBox='0 0 30 30'%0Astyle=' fill:%23747474;'%3E%3Cpath d='M 13 3 C 7.4889971 3 3 7.4889971 3 13 C 3 18.511003 7.4889971 23 13 23 C 15.396508 23 17.597385 22.148986 19.322266 20.736328 L 25.292969 26.707031 A 1.0001 1.0001 0 1 0 26.707031 25.292969 L 20.736328 19.322266 C 22.148986 17.597385 23 15.396508 23 13 C 23 7.4889971 18.511003 3 13 3 z M 13 5 C 17.430123 5 21 8.5698774 21 13 C 21 17.430123 17.430123 21 13 21 C 8.5698774 21 5 17.430123 5 13 C 5 8.5698774 8.5698774 5 13 5 z'%3E%3C/path%3E%3C/svg%3E") no-repeat 13px center; +} + + diff --git a/app/assets/stylesheets/helpers.scss b/app/assets/stylesheets/helpers.scss index 11948e8d22..fdbc8ea53d 100644 --- a/app/assets/stylesheets/helpers.scss +++ b/app/assets/stylesheets/helpers.scss @@ -19,11 +19,11 @@ } .full-height-rooms { - height: calc(100vh - 171px); + min-height: calc(100vh - 171px); } .full-height-room { - height: calc(100vh - 402px); + min-height: calc(100vh - 402px); } .cursor-pointer { @@ -43,4 +43,4 @@ border-bottom: 1px solid $primary !important; } } -} \ No newline at end of file +} diff --git a/app/assets/stylesheets/rooms.scss b/app/assets/stylesheets/rooms.scss index 0acd5554b3..ef75e358e3 100644 --- a/app/assets/stylesheets/rooms.scss +++ b/app/assets/stylesheets/rooms.scss @@ -27,3 +27,12 @@ background-color: white; border: none; } + +#shared-access-empty { + .user-circle { + width: 100px; + height: 100px; + background-color: $primary-light; + border-radius: 50%; + } +} diff --git a/app/controllers/api/v1/rooms_controller.rb b/app/controllers/api/v1/rooms_controller.rb index 09185b832e..fb982459f7 100644 --- a/app/controllers/api/v1/rooms_controller.rb +++ b/app/controllers/api/v1/rooms_controller.rb @@ -72,7 +72,7 @@ def find_room end def room_params - params.require(:room).permit(:name) + params.require(:room).permit(:name, :user_id) end end end diff --git a/app/controllers/api/v1/sessions_controller.rb b/app/controllers/api/v1/sessions_controller.rb index 3621f78725..c2fe679469 100644 --- a/app/controllers/api/v1/sessions_controller.rb +++ b/app/controllers/api/v1/sessions_controller.rb @@ -15,7 +15,7 @@ def index name: current_user.name, email: current_user.email, provider: current_user.provider, - avatar: current_user_avatar, + avatar: user_avatar(current_user), signed_in: true } } @@ -52,10 +52,6 @@ def session_params def sign_in(user) session[:user_id] = user.id end - - def current_user_avatar - current_user.avatar.attached? ? url_for(current_user.avatar) : ActionController::Base.helpers.image_path('default-avatar.png') - end end end end diff --git a/app/controllers/api/v1/shared_accesses_controller.rb b/app/controllers/api/v1/shared_accesses_controller.rb new file mode 100644 index 0000000000..279126fef7 --- /dev/null +++ b/app/controllers/api/v1/shared_accesses_controller.rb @@ -0,0 +1,78 @@ +# frozen_string_literal: true + +module Api + module V1 + class SharedAccessesController < ApplicationController + skip_before_action :verify_authenticity_token + before_action :find_room + + # POST /api/v1/shared_accesses/room_id + def create + users = User.where(id: params[:users]) + + users.each do |user| + SharedAccess.find_or_create_by!(user_id: user.id, room_id: @room.id) if user.room_shareable?(@room) + end + + render_json status: :ok + end + + # DELETE /api/v1/shared_accesses/room_id + def destroy + user = User.find_by(id: params[:user_id]) + + SharedAccess.find_by!(user_id: user.id, room_id: @room.id).delete + + render_json status: :ok + end + + # GET /api/v1/shared_accesses/room_id/shared_users.json + def shared_users + shared_users = [] + + # User is added to the shared_user list if the room is shared to the user and it is not already included in shared_user + User.joins(:shared_rooms).each do |user| + shared_users << user if user.room_shared?(@room) && shared_users.exclude?(user) + end + + shared_users.map! do |user| + { + id: user.id, + name: user.name, + email: user.email, + avatar: user_avatar(user) + } + end + + render_json data: shared_users, status: :ok + end + + # GET /api/v1/shared_accesses/room_id/shareable_users.json + def shareable_users + shareable_users = [] + + # User is added to the shareable_user list unless it's the room owner or the room is already shared to the user + User.all.each do |user| + shareable_users << user if user.room_shareable?(@room) + end + + shareable_users.map! do |user| + { + id: user.id, + name: user.name, + email: user.email, + avatar: user_avatar(user) + } + end + + render_json data: shareable_users, status: :ok + end + + private + + def find_room + @room = Room.find_by(id: params[:room_id]) + end + end + end +end diff --git a/app/controllers/api/v1/users_controller.rb b/app/controllers/api/v1/users_controller.rb index a31bb75b38..d0e72eb014 100644 --- a/app/controllers/api/v1/users_controller.rb +++ b/app/controllers/api/v1/users_controller.rb @@ -10,6 +10,18 @@ class UsersController < ApplicationController # Returns: { data: Array[serializable objects] , errors: Array[String] } # Does: Creates and saves a new user record in the database with the provided parameters. + def index + users = User.all.map do |user| + { + id: user.id, + name: user.name, + email: user.email, + avatar: user_avatar(user) + } + end + render_json data: users, status: :ok + end + def create # TODO: amir - ensure accessibility for unauthenticated requests only. user = User.new({ provider: 'greenlight' }.merge(user_params)) # TMP fix for presence validation of :provider diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 53c3d288f5..ccaf768e09 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -1,10 +1,10 @@ # frozen_string_literal: true class ApplicationController < ActionController::Base - before_action do - # Unless the request format is explicitly json Rails will mitigate the responsability to CSR to handle it. - render 'components/index' unless valid_api_request? - end + # before_action do + # # Unless the request format is explicitly json Rails will mitigate the responsability to CSR to handle it. + # render 'components/index' unless valid_api_request? + # end # For requests that raised an unkown exception. # Note: The order of each rescue is important (The highest has the lowest priority). @@ -35,6 +35,10 @@ def current_user @current_user ||= User.find_by(id: session[:user_id]) end + def user_avatar(user) + user.avatar.attached? ? url_for(user.avatar) : ActionController::Base.helpers.image_path('default-avatar.png') + end + def render_json(data: {}, errors: [], status: :ok, include: nil) render json: { data:, diff --git a/app/javascript/components/forms/CreateRoomForm.jsx b/app/javascript/components/forms/CreateRoomForm.jsx index c6aaf71723..61922e9bca 100644 --- a/app/javascript/components/forms/CreateRoomForm.jsx +++ b/app/javascript/components/forms/CreateRoomForm.jsx @@ -20,7 +20,7 @@ export default function CreateRoomForm({ handleClose }) {