diff --git a/src/api/app/views/webui/shared/_buildresult_box.html.haml b/src/api/app/views/webui/shared/_buildresult_box.html.haml new file mode 100644 index 00000000000..70846c4f2a7 --- /dev/null +++ b/src/api/app/views/webui/shared/_buildresult_box.html.haml @@ -0,0 +1,36 @@ +:ruby + index ||= '' + ajax_data = {} + ajax_data['project'] = h(project) if defined?(project) + ajax_data['package'] = h(package) if defined?(package) + ajax_data['index'] = h(index) if defined?(index) + +.card + .bg-light{ id: "buildresult#{index}-urls", data: { buildresult_url: defined?(package) ? package_buildresult_path : project_buildresult_path } } + %ul.nav.nav-tabs.pt-2.px-3.flex-nowrap{ id: "buildresult#{index}-box", role: 'tablist', data: ajax_data } + %li.nav-item + = link_to("#build#{index}", id: "build#{index}-tab", class: 'nav-link active text-nowrap', + data: { toggle: 'tab' }, role: 'tab', aria: { controls: "build#{index}", selected: true }) do + Build Results + - if defined?(package) + %li.nav-item + = link_to("#rpm#{index}", id: "rpm#{index}-tab", class: 'nav-link text-nowrap', data: { toggle: 'tab' }, + role: 'tab', aria: { controls: "rpm#{index}", selected: false }) do + RPM Lint + .card-body + .tab-content + .tab-pane.fade.show.active{ id: "build#{index}", role: 'tabpanel', aria: { labelledby: "build#{index}-tab" } } + .btn.btn-outline-primary.mb-2.build-refresh{ onclick: "updateBuildResult('#{index}')", accesskey: 'r', title: 'Refresh Build Results' } + Refresh + %i.fas.fa-sync-alt{ id: "build#{index}-reload" } + .result + - if defined?(package) + .tab-pane.fade{ id: "rpm#{index}", role: 'tabpanel', aria: { labelledby: "rpm#{index}-tab" } } + .btn.btn-outline-primary.mb-2{ onclick: "updateRpmlintResult('#{index}')", title: 'Refresh Rpmlint Results' } + Refresh + %i.fas.fa-sync-alt{ id: "rpm#{index}-reload" } + .result + +:javascript + updateBuildResult('#{index}'); + if ($('#rpm#{index}').length === 1) updateRpmlintResult('#{index}'); diff --git a/src/api/app/views/webui/shared/_dialog_action_buttons.html.haml b/src/api/app/views/webui/shared/_dialog_action_buttons.html.haml index 9d8bd59fa12..27f9be22452 100644 --- a/src/api/app/views/webui/shared/_dialog_action_buttons.html.haml +++ b/src/api/app/views/webui/shared/_dialog_action_buttons.html.haml @@ -1,3 +1,5 @@ -.dialog-buttons - = remove_dialog_tag('Cancel') - = submit_tag('Accept') +- submit_tag_text ||= 'Accept' + +%a.btn.btn-outline-danger.px-4{ data: { dismiss: 'modal' } } + Cancel += submit_tag(submit_tag_text, class: 'btn btn-primary px-4') diff --git a/src/api/app/views/webui/shared/_download_repository_link.html.haml b/src/api/app/views/webui/shared/_download_repository_link.html.haml new file mode 100644 index 00000000000..76f6dc5ec8e --- /dev/null +++ b/src/api/app/views/webui/shared/_download_repository_link.html.haml @@ -0,0 +1,5 @@ +- url = "#{download_url}/#{project.to_s.gsub(/:/, ':/')}/#{repository}" +%li.list-inline-item + = link_to(url, title: 'Go to download repository', class: 'nav-link') do + %i.fas.fa-download + Go to download repository diff --git a/src/api/app/views/webui/shared/_editor.html.haml b/src/api/app/views/webui/shared/_editor.html.haml new file mode 100644 index 00000000000..c934643d4ce --- /dev/null +++ b/src/api/app/views/webui/shared/_editor.html.haml @@ -0,0 +1,54 @@ +:ruby + save ||= {} + style ||= {} + style.reverse_merge!(read_only: false, big_editor: true) + uid ||= next_codemirror_uid + content_for(:head_style, codemirror_style(style)) + +%div{ class: "card #{'editable' unless style[:read_only]}" } + - unless style[:read_only] + .sticky-top.bg-light{ id: "top_#{uid}" } + .card-header + .d-flex.justify-content-between + .btn-group.pl-2 + %button.btn.btn-secondary{ id: "undo_#{uid}", onclick: "editors[#{uid}].Undo(this);", disabled: true } + %i.fa.fa-undo + Undo + %button.btn.btn-secondary{ id: "redo_#{uid}", onclick: "editors[#{uid}].Redo(this);", disabled: true } + %i.fa.fa-redo + Redo + %button.btn.btn-warning{ data: { 'target': "#settings#{uid}", 'toggle': 'modal' } } + %i.fa.fa-cog + .progress.short-progress.rounded-0.d-none{ id: "loading_#{uid}" } + .progress-bar.progress-bar-striped.progress-bar-animated.w-100 + + :ruby + data = {} + data['save-url'] = save[:url] if save[:url] + data['save-method'] = save[:method] if save[:method] + data['data'] = save[:data] if save[:data] + text = force_utf8_and_transform_nonprintables(text) + + = text_area_tag("editor_#{uid}", text, cols: '0', rows: '0', data: data, class: 'form-control') + + - unless style[:read_only] + .bg-light{ id: "bottom_#{uid}" } + .card-footer + .d-flex.justify-content-end + %p + line: + %span{ id: "ln_#{uid}" } 0 + char: + %span{ id: "ch_#{uid}" } 0 + .d-flex.mb-2 + %textarea.form-control{ id: "comment_#{uid}", disabled: true, placeholder: 'Describe your changes' } + .d-flex.justify-content-end + %button.btn.btn-danger.save{ id: "save_#{uid}", disabled: true } + %i.fa.fa-save + Save + +- unless style[:read_only] + = render partial: 'shared/editor_modal', locals: { uid: uid } + +- content_for :ready_function do + use_codemirror(#{uid}, #{style[:read_only]}, '#{mode}', #{style[:big_editor]}); diff --git a/src/api/app/views/webui/shared/_editor_modal.html.haml b/src/api/app/views/webui/shared/_editor_modal.html.haml new file mode 100644 index 00000000000..674dfa63746 --- /dev/null +++ b/src/api/app/views/webui/shared/_editor_modal.html.haml @@ -0,0 +1,55 @@ +.modal.fade{ id: "settings#{uid}" } + .modal-dialog + .modal-content + .modal-header + %h5.modal-title Editor settings + %button.close{ 'data-dismiss': 'modal' } + %span × + .modal-body + .input-group + .input-group-prepend + .input-group-text + Text size + = select_tag("fontsize_#{uid}", options_for_select(%w[0.5em 0.6em 0.75em 0.9em 1em 1.2em 1.5em]), + onchange: "editors[#{uid}].updateFontsize(this)", class: 'custom-select') + + .modal-body + .input-group + .input-group-prepend + .input-group-text + Highlighting + :ruby + modes = [ + ['changes', 'rpm-changes', { id: "rpm-changes_#{uid}" }], + ['spec', 'rpm-spec', { id: "rpm-spec-#{uid}" }], + ['diff', { id: "diff_#{uid}" }], + ['shell', 'text/x-sh', { id: "shell_#{uid}" }], + ['prjconf', 'prjconf', { id: "prjconf_#{uid}" }], + ['baselibs', 'baselibsconf', { id: "baselibs_#{uid}" }], + ['perl', { id: "perl_#{uid}" }], + ['css', 'css', { id: "css_#{uid}" }], + ['html', 'htmlmixed', { id: "html_#{uid}" }], + ['js', 'javascript', { id: "js_#{uid}" }], + ['php', 'application/x-httpd-php-open', { id: "php_#{uid}" }], + ['xml', { id: "xml_#{uid}" }], + ['---', '', { id: "x_#{uid}", selected: true }] + ] + = select_tag("mode_#{uid}", options_for_select(modes), + onchange: "editors[#{uid}].updateMode(this)", class: 'custom-select') + .modal-body + .input-group + .input-group-prepend + .input-group-text + Tab width + = select_tag("tabsize_#{uid}", options_for_select(2..8), + onchange: "editors[#{uid}].updateTabsize(this)", class: 'custom-select') + .modal-body + .row + .col + %label Line wrapping: + %button.btn.btn-block.btn-danger{ onclick: "editors[#{uid}].Wrap(this)" } + off + .col + %label Parenthesis matching: + %button.btn.btn-block.btn-danger{ id: "match_#{uid}", onclick: "editors[#{uid}].Match(this);" } + off diff --git a/src/api/app/views/webui/shared/_flag_popover.html.haml b/src/api/app/views/webui/shared/_flag_popover.html.haml new file mode 100644 index 00000000000..24796c24b97 --- /dev/null +++ b/src/api/app/views/webui/shared/_flag_popover.html.haml @@ -0,0 +1,17 @@ +.d-none{ data: { url: change_repository_flag_path(project: project, package: package) }, id: 'flag-popover-container' } + .flag-set-enable + = link_to('javascript:;', class: 'popover_flag_action', data: { cmd: 'set-disable' }) do + %i.fas.fa-ban.text-danger + Disable + .flag-set-disable + = link_to('javascript:;', class: 'popover_flag_action', data: { cmd: 'set-enable' }) do + %i.fas.fa-check.text-success + Enable + .flag-remove-enable + = link_to('javascript:;', class: 'popover_flag_action', data: { cmd: 'remove' }) do + %i.fas{ class: 'fa-check text-success' } + Take default (enable) + .flag-remove-disable + = link_to('javascript:;', class: 'popover_flag_action', data: { cmd: 'remove' }) do + %i.fas{ class: 'fa-ban text-danger' } + Take default (disable) diff --git a/src/api/app/views/webui/shared/_open_requests.html.haml b/src/api/app/views/webui/shared/_open_requests.html.haml new file mode 100644 index 00000000000..f317b249949 --- /dev/null +++ b/src/api/app/views/webui/shared/_open_requests.html.haml @@ -0,0 +1,6 @@ +- if requests.present? + - path = package ? package_requests_path(project, package) : project_requests_path(project) + - path = request_show_path(requests[0]) if requests.size == 1 + %li + %i.fas.fa-info-circle.text-info + = link_to(pluralize(requests.size, 'open request'), path) diff --git a/src/api/app/views/webui/shared/_package_branch_form.html.haml b/src/api/app/views/webui/shared/_package_branch_form.html.haml new file mode 100644 index 00000000000..a9ad8f3dcce --- /dev/null +++ b/src/api/app/views/webui/shared/_package_branch_form.html.haml @@ -0,0 +1,27 @@ +- if show_project_field + %p + %strong Change Branch Destination + .form-group + %label{ for: 'target_project' } + %strong Branch project name + = text_field_tag 'target_project', target_project, size: 80, maxlength: 200, class: 'form-control' +.form-group + %label{ for: 'target_package' } + %strong Branch package name + = text_field_tag 'target_package', package.try(:name), size: 80, maxlength: 200, class: 'form-control' +.custom-control.custom-checkbox + = check_box_tag(:current_revision, false, false, class: 'custom-control-input') + = label_tag(:current_revision, class: 'custom-control-label') do + Stay on this revision + - if revision + (##{revision}) + = hidden_field_tag(:revision, revision) if revision +- if show_project_field && Configuration.cleanup_after_days + .custom-control.custom-checkbox + %input.custom-control-input#disable-autocleanup{ type: 'checkbox' } + %label.custom-control-label{ for: 'disable-autocleanup' } Disable Autocleanup + = hidden_field_tag(:autocleanup, true) + :javascript + $('#disable-autocleanup').click(function(){ + $('#autocleanup').val($('#disable-autocleanup').prop('checked') ? 'false' : 'true'); + }); diff --git a/src/api/app/views/webui/shared/_patchinfos_table.html.haml b/src/api/app/views/webui/shared/_patchinfos_table.html.haml new file mode 100644 index 00000000000..4243f44f5ab --- /dev/null +++ b/src/api/app/views/webui/shared/_patchinfos_table.html.haml @@ -0,0 +1,32 @@ +%table.responsive.table.table-sm.table-bordered.table-hover.w-100#open-patchinfos-table{ title: 'Running Maintenance Updates' } + %thead + %tr + %th Project + %th Package + %th Issues + %th Actions + %tbody + - involved_patchinfos.each do |patchinfo| + %tr + - shortened_prj, shortened_pkg = elide_two(patchinfo[:package][:project], patchinfo[:package][:name], 60) + %td= link_to(shortened_prj, project_show_path(patchinfo[:package][:project])) + %td= link_to(shortened_pkg, package_show_path(patchinfo[:package][:project], patchinfo[:package][:name])) + %td + - size = patchinfo[:issues].size + - patchinfo[:issues].each_with_index do |item, index| + = succeed "#{',' if index < size - 1}" do + = link_to item[:label], item[:url], title: item[:summary] + %td + = link_to(project_monitor_path(patchinfo[:package][:project], pkgname: patchinfo[:package][:name])) do + %i.fas.fa-heartbeat.text-danger{ title: 'Monitor' } + += javascript_tag do + :plain + $(function() { + $('#open-patchinfos-table').dataTable({ + iDisplayLength: 10, + stateSave: true, + stateDuration: #{2.days} + }); + }); + diff --git a/src/api/app/views/webui/shared/_repositories.html.haml b/src/api/app/views/webui/shared/_repositories.html.haml new file mode 100644 index 00000000000..a5034614f52 --- /dev/null +++ b/src/api/app/views/webui/shared/_repositories.html.haml @@ -0,0 +1,38 @@ += render(partial: 'shared/flag_popover', locals: { project: project, package: package }) + +.row.mt-5 + .col + %h5 + Build Flag + %span.flagerror + = render partial: 'shared/repositories_flag_table', + locals: { flags: flags[:build], project: project, package: package, + architectures: architectures, table_id: 'flag_table_build' } + .col + %h5 + Publish Flag + %span.flagerror + = render partial: 'shared/repositories_flag_table', + locals: { flags: flags[:publish], project: project, package: package, + architectures: architectures, table_id: 'flag_table_publish' } +.row + .col + %h5 + Debuginfo Flag + %span.flagerror + = render partial: 'shared/repositories_flag_table', + locals: { flags: flags[:debuginfo], project: project, package: package, + architectures: architectures, table_id: 'flag_table_debuginfo' } + .col + %h5 + Use for Build Flag + %span.flagerror + = render partial: 'shared/repositories_flag_table', + locals: { flags: flags[:useforbuild], project: project, package: package, + architectures: architectures, table_id: 'flag_table_useforbuild' } + +- if user_can_modify + - content_for :ready_function do + :plain + setSpinnersForFlags(); + setupFlagPopup(); diff --git a/src/api/app/views/webui/shared/_repositories_flag_table.html.haml b/src/api/app/views/webui/shared/_repositories_flag_table.html.haml new file mode 100644 index 00000000000..c60de18cb68 --- /dev/null +++ b/src/api/app/views/webui/shared/_repositories_flag_table.html.haml @@ -0,0 +1,22 @@ +.table-responsive + %table.table.table-hover.table-sm{ id: table_id } + %thead.thead-light + %tr + %th.w-auto Repository + %th.w-auto.text-center All + - architectures.each do |architecture| + %th.w-auto.text-center= architecture.name + %tbody + - ([nil] + project.repositories).each do |repository| + %tr + %td.reponame.text-word-break-all + - repository_name = repository.try(&:name) + - if repository.nil? + All + - elsif package + = link_to(repository_name, package_binaries_path(project: project, package: package, repository: repository_name)) + - else + = link_to(repository_name, action: :state, project: project, repository: repository_name) + - ([nil] + architectures).each do |architecture| + %td.text-center{ class: architecture && repository ? nil : 'all_flag' } + = flag_column(flags, repository_name, architecture.try(&:name)) diff --git a/src/api/app/views/webui/shared/_requests_state_and_type_form.html.haml b/src/api/app/views/webui/shared/_requests_state_and_type_form.html.haml index 1fc07df61e5..59b7197ac7b 100644 --- a/src/api/app/views/webui/shared/_requests_state_and_type_form.html.haml +++ b/src/api/app/views/webui/shared/_requests_state_and_type_form.html.haml @@ -1,12 +1,19 @@ -%p - Display - = select_tag('request_type_select', - options_for_select(Webui::RequestHelper::AVAILABLE_TYPES, @default_request_type), - data: { table: 'all_requests_table' }) - requests in state - = select_tag('request_state_select', - options_for_select(Webui::RequestHelper::AVAILABLE_STATES, @default_request_state), - data: { table: 'all_requests_table' }) - %span#request-count - \: - = image_tag('ajax-loader.gif', id: 'spinner', class: 'hidden') +.row + .form-group.input-group.col-sm-12.col-md-6 + .input-group-prepend + = label_tag('request_type_select', 'Display', class: 'control-label input-group-text') + = select_tag('request_type_select', + options_for_select(Webui::RequestHelper::AVAILABLE_TYPES, selected_type), + data: { table: 'all_requests_table' }, + class: 'form-control custom-select dataTables_length') + + .form-group.input-group.col-sm-12.col-md + .input-group-prepend + = label_tag('request_state_select', 'Requests in state', class: 'control-label input-group-text') + = select_tag('request_state_select', + options_for_select(Webui::RequestHelper::AVAILABLE_STATES, selected_state), + data: { table: 'all_requests_table' }, + class: 'form-control custom-select dataTables_length') + + + diff --git a/src/api/app/views/webui/shared/_requests_table.html.haml b/src/api/app/views/webui/shared/_requests_table.html.haml index a77642f769b..4a73c63eb65 100644 --- a/src/api/app/views/webui/shared/_requests_table.html.haml +++ b/src/api/app/views/webui/shared/_requests_table.html.haml @@ -1,6 +1,5 @@ -%table.requests-datatable.compact{ 'data-source' => source_url, - 'id' => id, - 'width' => '100%' } +%table.responsive.requests-datatable.table.table-sm.table-bordered.table-hover.w-100{ data: { source: source_url, + 'page-length': local_assigns[:page_length] }, id: id } %thead %tr %th Created @@ -10,4 +9,4 @@ %th Type %th Priority %th -%tbody + %tbody diff --git a/src/api/app/views/webui/shared/_sign_up.html.haml b/src/api/app/views/webui/shared/_sign_up.html.haml new file mode 100644 index 00000000000..63c2aa3236d --- /dev/null +++ b/src/api/app/views/webui/shared/_sign_up.html.haml @@ -0,0 +1,26 @@ +- if CONFIG['proxy_auth_mode'] == :on + - if CONFIG['proxy_auth_register_page'].blank? + %p Sorry, signing up is currently disabled + - else + %p= link_to 'Use this link to Sign Up', CONFIG['proxy_auth_register_page'] +- else + = form_tag({ controller: 'user', action: 'register', method: :post }, class: 'sign-up', autocomplete: 'off') do + .form-group + = label_tag 'login', 'Username:' + %abbr.text-danger{ title: 'required' } * + = text_field_tag 'login', nil, placeholder: 'Username', autocomplete: 'off', class: 'form-control', required: true + .form-group + = label_tag 'email', 'Email:' + %abbr.text-danger{ title: 'required' } * + = text_field_tag 'email', nil, placeholder: 'Email address', autocomplete: 'off', class: 'form-control', type: 'email', required: true + .form-group + = label_tag 'password', 'Password:' + %abbr.text-danger{ title: 'required' } * + = password_field_tag :password, nil, id: 'pwd', placeholder: 'Enter a password', autocomplete: 'off', class: 'form-control', required: true + .form-group + = label_tag 'password_confirmation', 'Password confirmation:' + %abbr.text-danger{ title: 'required' } * + = password_field_tag(:password_confirmation, nil, id: 'pwd_confirmation', placeholder: 'Password confirmation', autocomplete: 'off', + class: 'form-control', required: true) + = hidden_field_tag 'register', 'true' + = submit_tag submit_btn_text, class: 'btn btn-primary' diff --git a/src/api/app/views/webui/shared/_truncated_diff_hint.html.erb b/src/api/app/views/webui/shared/_truncated_diff_hint.html.erb deleted file mode 100644 index 85acf565884..00000000000 --- a/src/api/app/views/webui/shared/_truncated_diff_hint.html.erb +++ /dev/null @@ -1,11 +0,0 @@ -
- - We truncated the diff of some files because they were too big. If you want to see the full diff for - every file, - <% if type == :request %> - <%= link_to 'click here', request_show_path(number: @bs_request.number, full_diff: true) %>. - <% elsif type == :package %> - <%= link_to 'click here', package_rdiff_path(project: @project, package: @package, linkrev: @linkrev, rev: @rev, full_diff: true) %>. - <% end %> - -
diff --git a/src/api/app/views/webui/shared/_truncated_diff_hint.html.haml b/src/api/app/views/webui/shared/_truncated_diff_hint.html.haml new file mode 100644 index 00000000000..8b43318050c --- /dev/null +++ b/src/api/app/views/webui/shared/_truncated_diff_hint.html.haml @@ -0,0 +1,4 @@ +.alert.alert-warning{ role: :alert } + %i.fa.fa-exclamation-triangle.text-warning + We truncated the diff of some files because they were too big. + If you want to see the full diff for every file, #{link_to 'click here', path}. diff --git a/src/api/app/views/webui/shared/bs_requests/index.json.erb b/src/api/app/views/webui/shared/bs_requests/index.json.erb index b621bc172b9..fce6cd3ca48 100644 --- a/src/api/app/views/webui/shared/bs_requests/index.json.erb +++ b/src/api/app/views/webui/shared/bs_requests/index.json.erb @@ -12,7 +12,13 @@ "<%= escape_javascript(user_with_realname_and_icon(row.creator, short: true)) %>", "<%= escape_javascript(new_or_update_request(row)) %>", "<%= escape_javascript(row.priority) %>", - "<%= escape_javascript(link_to(sprite_tag('req-showdiff', title: "Show request ##{row.number}"), request_show_path(row.number), { class: :request_link })) %>" + "<%= escape_javascript(link_to( + ' + + + '.html_safe, + request_show_path(row.number), + { title: "Show request ##{row.number}", class: :request_link })) %>" <% end %> ] <% unless index == @requests_data_table.rows.length - 1 %> diff --git a/src/api/app/views/webui/shared/user_or_groups_roles/_add_group_dialog.html.haml b/src/api/app/views/webui/shared/user_or_groups_roles/_add_group_dialog.html.haml new file mode 100644 index 00000000000..01bb2bb9808 --- /dev/null +++ b/src/api/app/views/webui/shared/user_or_groups_roles/_add_group_dialog.html.haml @@ -0,0 +1,16 @@ +.modal.fade#add-group-role-modal{ tabindex: -1, role: 'dialog', aria: { labelledby: 'edit-modal-label', hidden: true } } + .modal-dialog.modal-dialog-centered{ role: 'document' } + .modal-content + = form_tag action: :save_group do + .modal-header + %h5.modal-title#edit-modal-label Add Group + .modal-body + = render partial: 'webui/autocomplete', locals: { html_id: 'groupid', label: 'Group:', + data: { source: autocomplete_groups_path } } + .form-group + = label_tag(:role, 'Role:') + = select_tag 'role', options_for_select(Role.local_roles, nil), required: true, class: 'form-control' + = hidden_field_tag 'package', package + = hidden_field_tag 'project', project + .modal-footer + = render partial: 'webui2/shared/dialog_action_buttons' diff --git a/src/api/app/views/webui/shared/user_or_groups_roles/_add_user_dialog.html.haml b/src/api/app/views/webui/shared/user_or_groups_roles/_add_user_dialog.html.haml new file mode 100644 index 00000000000..64fd296ed35 --- /dev/null +++ b/src/api/app/views/webui/shared/user_or_groups_roles/_add_user_dialog.html.haml @@ -0,0 +1,17 @@ +.modal.fade#add-user-role-modal{ tabindex: -1, role: 'dialog', aria: { labelledby: 'edit-modal-label', hidden: true } } + .modal-dialog.modal-dialog-centered{ role: 'document' } + .modal-content + = form_tag action: :save_person do + .modal-header + %h5.modal-title#edit-modal-label Add User + .modal-body + = render partial: 'webui/autocomplete', locals: { html_id: 'userid', label: 'User:', + data: { source: autocomplete_users_path } } + .form-group + = label_tag(:role, 'Role:') + = select_tag 'role', options_for_select(Role.local_roles, nil), required: true, class: 'form-control' + = hidden_field_tag 'package', package + = hidden_field_tag 'project', project + = hidden_field_tag 'webui2', true + .modal-footer + = render partial: 'webui2/shared/dialog_action_buttons' diff --git a/src/api/app/views/webui/shared/user_or_groups_roles/_delete_dialog.html.haml b/src/api/app/views/webui/shared/user_or_groups_roles/_delete_dialog.html.haml new file mode 100644 index 00000000000..948c71a3340 --- /dev/null +++ b/src/api/app/views/webui/shared/user_or_groups_roles/_delete_dialog.html.haml @@ -0,0 +1,27 @@ +.modal.fade{ id: 'delete-role-modal', tabindex: -1, role: 'dialog', aria: { labelledby: 'delete-modal-label', hidden: true } } + .modal-dialog.modal-dialog-centered{ role: 'document' } + .modal-content + .modal-header + %h5.modal-title + Delete all roles of + = succeed '?' do + %span.type + .modal-body + %p + Please confirm deletion of all roles of the + %span.type + = surround "'" do + %span.object + = form_tag(nil, method: :post) do + .modal-footer + %button.btn.btn-sm.btn-outline-secondary.px-4{ data: { dismiss: 'modal' } } + Cancel + = submit_tag('Delete', class: 'btn btn-sm btn-danger px-4') +- content_for :ready_function do + :plain + $('#delete-role-modal').on('show.bs.modal', function (event) { + var link = $(event.relatedTarget); + $(this).find('.type').text(link.data('type')); + $(this).find('.object').text(link.data('object')); + $(this).find('form').attr('action', link.data('action')); + }); diff --git a/src/api/app/views/webui/shared/user_or_groups_roles/_index.html.haml b/src/api/app/views/webui/shared/user_or_groups_roles/_index.html.haml new file mode 100644 index 00000000000..a6fadde2865 --- /dev/null +++ b/src/api/app/views/webui/shared/user_or_groups_roles/_index.html.haml @@ -0,0 +1,73 @@ +:ruby + user_is_maintainer = User.possibly_nobody.can_modify?(package || project) + data = { 'project' => project.name } + if package + data['save-user'] = package_save_person_url + data['remove'] = package_remove_role_url + data['save-group'] = package_save_group_path + data['package'] = package.name + else + data['save-user'] = project_save_person_url + data['remove'] = project_remove_role_url + data['save-group'] = project_save_group_path + end + +#involved-users{ data: data } + - if users.present? + %h3 User Roles + %table.responsive.table.table-sm.table-bordered.table-hover.w-100#user-table + %thead + %tr + %td Username + - roles.each do |role| + %td= role.title.capitalize + %td + %tbody + = render partial: 'webui2/shared/user_or_groups_roles/list', + locals: { records: users, roles: roles, type: 'user', + user_is_maintainer: user_is_maintainer, + project: project, package: package } + + - if user_is_maintainer + %ul.list-inline + %li.list-inline-item + = render(partial: 'webui2/shared/user_or_groups_roles/add_user_dialog', locals: { project: project.to_param, package: package.to_param }) + = link_to('#', data: { toggle: 'modal', target: '#add-user-role-modal' }, id: 'add-user', class: 'nav-link') do + %i.fas.fa-plus-circle.text-primary + Add User + = render(partial: 'webui2/shared/user_or_groups_roles/delete_dialog') + + %hr + + - if @groups.present? + %h3 Group Roles + %table.responsive.table.table-sm.table-bordered.table-hover.w-100#group-table + %thead + %tr + %td Group name + - roles.each do |role| + %td= role.title.capitalize + - if user_is_maintainer + %td + %tbody + = render partial: 'webui2/shared/user_or_groups_roles/list', + locals: { records: groups, roles: roles, type: 'group', + user_is_maintainer: user_is_maintainer, + project: project, package: package } + - if user_is_maintainer + %ul.list-inline + %li.list-inline-item + = render(partial: 'webui2/shared/user_or_groups_roles/add_group_dialog', locals: { project: project.to_param, package: package.to_param }) + = link_to('#', data: { toggle: 'modal', target: '#add-group-role-modal' }, id: 'add-group', class: 'nav-link') do + %i.fas.fa-plus-circle.text-primary + Add Group + +:javascript + setDataTableForUsersAndGroups(); +- if user_is_maintainer + :javascript + $(document).ready(function() { + $(document).on('click','.trigger', function() { + changeUserRole($(this)); + }); + }); diff --git a/src/api/app/views/webui/shared/user_or_groups_roles/_list.html.haml b/src/api/app/views/webui/shared/user_or_groups_roles/_list.html.haml new file mode 100644 index 00000000000..e6512591a1b --- /dev/null +++ b/src/api/app/views/webui/shared/user_or_groups_roles/_list.html.haml @@ -0,0 +1,29 @@ +- if User.session + :ruby + mail_subject = "#{home_title} - #{project}" + mail_subject += "/#{package}" if package +- records.each do |record| + %tr + %td.align-middle + = image_tag_for(record, size: 20) + = link_to(display_name(record), user_or_group_show_path(record)) + - roles.each do |role| + %td.align-middle + .custom-control.custom-checkbox + = check_box_tag("#{type}_#{role}_#{record}", '', + (package || project).send("#{type}_has_role?", record, role), disabled: !user_is_maintainer, + data: { "#{type}": record.to_s, role: role.title, type: type }, class: 'trigger custom-control-input') + %label.custom-control-label{ for: "#{type}_#{role}_#{record}" } + %i.fas.fa-spinner.fa-spin.d-none + - if package && project.send("#{type}_has_role?", record, role) + = link_to(project_users_path(project: project)) do + %i.fa.fa-cubes.text-secondary{ title: 'inherited from project' } + %td.text-nowrap + - if mail_subject && record.email + = mail_to(record.email, subject: mail_subject) do + %i.far.fa-envelope{ title: "Send email to #{type}" } + - if user_is_maintainer + = link_to('#', class: "remove-#{type}", + data: { toggle: 'modal', target: '#delete-role-modal', + action: user_or_groups_roles_delete_path(project, type, record, package), type: type, object: record.to_s }) do + %i.fas.fa-times-circle.text-danger{ title: "Delete all roles for #{type}" }