if (lst.length > 0) {
html = '<li><a href="#" class="btn btn-xs btn-info" id="clear_selections_button"><i class="fa fa-fw fa-ban"></i> Clear selections</a></li>';
if (this_object_uuid.match('-j7d0g-'))
- html += '<li><button class="btn btn-xs btn-info" type="submit" name="copy_selections_into_folder" id="copy_selections_into_folder"><i class="fa fa-fw fa-folder-open"></i> Copy selections into this folder</button></li>';
+ html += '<li><button class="btn btn-xs btn-info" type="submit" name="copy_selections_into_project" id="copy_selections_into_project"><i class="fa fa-fw fa-folder-open"></i> Copy selections into this project</button></li>';
html += '<li><button class="btn btn-xs btn-info" type="submit" name="combine_selected_files_into_collection" '
+ ' id="combine_selected_files_into_collection">'
+ '<i class="fa fa-fw fa-archive"></i> Combine selected collections and files into a new collection</button></li>'
-.arv-folder-list > .row {
+.arv-project-list > .row {
padding-top: 5px;
padding-bottom: 5px;
padding-right: 1em;
}
-.arv-folder-list > .row.folder:hover {
+.arv-project-list > .row.project:hover {
background: #d9edf7;
}
div.scroll-20em {
redirect_to :back
end
- expose_action :copy_selections_into_folder do
+ expose_action :copy_selections_into_project do
link_selections = Link.filter([['uuid','in',params["selection"]]])
link_uuids = link_selections.collect(&:uuid)
end
end
- helper_method :my_folders
- def my_folders
- return @my_folders if @my_folders
- @my_folders = []
+ helper_method :my_projects
+ def my_projects
+ return @my_projects if @my_projects
+ @my_projects = []
root_of = {}
- Group.filter([['group_class','=','folder']]).each do |g|
+ Group.filter([['group_class','in',['project','folder']]]).each do |g|
root_of[g.uuid] = g.owner_uuid
- @my_folders << g
+ @my_projects << g
end
done = false
while not done
end
end
end
- @my_folders = @my_folders.select do |g|
+ @my_projects = @my_projects.select do |g|
root_of[g.uuid] == current_user.uuid
end
end
helper_method :recent_jobs_and_pipelines
def recent_jobs_and_pipelines
- in_my_folders = ['owner_uuid','in',my_folders.collect(&:uuid)]
- (Job.limit(10).filter([in_my_folders]) |
- PipelineInstance.limit(10).filter([in_my_folders])).
+ in_my_projects = ['owner_uuid','in',my_projects.collect(&:uuid)]
+ (Job.limit(10).filter([in_my_projects]) |
+ PipelineInstance.limit(10).filter([in_my_projects])).
sort_by do |x|
x.finished_at || x.started_at || x.created_at rescue x.created_at
end
end
@output_of = jobs_with.call(output: @object.uuid)
@log_of = jobs_with.call(log: @object.uuid)
- folder_links = Link.limit(RELATION_LIMIT).order("modified_at DESC")
+ project_links = Link.limit(RELATION_LIMIT).order("modified_at DESC")
.where(head_uuid: @object.uuid, link_class: 'name').results
- folder_hash = Group.where(uuid: folder_links.map(&:tail_uuid)).to_hash
- @folders = folder_links.map { |link| folder_hash[link.tail_uuid] }
+ project_hash = Group.where(uuid: project_links.map(&:tail_uuid)).to_hash
+ @projects = project_links.map { |link| project_hash[link.tail_uuid] }
@permissions = Link.limit(RELATION_LIMIT).order("modified_at DESC")
.where(head_uuid: @object.uuid, link_class: 'permission',
name: 'can_read').results
class GroupsController < ApplicationController
def index
- @groups = Group.filter [['group_class', 'not in', ['folder']]]
+ @groups = Group.filter [['group_class', 'not in', ['folder', 'project']]]
@group_uuids = @groups.collect &:uuid
@links_from = Link.where link_class: 'permission', tail_uuid: @group_uuids
@links_to = Link.where link_class: 'permission', head_uuid: @group_uuids
end
def show
- return redirect_to(folder_path(@object)) if @object.group_class == 'folder'
- super
+ if @object.group_class.in?(['project','folder'])
+ redirect_to(project_path(@object))
+ else
+ super
+ end
end
end
-class FoldersController < ApplicationController
+class ProjectsController < ApplicationController
def model_class
Group
end
def index_pane_list
- %w(Folders)
+ %w(Projects)
end
def show_pane_list
def remove_item
params[:item_uuids] = [params[:item_uuid]]
remove_items
- render template: 'folders/remove_items'
+ render template: 'projects/remove_items'
end
def remove_items
item.link_class == 'name' and
item.tail_uuid == @object.uuid)
# Given uuid is a name link, linking an object to this
- # folder. First follow the link to find the item we're removing,
+ # project. First follow the link to find the item we're removing,
# then delete the link.
links << item
item = ArvadosBase.find item.head_uuid
link.destroy
end
if item.owner_uuid == @object.uuid
- # Object is owned by this folder. Remove it from the folder by
+ # Object is owned by this project. Remove it from the project by
# changing owner to the current user.
item.update_attributes owner_uuid: current_user.uuid
@removed_uuids << item.uuid
end
def find_objects_for_index
- @objects = Group.where(group_class: 'folder').order('name')
+ @objects = Group.
+ filter([['group_class','in',['project','folder']]]).
+ order('name')
super
parent_of = {current_user.uuid => 'me'}
@objects.each do |ob|
end
paths
end
- @my_folder_tree =
+ @my_project_tree =
sorted_paths.call buildtree.call(children_of, 'me')
- @shared_folder_tree =
+ @shared_project_tree =
sorted_paths.call({'Shared with me' =>
buildtree.call(children_of, false)})
end
formats: [:html],
locals: {
objects_and_names: @objects_and_names,
- folder: @object
+ project: @object
}),
next_page_href: (next_page_offset and
url_for(offset: next_page_offset, partial: true))
end
def create
- @new_resource_attrs = (params['folder'] || {}).merge(group_class: 'folder')
- @new_resource_attrs[:name] ||= 'New folder'
+ @new_resource_attrs = (params['project'] || {}).merge(group_class: 'project')
+ @new_resource_attrs[:name] ||= 'New project'
super
end
def update
- @updates = params['folder']
+ @updates = params['project']
super
end
end
attrvalue = object.send(attr) if attrvalue.nil?
if !object.attribute_editable?(attr, :ever) or
(!object.editable? and
- !object.owner_uuid.in?(my_folders.collect(&:uuid)))
+ !object.owner_uuid.in?(my_projects.collect(&:uuid)))
return ((attrvalue && attrvalue.length > 0 && attrvalue) ||
(attr == 'name' and object.andand.default_name) ||
'(none)')
if !object or
!object.attribute_editable?(attr, :ever) or
(!object.editable? and
- !object.owner_uuid.in?(my_folders.collect(&:uuid)))
+ !object.owner_uuid.in?(my_projects.collect(&:uuid)))
return link_to_if_arvados_object attrvalue
end
+++ /dev/null
-module FoldersHelper
-end
--- /dev/null
+module ProjectsHelper
+end
current_user
end
- def self.goes_in_folders?
+ def self.goes_in_projects?
false
end
!!locator.to_s.match("^#{MD5_EMPTY}(\\+.*)?\$")
end
- def self.goes_in_folders?
+ def self.goes_in_projects?
true
end
class Group < ArvadosBase
- def self.goes_in_folders?
+ def self.goes_in_projects?
true
end
end
def class_for_display
- group_class == 'folder' ? 'Folder' : super
+ group_class.in?(['folder', 'project']) ? 'Project' : super
end
def editable?
class Human < ArvadosBase
- def self.goes_in_folders?
+ def self.goes_in_projects?
true
end
end
class Job < ArvadosBase
- def self.goes_in_folders?
+ def self.goes_in_projects?
true
end
class PipelineInstance < ArvadosBase
attr_accessor :pipeline_template
- def self.goes_in_folders?
+ def self.goes_in_projects?
true
end
class PipelineTemplate < ArvadosBase
- def self.goes_in_folders?
+ def self.goes_in_projects?
true
end
class Specimen < ArvadosBase
- def self.goes_in_folders?
+ def self.goes_in_projects?
true
end
end
class Trait < ArvadosBase
- def self.goes_in_folders?
+ def self.goes_in_projects?
true
end
end
<% content_for :content_top do %>
- <% if @object and not @object.is_a?(Group) and @object.class.goes_in_folders? and @object.owner_uuid == current_user.uuid %>
+ <% if @object and not @object.is_a?(Group) and @object.class.goes_in_projects? and @object.owner_uuid == current_user.uuid %>
<div class="pull-right" style="width: 40%">
<div class="alert alert-warning alert-dismissable">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
- <strong>Hey.</strong> This <%= @object.class_for_display.downcase %> belongs to your account, but it's not in any of your folders. If you want it to be easy to find in the future, you should move it to a folder.<br />
- <%= button_to(choose_folders_path(
+ <strong>Hey.</strong> This <%= @object.class_for_display.downcase %> belongs to your account, but it's not in any of your projects. If you want it to be easy to find in the future, you should move it to a project.<br />
+ <%= button_to(choose_projects_path(
title: 'Move to...',
editable: true,
action_name: 'Move',
action_method: 'patch',
action_data: {selection_param: @object.resource_param_name+'[owner_uuid]', success: 'page-refresh'}.to_json),
{ class: "btn btn-primary btn-sm", remote: true, method: 'get' }) do %>
- <i class="fa fa-fw fa-folder"></i> Choose a folder...
+ <i class="fa fa-fw fa-folder"></i> Choose a project...
<% end %>
</div>
</div>
-<%if object and object.class.goes_in_folders? %>
+<%if object and object.class.goes_in_projects? %>
<% fn = if defined? friendly_name
friendly_name
else
<table class="table table-condensed arv-index">
<thead>
<tr>
- <% if objects.first and objects.first.class.goes_in_folders? %>
+ <% if objects.first and objects.first.class.goes_in_projects? %>
<th></th>
<% end %>
<th></th>
<tbody>
<% objects.each do |object| %>
<tr data-object-uuid="<%= object.uuid %>">
- <% if objects.first.class.goes_in_folders? %>
+ <% if objects.first.class.goes_in_projects? %>
<td>
<%= render :partial => "selection_checkbox", :locals => {:object => object} %>
</td>
</div>
<div style="height:0.5em;"></div>
- <% if @folders.andand.any? %>
- <p>Included in folders:<br />
- <%= render_arvados_object_list_start(@folders, 'Show all folders',
+ <% if @projects.andand.any? %>
+ <p>Included in projects:<br />
+ <%= render_arvados_object_list_start(@projects, 'Show all projects',
links_path(filter: [['head_uuid', '=', @object.uuid],
- ['link_class', '=', 'name']].to_json)) do |folder| %>
- <%= link_to_if_arvados_object(folder, friendly_name: true) %><br />
+ ['link_class', '=', 'name']].to_json)) do |project| %>
+ <%= link_to_if_arvados_object(project, friendly_name: true) %><br />
<% end %>
</p>
<% end %>
+++ /dev/null
-<div class="container-fluid arv-folder-list">
- <% tree.each do |foldernode| %>
- <% rowtype = foldernode[:object].class %>
- <% next if rowtype != Group and !show_root_node %>
- <div class="<%= 'folder' if rowtype == Group %> row">
- <div class="col-md-12" style="padding-left: <%= foldernode[:depth] - (show_root_node ? 0 : 1) %>em;">
- <% if show_root_node and rowtype == String %>
- <i class="fa fa-fw fa-folder-open-o"></i>
- <%= foldernode[:object] %>
- <% elsif show_root_node and rowtype == User %>
- <% if foldernode[:object].uuid == current_user.andand.uuid %>
- <i class="fa fa-fw fa-folder-open-o"></i>
- My Folders
- <% else %>
- <i class="fa fa-fw fa-folder-o"></i>
- <%= foldernode[:object].friendly_link_name %>
- <% end %>
- <% elsif rowtype == Group %>
- <i class="fa fa-fw fa-folder-o"></i>
- <% opts = {} %>
- <% opts[:title] = foldernode[:object].description %>
- <% opts[:'data-toggle'] = 'tooltip' %>
- <% opts[:'data-placement'] = 'bottom' %>
- <%= link_to foldernode[:object], opts do %>
- <%= foldernode[:object].friendly_link_name %>
- <% end %>
- <% end %>
- </div>
- </div>
- <% end %>
-</div>
<% if @object and \
((@name_link and (o = Group.find?(@name_link.tail_uuid)))\
or (o = Group.find?(@object.owner_uuid))) %>
- <%= link_to(o.name, folder_path(o.uuid)) %>
+ <%= link_to(o.name, project_path(o.uuid)) %>
<% else %>
<%= link_to(
controller.controller_name.humanize.downcase,
<span class="glyphicon glyphicon-arrow-right"></span>
</li>
<li>
+
<%= link_to_if_arvados_object (@name_link || @object), {friendly_name: true}, {data: {object_uuid: (@name_link.andand.uuid || @object.andand.uuid), name: 'name'}} %>
</li>
<% end %>
<% content_for :breadcrumbs do %>
<li class="nav-separator"><span class="glyphicon glyphicon-arrow-right"></span></li>
<li>
- <%= link_to(o.name, folder_path(o.uuid)) %>
+ <%= link_to(o.name, project_path(o.uuid)) %>
</li>
<li class="nav-separator">
<span class="glyphicon glyphicon-arrow-right"></span>
<div class="modal-header">
<button type="button" class="close" onClick="reset_form()" data-dismiss="modal" aria-hidden="true">×</button>
- <h4 class="modal-title"><%= params[:title] || 'Choose folder' %></h4>
+ <h4 class="modal-title"><%= params[:title] || 'Choose project' %></h4>
</div>
<div class="modal-body">
<div class="selectable-container" style="height: 15em; overflow-y: scroll">
- <% [@my_folder_tree, @shared_folder_tree].each do |tree| %>
- <% tree.each do |foldernode| %>
- <% if foldernode[:object].is_a? String %>
- <div class="row" style="padding-left: <%= 1 + foldernode[:depth] %>em;">
+ <% [@my_project_tree, @shared_project_tree].each do |tree| %>
+ <% tree.each do |projectnode| %>
+ <% if projectnode[:object].is_a? String %>
+ <div class="row" style="padding-left: <%= 1 + projectnode[:depth] %>em;">
<i class="fa fa-fw fa-folder-open-o"></i>
- <%= foldernode[:object] %>
+ <%= projectnode[:object] %>
</div>
<% else %>
- <div class="<%= 'selectable folder' if !params[:editable] || foldernode[:object].editable? %> row" style="padding-left: <%= 1 + foldernode[:depth] %>em;" data-object-uuid="<%= foldernode[:object].uuid %>">
+ <div class="<%= 'selectable project' if !params[:editable] || projectnode[:object].editable? %> row" style="padding-left: <%= 1 + projectnode[:depth] %>em;" data-object-uuid="<%= projectnode[:object].uuid %>">
<i class="fa fa-fw fa-folder-o"></i>
- <% if foldernode[:object].uuid == current_user.uuid %>
- My Folders
+ <% if projectnode[:object].uuid == current_user.uuid %>
+ My Projects
<% else %>
- <%= foldernode[:object].friendly_link_name || 'New folder' %>
+ <%= projectnode[:object].friendly_link_name || 'New project' %>
<% end %>
</div>
<% end %>
--- /dev/null
+<div class="container-fluid arv-project-list">
+ <% tree.each do |projectnode| %>
+ <% rowtype = projectnode[:object].class %>
+ <% next if rowtype != Group and !show_root_node %>
+ <div class="<%= 'project' if rowtype == Group %> row">
+ <div class="col-md-12" style="padding-left: <%= projectnode[:depth] - (show_root_node ? 0 : 1) %>em;">
+ <% if show_root_node and rowtype == String %>
+ <i class="fa fa-fw fa-folder-open-o"></i>
+ <%= projectnode[:object] %>
+ <% elsif show_root_node and rowtype == User %>
+ <% if projectnode[:object].uuid == current_user.andand.uuid %>
+ <i class="fa fa-fw fa-folder-open-o"></i>
+ My Projects
+ <% else %>
+ <i class="fa fa-fw fa-folder-o"></i>
+ <%= projectnode[:object].friendly_link_name %>
+ <% end %>
+ <% elsif rowtype == Group %>
+ <i class="fa fa-fw fa-folder-o"></i>
+ <% opts = {} %>
+ <% opts[:title] = projectnode[:object].description %>
+ <% opts[:'data-toggle'] = 'tooltip' %>
+ <% opts[:'data-placement'] = 'bottom' %>
+ <%= link_to projectnode[:object], opts do %>
+ <%= projectnode[:object].friendly_link_name %>
+ <% end %>
+ <% end %>
+ </div>
+ </div>
+ <% end %>
+</div>
<% content_for :content_top do %>
<h2>
- <%= render_editable_attribute @object, 'name', nil, { 'data-emptytext' => "New folder" } %>
+ <%= render_editable_attribute @object, 'name', nil, { 'data-emptytext' => "New project" } %>
</h2>
<div class="arv-description-as-subtitle">
<% content_for :tab_line_buttons do %>
<% if @objects_and_names.empty? %>
- <%= button_to(folder_path(id: @object.uuid, return_to: folders_path), method: 'delete', class: 'btn btn-sm btn-primary', data: {confirm: "Really delete folder '#{@object.name}'?"}) do %>
- <i class="fa fa-fw fa-trash-o"></i> Delete folder
+ <%= button_to(project_path(id: @object.uuid, return_to: projects_path), method: 'delete', class: 'btn btn-sm btn-primary', data: {confirm: "Really delete project '#{@object.name}'?"}) do %>
+ <i class="fa fa-fw fa-trash-o"></i> Delete project
<% end %>
<% end %>
<% end %>
<% if @object.editable? %>
<%= link_to(
choose_collections_path(
- title: 'Add data to folder:',
+ title: 'Add data to project:',
multiple: true,
action_name: 'Add',
action_href: actions_path(id: @object.uuid),
action_method: 'post',
- action_data: {selection_param: 'selection[]', copy_selections_into_folder: @object.uuid, success: 'page-refresh'}.to_json),
+ action_data: {selection_param: 'selection[]', copy_selections_into_project: @object.uuid, success: 'page-refresh'}.to_json),
{ class: "btn btn-primary btn-sm", remote: true, method: 'get', data: {'event-after-select' => 'page-refresh'} }) do %>
<i class="fa fa-fw fa-plus"></i> Add data
<% end %>
<div class="col-sm-3">
<form class="form-inline" role="form">
Show:
- <select class="form-control form-control-sm filterable-control" data-filterable-attribute="data-kind" data-filterable-target="table.arv-index.arv-folder-contents tbody">
+ <select class="form-control form-control-sm filterable-control" data-filterable-attribute="data-kind" data-filterable-target="table.arv-index.arv-project-contents tbody">
<option value="">Everything</option>
<option value="arvados#collection">Data</option>
<option value="arvados#pipelineInstance arvados#job">Compute jobs</option>
</form>
</div>
<div class="col-sm-4">
- <input type="text" class="form-control filterable-control" placeholder="Search folder contents" data-filterable-target="table.arv-index.arv-folder-contents tbody"/>
+ <input type="text" class="form-control filterable-control" placeholder="Search project contents" data-filterable-target="table.arv-index.arv-project-contents tbody"/>
</div>
</div>
- <table class="table table-condensed table-fixedlayout arv-index arv-folder-contents" style="overflow-x: hidden">
+ <table class="table table-condensed table-fixedlayout arv-index arv-project-contents" style="overflow-x: hidden">
<colgroup>
<col width="40%" />
<col width="60%" />
</colgroup>
<tbody data-infinite-scroller="#Contents-scroll" data-infinite-content-href="<%= url_for(format: :json, partial: :contents_rows, offset: next_page_offset) if next_page_offset %>">
- <%= render partial: 'show_contents_rows', locals: {folder: @object, objects_and_names: @objects_and_names} %>
+ <%= render partial: 'show_contents_rows', locals: {project: @object, objects_and_names: @objects_and_names} %>
</tbody>
<thead>
<tr>
<td>
<%= render partial: 'selection_checkbox', locals: {object: object, friendly_name: ((name_object.name rescue '') || '')} %>
- <% if folder.editable? %>
- <%= link_to({action: 'remove_item', id: folder.uuid, item_uuid: ((name_link && name_link.uuid) || object.uuid)}, method: :delete, remote: true, data: {confirm: "Remove #{object.class_for_display.downcase} #{name_object.name rescue object.uuid} from this folder?", toggle: 'tooltip', placement: 'top'}, class: 'btn btn-sm btn-default btn-nodecorate', title: 'remove') do %>
+ <% if project.editable? %>
+ <%= link_to({action: 'remove_item', id: project.uuid, item_uuid: ((name_link && name_link.uuid) || object.uuid)}, method: :delete, remote: true, data: {confirm: "Remove #{object.class_for_display.downcase} #{name_object.name rescue object.uuid} from this project?", toggle: 'tooltip', placement: 'top'}, class: 'btn btn-sm btn-default btn-nodecorate', title: 'remove') do %>
<i class="fa fa-fw fa-ban"></i>
<% end %>
<% else %>
Inherited permissions
</div>
<div class="panel-body">
- <p>Permissions for this folder are inherited by the owner or parent folder:
+ <p>Permissions for this project are inherited by the owner or parent project:
</p>
<p style="margin-left: 4em">
<% if User == resource_class_for_uuid(@object.owner_uuid) %>
<% end %>
<%= link_to_if_arvados_object @object.owner_uuid, friendly_name: true %>
<%= button_to('Move to...',
- choose_folders_path(
+ choose_projects_path(
title: 'Move to...',
editable: true,
action_name: 'Move',
- action_href: folder_path(@object.uuid),
+ action_href: project_path(@object.uuid),
action_method: 'put',
- action_data: {selection_param: 'folder[owner_uuid]', success: 'page-refresh'}.to_json),
- { class: "btn btn-default btn-xs arv-move-to-folder", remote: true, method: 'get' }) %>
+ action_data: {selection_param: 'project[owner_uuid]', success: 'page-refresh'}.to_json),
+ { class: "btn btn-default btn-xs arv-move-to-project", remote: true, method: 'get' }) %>
</p>
</div>
</div>
<div>
<div class="row">
<div class="col-sm-6">
- <% if my_folders.empty? %>
+ <% if my_projects.empty? %>
<div class="panel panel-info">
<div class="panel-heading">
<h3 class="panel-title">
This site runs Arvados, the open source biomedical analysis platform. <a href="https://arvados.org" target="_blank">Learn more…</a>
</p>
<p>
- <b>To get started,</b> create a folder using the "Add new folder" button below.
+ <b>To get started,</b> create a project using the "Add new project" button below.
</p>
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading">
<div class="pull-right">
- <%= button_to folders_path(method: 'post'), class: 'btn btn-xs btn-primary' do %>
+ <%= button_to projects_path(method: 'post'), class: 'btn btn-xs btn-primary' do %>
<i class="fa fa-fw fa-plus"></i>
- Add new folder
+ Add new project
<% end %>
</div>
<h3 class="panel-title">
- My folders
+ My projects
</h3>
</div>
<div class="panel-body scroll-20em">
- <%= render partial: 'index_folders', locals: {tree: @my_folder_tree, show_root_node: false} %>
+ <%= render partial: 'index_projects', locals: {tree: @my_project_tree, show_root_node: false} %>
</div>
</div>
</div>
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">
- Shared folders
+ Shared projects
</h3>
</div>
<div class="panel-body scroll-20em">
- <%= render partial: 'index_folders', locals: {tree: @shared_folder_tree, show_root_node: false} %>
+ <%= render partial: 'index_projects', locals: {tree: @shared_project_tree, show_root_node: false} %>
</div>
</div>
</div>
format: false)
get '/collections/download/:uuid/:reader_token' => 'collections#show_file_links'
get '/collections/:uuid/*file' => 'collections#show_file', :format => false
- resources :folders do
+ resources :projects do
match 'remove/:item_uuid', on: :member, via: :delete, action: :remove_item
match 'remove_items', on: :member, via: :delete, action: :remove_items
get 'choose', on: :collection
post 'actions' => 'actions#post'
get 'websockets' => 'websocket#index'
- root :to => 'folders#index'
+ root :to => 'projects#index'
# Send unroutable requests to an arbitrary controller
# (ends up at ApplicationController#render_not_found)
assert_equal([['.', 'foo', 3]], assigns(:object).files)
end
- test "viewing a collection fetches related folders" do
+ test "viewing a collection fetches related projects" do
show_collection(:foo_file, :active)
- assert_includes(assigns(:folders).map(&:uuid),
- api_fixture('groups')['afolder']['uuid'],
- "controller did not find linked folder")
+ assert_includes(assigns(:projects).map(&:uuid),
+ api_fixture('groups')['aproject']['uuid'],
+ "controller did not find linked project")
end
test "viewing a collection fetches related permissions" do
require 'test_helper'
-class FoldersControllerTest < ActionController::TestCase
+class ProjectsControllerTest < ActionController::TestCase
test "inactive user is asked to sign user agreements on front page" do
get :index, {}, session_for(:inactive)
assert_response :success
test "Collection page renders default name links" do
uuid = api_fixture('collections')['foo_file']['uuid']
- coll_name = api_fixture('links')['foo_collection_name_in_afolder']['name']
+ coll_name = api_fixture('links')['foo_collection_name_in_aproject']['name']
visit page_with_token('active', "/collections/#{uuid}")
assert(page.has_text?(coll_name), "Collection page did not include name")
# Now check that the page is otherwise normal, and the collection name
instance_page = current_path
- # put this pipeline instance in "A Folder"
- find('button', text: 'Choose a folder...').click
+ # put this pipeline instance in "A Project"
+ find('button', text: 'Choose a project...').click
within('.modal-dialog') do
- find('.selectable', text: 'A Folder').click
+ find('.selectable', text: 'A Project').click
find('button', text: 'Move').click
end
end
find('#persistent-selection-count').click
- # Add this collection to the folder
- visit '/folders'
- find('.arv-folder-list a,button', text: 'A Folder').click
+ # Add this collection to the project
+ visit '/projects'
+ find('.arv-project-list a,button', text: 'A Project').click
find('.btn', text: 'Add data').click
find('span', text: 'foo_tag').click
within('.modal-dialog') do
assert_not page.has_text? 'Graph'
end
- # Create a pipeline instance from within a folder and run
- test 'Create pipeline inside a folder and run' do
+ # Create a pipeline instance from within a project and run
+ test 'Create pipeline inside a project and run' do
visit page_with_token('active_trustedclient')
# Go over to the collections page and select something
end
find('#persistent-selection-count').click
- # Add this collection to the folder using collections menu from top nav
- visit '/folders'
- find('.arv-folder-list a,button', text: 'A Folder').click
+ # Add this collection to the project using collections menu from top nav
+ visit '/projects'
+ find('.arv-project-list a,button', text: 'A Project').click
find('#collections-menu').click
- click_button 'Copy selections into this folder'
+ click_button 'Copy selections into this project'
# create a pipeline instance
find('.btn', text: 'Run a pipeline').click
require 'selenium-webdriver'
require 'headless'
-class FoldersTest < ActionDispatch::IntegrationTest
+class ProjectsTest < ActionDispatch::IntegrationTest
setup do
Capybara.current_driver = Capybara.javascript_driver
end
- test 'Find a folder and edit its description' do
+ test 'Find a project and edit its description' do
visit page_with_token 'active', '/'
- find('.arv-folder-list a,button', text: 'A Folder').
+ find('.arv-project-list a,button', text: 'A Project').
click
- within('.container-fluid', text: api_fixture('groups')['afolder']['name']) do
- find('span', text: api_fixture('groups')['afolder']['name']).click
+ within('.container-fluid', text: api_fixture('groups')['aproject']['name']) do
+ find('span', text: api_fixture('groups')['aproject']['name']).click
within('.arv-description-as-subtitle') do
find('.fa-pencil').click
find('.editable-input textarea').set('I just edited this.')
end
test 'Add a new name, then edit it, without creating a duplicate' do
- folder_uuid = api_fixture('groups')['afolder']['uuid']
- specimen_uuid = api_fixture('specimens')['owned_by_afolder_with_no_name_link']['uuid']
- visit page_with_token 'active', '/folders/' + folder_uuid
+ project_uuid = api_fixture('groups')['aproject']['uuid']
+ specimen_uuid = api_fixture('specimens')['owned_by_aproject_with_no_name_link']['uuid']
+ visit page_with_token 'active', '/projects/' + project_uuid
within(".selection-action-container") do
within (first('tr', text: 'Specimen')) do
find(".fa-pencil").click
end
end
- test 'Create a folder and move it into a different folder' do
- visit page_with_token 'active', '/folders'
- find('.btn', text: "Add new folder").click
+ test 'Create a project and move it into a different project' do
+ visit page_with_token 'active', '/projects'
+ find('.btn', text: "Add new project").click
- # within('.editable', text: 'New folder') do
+ # within('.editable', text: 'New project') do
within('h2') do
find('.fa-pencil').click
- find('.editable-input input').set('Folder 1234')
+ find('.editable-input input').set('Project 1234')
find('.glyphicon-ok').click
end
wait_for_ajax
- visit '/folders'
- find('.btn', text: "Add new folder").click
+ visit '/projects'
+ find('.btn', text: "Add new project").click
within('h2') do
find('.fa-pencil').click
- find('.editable-input input').set('Folder 5678')
+ find('.editable-input input').set('Project 5678')
find('.glyphicon-ok').click
end
wait_for_ajax
click_link 'Permissions'
find('input[value="Move to..."]').click
- find('.selectable', text: 'Folder 1234').click
+ find('.selectable', text: 'Project 1234').click
find('a,button', text: 'Move').click
wait_for_ajax
# Wait for the page to refresh and show the new parent in Permissions panel
click_link 'Permissions'
- find('.panel', text: 'Folder 1234')
+ find('.panel', text: 'Project 1234')
- assert(find('.panel', text: 'Permissions for this folder are inherited by the owner or parent folder').
- all('*', text: 'Folder 1234').any?,
- "Folder 5678 should now be inside folder 1234")
+ assert(find('.panel', text: 'Permissions for this project are inherited by the owner or parent project').
+ all('*', text: 'Project 1234').any?,
+ "Project 5678 should now be inside project 1234")
end
end
test 'links_for on non-empty resource list' do
use_token :active
- results = Group.find(api_fixture('groups')['afolder']['uuid']).contents(include_linked: true)
+ results = Group.find(api_fixture('groups')['aproject']['uuid']).contents(include_linked: true)
assert_equal [], results.links_for(api_fixture('users')['active']['uuid'])
assert_equal [], results.links_for(api_fixture('jobs')['running_cancelled']['uuid'])
assert_equal [], results.links_for(api_fixture('jobs')['running']['uuid'], 'bogus-link-class')
end
test 'links_for returns all link classes (simulated results)' do
- folder_uuid = api_fixture('groups')['afolder']['uuid']
- specimen_uuid = api_fixture('specimens')['in_afolder']['uuid']
+ project_uuid = api_fixture('groups')['aproject']['uuid']
+ specimen_uuid = api_fixture('specimens')['in_aproject']['uuid']
api_response = {
kind: 'arvados#specimenList',
links: [{kind: 'arvados#link',
uuid: 'zzzzz-o0j2j-asdfasdfasdfas0',
- tail_uuid: folder_uuid,
+ tail_uuid: project_uuid,
head_uuid: specimen_uuid,
link_class: 'name',
name: 'Alice'},
{kind: 'arvados#link',
uuid: 'zzzzz-o0j2j-asdfasdfasdfas1',
- tail_uuid: folder_uuid,
+ tail_uuid: project_uuid,
head_uuid: specimen_uuid,
link_class: 'foo',
name: 'Bob'},
{kind: 'arvados#link',
uuid: 'zzzzz-o0j2j-asdfasdfasdfas2',
- tail_uuid: folder_uuid,
+ tail_uuid: project_uuid,
head_uuid: specimen_uuid,
link_class: nil,
name: 'Clydesdale'}],
test "get contents with names" do
use_token :active
oi = Group.
- find(api_fixture('groups')['asubfolder']['uuid']).
+ find(api_fixture('groups')['asubproject']['uuid']).
contents(include_linked: true)
assert_operator(0, :<, oi.count,
"Expected to find some items belonging to :active user")
"Expected to receive name links with contents response")
oi_uuids = oi.collect { |i| i['uuid'] }
- expect_uuid = api_fixture('specimens')['in_asubfolder']['uuid']
+ expect_uuid = api_fixture('specimens')['in_asubproject']['uuid']
assert_includes(oi_uuids, expect_uuid,
- "Expected '#{expect_uuid}' in asubfolder's contents")
+ "Expected '#{expect_uuid}' in asubproject's contents")
- expect_uuid = api_fixture('specimens')['in_afolder_linked_from_asubfolder']['uuid']
- expect_name = api_fixture('links')['specimen_is_in_two_folders']['name']
+ expect_uuid = api_fixture('specimens')['in_aproject_linked_from_asubproject']['uuid']
+ expect_name = api_fixture('links')['specimen_is_in_two_projects']['name']
assert_includes(oi_uuids, expect_uuid,
- "Expected '#{expect_uuid}' in asubfolder's contents")
+ "Expected '#{expect_uuid}' in asubproject's contents")
assert_equal(expect_name, oi.name_for(expect_uuid),
"Expected name_for '#{expect_uuid}' to be '#{expect_name}'")
end
+++ /dev/null
-require 'test_helper'
-
-class FoldersHelperTest < ActionView::TestCase
-end
--- /dev/null
+require 'test_helper'
+
+class ProjectsHelperTest < ActionView::TestCase
+end
--- /dev/null
+class RenameFolderToProject < ActiveRecord::Migration
+ def up
+ Group.update_all("group_class = 'project'", "group_class = 'folder'")
+ end
+
+ def down
+ Group.update_all("group_class = 'folder'", "group_class = 'project'")
+ end
+end
owner_uuid: zzzzz-tpzed-000000000000000
name: Administrators of a subset of users
-afolder:
+aproject:
uuid: zzzzz-j7d0g-v955i6s2oi1cbso
owner_uuid: zzzzz-tpzed-xurymjxw79nv3jz
created_at: 2014-04-21 15:37:48 -0400
modified_by_user_uuid: zzzzz-tpzed-xurymjxw79nv3jz
modified_at: 2014-04-21 15:37:48 -0400
updated_at: 2014-04-21 15:37:48 -0400
- name: A Folder
- description: Test folder belonging to active user
- group_class: folder
+ name: A Project
+ description: Test project belonging to active user
+ group_class: project
-asubfolder:
+asubproject:
uuid: zzzzz-j7d0g-axqo7eu9pwvna1x
owner_uuid: zzzzz-j7d0g-v955i6s2oi1cbso
created_at: 2014-04-21 15:37:48 -0400
modified_by_user_uuid: zzzzz-tpzed-xurymjxw79nv3jz
modified_at: 2014-04-21 15:37:48 -0400
updated_at: 2014-04-21 15:37:48 -0400
- name: A Subfolder
- description: "Test folder belonging to active user's first test folder"
+ name: A Subproject
+ description: "Test project belonging to active user's first test project"
group_class: folder
bad_group_has_ownership_cycle_a:
name: test
properties: {}
-specimen_is_in_two_folders:
+specimen_is_in_two_projects:
uuid: zzzzz-o0j2j-ryhm1bn83ni03sn
owner_uuid: zzzzz-j7d0g-axqo7eu9pwvna1x
created_at: 2014-04-21 15:37:48 -0400
tail_uuid: zzzzz-j7d0g-axqo7eu9pwvna1x
head_uuid: zzzzz-j58dm-5gid26432uujf79
link_class: name
- name: "I'm in a subfolder, too"
+ name: "I'm in a subproject, too"
properties: {}
-template_name_in_afolder:
+template_name_in_aproject:
uuid: zzzzz-o0j2j-4kpwf3d6rwkeqhl
owner_uuid: zzzzz-tpzed-xurymjxw79nv3jz
created_at: 2014-04-29 16:47:26 -0400
tail_uuid: zzzzz-j7d0g-v955i6s2oi1cbso
head_uuid: zzzzz-p5p6p-aox0k0ofxrystgw
link_class: name
- name: "I'm a template in a folder"
+ name: "I'm a template in a project"
properties: {}
-job_name_in_afolder:
+job_name_in_aproject:
uuid: zzzzz-o0j2j-1kt6dppqcxbl1yt
owner_uuid: zzzzz-tpzed-xurymjxw79nv3jz
created_at: 2014-04-29 16:47:26 -0400
tail_uuid: zzzzz-j7d0g-v955i6s2oi1cbso
head_uuid: zzzzz-8i9sb-pshmckwoma9plh7
link_class: name
- name: "I'm a job in a folder"
+ name: "I'm a job in a project"
properties: {}
-foo_collection_name_in_afolder:
- uuid: zzzzz-o0j2j-foofoldername12
+foo_collection_name_in_aproject:
+ uuid: zzzzz-o0j2j-fooprojectname1
owner_uuid: zzzzz-tpzed-xurymjxw79nv3jz
created_at: 2014-04-21 15:37:48 -0400
modified_by_client_uuid: zzzzz-ozdt8-brczlopd8u8d0jr
head_uuid: 1f4b0bc7583c2a7f9102c395f4ffc5e3+45
link_class: name
# This should resemble the default name assigned when a
- # Collection is added to a Folder.
+ # Collection is added to a Project.
name: "1f4b0bc7583c2a7f9102c395f4ffc5e3+45 added sometime"
properties: {}
created_at: 2014-04-21 15:37:48 -0400
modified_at: 2014-04-21 15:37:48 -0400
-in_afolder:
+in_aproject:
uuid: zzzzz-j58dm-7r18rnd5nzhg5yk
owner_uuid: zzzzz-j7d0g-v955i6s2oi1cbso
created_at: 2014-04-21 15:37:48 -0400
modified_at: 2014-04-21 15:37:48 -0400
-in_asubfolder:
+in_asubproject:
uuid: zzzzz-j58dm-c40lddwcqqr1ffs
owner_uuid: zzzzz-j7d0g-axqo7eu9pwvna1x
created_at: 2014-04-21 15:37:48 -0400
modified_at: 2014-04-21 15:37:48 -0400
-in_afolder_linked_from_asubfolder:
+in_aproject_linked_from_asubproject:
uuid: zzzzz-j58dm-5gid26432uujf79
owner_uuid: zzzzz-j7d0g-v955i6s2oi1cbso
created_at: 2014-04-21 15:37:48 -0400
modified_at: 2014-04-21 15:37:48 -0400
-owned_by_afolder_with_no_name_link:
+owned_by_aproject_with_no_name_link:
uuid: zzzzz-j58dm-ypsjlol9dofwijz
owner_uuid: zzzzz-j7d0g-v955i6s2oi1cbso
created_at: 2014-05-05 04:11:52 -0400
@controller = Arvados::V1::GroupsController.new
authorize_with :admin
get :index, {
- filters: [ ['group_class', 'not in', ['folder']] ],
+ filters: [ ['group_class', 'not in', ['project']] ],
controller: 'groups',
}
assert_response :success
found = assigns(:objects)
assert_includes(found.collect(&:group_class), nil,
- "'group_class not in ['folder']' filter should pass null")
+ "'group_class not in ['project']' filter should pass null")
end
end
assert_response 403
end
- test "get list of folders" do
+ test "get list of projects" do
authorize_with :active
- get :index, filters: [['group_class', '=', 'folder']], format: :json
+ get :index, filters: [['group_class', 'in', ['project', 'folder']]], format: :json
assert_response :success
group_uuids = []
json_response['items'].each do |group|
- assert_equal 'folder', group['group_class']
+ assert_includes ['folder', 'project'], group['group_class']
group_uuids << group['uuid']
end
- assert_includes group_uuids, groups(:afolder).uuid
- assert_includes group_uuids, groups(:asubfolder).uuid
+ assert_includes group_uuids, groups(:aproject).uuid
+ assert_includes group_uuids, groups(:asubproject).uuid
assert_not_includes group_uuids, groups(:system_group).uuid
assert_not_includes group_uuids, groups(:private).uuid
end
- test "get list of groups that are not folders" do
+ test "get list of groups that are not projects" do
authorize_with :active
get :index, filters: [['group_class', '=', nil]], format: :json
assert_response :success
assert_equal nil, group['group_class']
group_uuids << group['uuid']
end
- assert_not_includes group_uuids, groups(:afolder).uuid
- assert_not_includes group_uuids, groups(:asubfolder).uuid
+ assert_not_includes group_uuids, groups(:aproject).uuid
+ assert_not_includes group_uuids, groups(:asubproject).uuid
assert_includes group_uuids, groups(:private).uuid
end
test 'get group-owned objects' do
authorize_with :active
get :contents, {
- id: groups(:afolder).uuid,
+ id: groups(:aproject).uuid,
format: :json,
include_linked: true,
}
test 'get group-owned objects with limit' do
authorize_with :active
get :contents, {
- id: groups(:afolder).uuid,
+ id: groups(:aproject).uuid,
limit: 1,
format: :json,
}
test 'get group-owned objects with limit and offset' do
authorize_with :active
get :contents, {
- id: groups(:afolder).uuid,
+ id: groups(:aproject).uuid,
limit: 1,
offset: 12345,
format: :json,
test 'get group-owned objects with additional filter matching nothing' do
authorize_with :active
get :contents, {
- id: groups(:afolder).uuid,
+ id: groups(:aproject).uuid,
filters: [['uuid', 'in', ['foo_not_a_uuid','bar_not_a_uuid']]],
format: :json,
}
end
test 'get group-owned objects without include_linked' do
- unexpected_uuid = specimens(:in_afolder_linked_from_asubfolder).uuid
+ unexpected_uuid = specimens(:in_aproject_linked_from_asubproject).uuid
authorize_with :active
get :contents, {
- id: groups(:asubfolder).uuid,
+ id: groups(:asubproject).uuid,
format: :json,
}
assert_response :success
end
test 'get group-owned objects with include_linked' do
- expected_uuid = specimens(:in_afolder_linked_from_asubfolder).uuid
+ expected_uuid = specimens(:in_aproject_linked_from_asubproject).uuid
authorize_with :active
get :contents, {
- id: groups(:asubfolder).uuid,
+ id: groups(:asubproject).uuid,
include_linked: true,
format: :json,
}
uuids = json_response['items'].collect { |i| i['uuid'] }
assert_includes uuids, expected_uuid, "Did not get #{expected_uuid}"
- expected_name = links(:specimen_is_in_two_folders).name
+ expected_name = links(:specimen_is_in_two_projects).name
found_specimen_name = false
assert(json_response['links'].any?,
"Expected a non-empty array of links in response")
# times within a test.
@json_response = nil
get :contents, {
- id: groups(:afolder).uuid,
+ id: groups(:aproject).uuid,
include_linked: inc_ind,
limit: limit,
offset: offset,
owner_received[item['owner_uuid']] = true
offset += 1
if not inc_ind
- assert_equal groups(:afolder).uuid, item['owner_uuid']
+ assert_equal groups(:aproject).uuid, item['owner_uuid']
end
end
break if offset >= items_available
test "Raise error on bogus #{arg} parameter #{val.inspect}" do
authorize_with :active
get :contents, {
- :id => groups(:afolder).uuid,
+ :id => groups(:aproject).uuid,
:format => :json,
arg => val,
}
test 'get writable_by list for owned group' do
authorize_with :active
get :show, {
- id: groups(:afolder).uuid,
+ id: groups(:aproject).uuid,
format: :json
}
assert_response :success
end
test "refuse duplicate name" do
- the_name = links(:job_name_in_afolder).name
- the_folder = links(:job_name_in_afolder).tail_uuid
+ the_name = links(:job_name_in_aproject).name
+ the_project = links(:job_name_in_aproject).tail_uuid
authorize_with :active
post :create, link: {
- tail_uuid: the_folder,
+ tail_uuid: the_project,
head_uuid: specimens(:owned_by_active_user).uuid,
link_class: 'name',
name: the_name,
assert_equal false, s.save, "should not save object with #{g.uuid} as owner"
# Use the group as the new owner of an existing object
- s = specimens(:in_afolder)
+ s = specimens(:in_aproject)
s.owner_uuid = groups(:bad_group_has_ownership_cycle_b).uuid
assert s.valid?, "ownership should pass validation"
assert_equal false, s.save, "should not save object with #{g.uuid} as owner"
end
test 'name links with the same tail_uuid must be unique' do
- a = Link.create!(tail_uuid: groups(:afolder).uuid,
+ a = Link.create!(tail_uuid: groups(:aproject).uuid,
head_uuid: specimens(:owned_by_active_user).uuid,
link_class: 'name',
name: 'foo')
assert a.valid?, a.errors.to_s
assert_raises ActiveRecord::RecordNotUnique do
- b = Link.create!(tail_uuid: groups(:afolder).uuid,
+ b = Link.create!(tail_uuid: groups(:aproject).uuid,
head_uuid: specimens(:owned_by_active_user).uuid,
link_class: 'name',
name: 'foo')
end
test 'name links with different tail_uuid need not be unique' do
- a = Link.create!(tail_uuid: groups(:afolder).uuid,
+ a = Link.create!(tail_uuid: groups(:aproject).uuid,
head_uuid: specimens(:owned_by_active_user).uuid,
link_class: 'name',
name: 'foo')
assert a.valid?, a.errors.to_s
- b = Link.create!(tail_uuid: groups(:asubfolder).uuid,
+ b = Link.create!(tail_uuid: groups(:asubproject).uuid,
head_uuid: specimens(:owned_by_active_user).uuid,
link_class: 'name',
name: 'foo')
[nil, '', false].each do |name|
test "name links cannot have name=#{name.inspect}" do
- a = Link.create(tail_uuid: groups(:afolder).uuid,
+ a = Link.create(tail_uuid: groups(:aproject).uuid,
head_uuid: specimens(:owned_by_active_user).uuid,
link_class: 'name',
name: name)
end
end
- ['users(:active)', 'groups(:afolder)'].each do |ofixt|
+ ['users(:active)', 'groups(:aproject)'].each do |ofixt|
test "delete #{ofixt} that owns other objects" do
o = eval ofixt
assert_equal(true, Specimen.where(owner_uuid: o.uuid).any?,