mirror of
https://github.com/opf/openproject.git
synced 2026-06-14 03:30:14 +00:00
159 lines
5.4 KiB
Ruby
159 lines
5.4 KiB
Ruby
#-- copyright
|
|
# OpenProject is an open source project management software.
|
|
# Copyright (C) the OpenProject GmbH
|
|
#
|
|
# This program is free software; you can redistribute it and/or
|
|
# modify it under the terms of the GNU General Public License version 3.
|
|
#
|
|
# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows:
|
|
# Copyright (C) 2006-2013 Jean-Philippe Lang
|
|
# Copyright (C) 2010-2013 the ChiliProject Team
|
|
#
|
|
# This program is free software; you can redistribute it and/or
|
|
# modify it under the terms of the GNU General Public License
|
|
# as published by the Free Software Foundation; either version 2
|
|
# of the License, or (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program; if not, write to the Free Software
|
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
#
|
|
# See COPYRIGHT and LICENSE files for more details.
|
|
#++
|
|
|
|
module API
|
|
module V3
|
|
module Projects
|
|
class ProjectSqlRepresenter
|
|
include API::Decorators::Sql::Hal
|
|
|
|
class << self
|
|
def ctes(walker_result)
|
|
{
|
|
visible_projects: visible_projects_sql,
|
|
ancestors: ancestors_sql(walker_result)
|
|
}
|
|
end
|
|
|
|
protected
|
|
|
|
def visible_projects_sql
|
|
Project.visible.to_sql
|
|
end
|
|
|
|
def ancestors_sql(walker_result)
|
|
<<~SQL.squish
|
|
SELECT id, CASE WHEN count(link) = 0 THEN '[]' ELSE json_agg(link) END ancestors
|
|
FROM
|
|
(
|
|
SELECT
|
|
origin.id,
|
|
#{ancestor_projection} link
|
|
FROM projects origin
|
|
LEFT OUTER JOIN projects ancestors
|
|
ON ancestors.lft < origin.lft AND ancestors.rgt > origin.rgt
|
|
WHERE origin.id IN (#{origin_subselect(walker_result).select(:id).to_sql})
|
|
ORDER by origin.id, ancestors.lft
|
|
) ancestors
|
|
GROUP BY id
|
|
SQL
|
|
end
|
|
|
|
def origin_subselect(walker_result)
|
|
if walker_result.page_size
|
|
walker_result.filter_scope.limit(sql_limit(walker_result)).offset(sql_offset(walker_result))
|
|
else
|
|
walker_result.filter_scope
|
|
end
|
|
end
|
|
|
|
def ancestor_projection
|
|
undisclosed_ancestor_title = OpenProject::SqlSanitization.sanitize(
|
|
"?", I18n.t(:"api_v3.undisclosed.ancestor")
|
|
)
|
|
|
|
if User.current.admin?
|
|
<<~SQL.squish
|
|
CASE
|
|
WHEN ancestors.id IS NOT NULL
|
|
THEN #{workspace_type_link_case('ancestors')}
|
|
ELSE NULL
|
|
END
|
|
SQL
|
|
else
|
|
<<~SQL.squish
|
|
CASE
|
|
WHEN ancestors.id IS NOT NULL AND ancestors.id IN (SELECT id FROM visible_projects)
|
|
THEN #{workspace_type_link_case('ancestors')}
|
|
WHEN ancestors.id IS NOT NULL AND ancestors.id NOT IN (SELECT id FROM visible_projects)
|
|
THEN json_build_object('href', '#{API::V3::URN_UNDISCLOSED}',
|
|
'title', #{undisclosed_ancestor_title})
|
|
ELSE NULL
|
|
END
|
|
SQL
|
|
end
|
|
end
|
|
|
|
def workspace_type_link_case(table = nil)
|
|
table = "#{table}." if table
|
|
|
|
<<~SQL.squish
|
|
CASE
|
|
WHEN #{table}workspace_type = 'project'
|
|
THEN json_build_object('href', format('#{api_v3_paths.project('%s')}', #{table}id),
|
|
'title', #{table}name)
|
|
WHEN #{table}workspace_type = 'program'
|
|
THEN json_build_object('href', format('#{api_v3_paths.program('%s')}', #{table}id),
|
|
'title', #{table}name)
|
|
WHEN #{table}workspace_type = 'portfolio'
|
|
THEN json_build_object('href', format('#{api_v3_paths.portfolio('%s')}', #{table}id),
|
|
'title', #{table}name)
|
|
END
|
|
SQL
|
|
end
|
|
end
|
|
|
|
link :self,
|
|
sql: -> { workspace_type_link_case(nil) },
|
|
path: { api: :project, params: %w(id) },
|
|
column: -> { :id },
|
|
title: -> { :name }
|
|
|
|
link :ancestors,
|
|
sql: -> { "ancestors" },
|
|
join: {
|
|
table: :ancestors,
|
|
condition: "ancestors.id = projects.id",
|
|
select: "ancestors"
|
|
}
|
|
|
|
property :_type,
|
|
representation: ->(*) {
|
|
<<~SQL.squish
|
|
CASE
|
|
WHEN workspace_type = 'project' THEN 'Project'
|
|
WHEN workspace_type = 'program' THEN 'Program'
|
|
WHEN workspace_type = 'portfolio' THEN 'Portfolio'
|
|
END
|
|
SQL
|
|
}
|
|
|
|
property :id
|
|
|
|
property :name
|
|
|
|
property :identifier
|
|
|
|
property :active
|
|
|
|
property :public
|
|
end
|
|
end
|
|
end
|
|
end
|