Skip to content
Snippets Groups Projects
Commit 4464c22d authored by Jarka Kadlecova's avatar Jarka Kadlecova
Browse files

Support descriptions for snippets

parent 8039b9c3
No related branches found
No related tags found
No related merge requests found
Showing
with 131 additions and 15 deletions
Loading
Loading
@@ -218,6 +218,16 @@ import ShortcutsBlob from './shortcuts_blob';
new gl.GLForm($('.tag-form'));
new RefSelectDropdown($('.js-branch-select'), window.gl.availableRefs);
break;
case 'projects:snippets:new':
case 'projects:snippets:edit':
case 'projects:snippets:create':
case 'projects:snippets:update':
case 'snippets:new':
case 'snippets:edit':
case 'snippets:create':
case 'snippets:update':
new gl.GLForm($('.snippet-form'));
break;
case 'projects:releases:edit':
new ZenMode();
new gl.GLForm($('.release-form'));
Loading
Loading
Loading
Loading
@@ -5,7 +5,7 @@ import './preview_markdown';
 
window.DropzoneInput = (function() {
function DropzoneInput(form) {
var updateAttachingMessage, $attachingFileMessage, $mdArea, $attachButton, $cancelButton, $retryLink, $uploadingErrorContainer, $uploadingErrorMessage, $uploadProgress, $uploadingProgressContainer, appendToTextArea, btnAlert, child, closeAlertMessage, closeSpinner, divHover, divSpinner, dropzone, $formDropzone, formTextarea, getFilename, handlePaste, iconPaperclip, iconSpinner, insertToTextArea, isImage, maxFileSize, pasteText, uploadsPath, showError, showSpinner, uploadFile;
var updateAttachingMessage, $attachingFileMessage, $mdArea, $attachButton, $cancelButton, $retryLink, $uploadingErrorContainer, $uploadingErrorMessage, $uploadProgress, $uploadingProgressContainer, appendToTextArea, btnAlert, child, closeAlertMessage, closeSpinner, divHover, divSpinner, dropzone, $formDropzone, formTextarea, getFilename, handlePaste, iconPaperclip, iconSpinner, insertToTextArea, isImage, maxFileSize, pasteText, uploadsPath, showError, showSpinner, uploadFile, addFileToForm;
Dropzone.autoDiscover = false;
divHover = '<div class="div-dropzone-hover"></div>';
iconPaperclip = '<i class="fa fa-paperclip div-dropzone-icon"></i>';
Loading
Loading
@@ -71,6 +71,7 @@ window.DropzoneInput = (function() {
pasteText(response.link.markdown, shouldPad);
// Show 'Attach a file' link only when all files have been uploaded.
if (!processingFileCount) $attachButton.removeClass('hide');
addFileToForm(response.link.url);
},
error: function(file, errorMessage = 'Attaching the file failed.', xhr) {
// If 'error' event is fired by dropzone, the second parameter is error message.
Loading
Loading
@@ -197,6 +198,10 @@ window.DropzoneInput = (function() {
return formTextarea.trigger('input');
};
 
addFileToForm = function(path) {
$(form).append('<input type="hidden" name="files[]" value="' + path + '">');
};
getFilename = function(e) {
var value;
if (window.clipboardData && window.clipboardData.getData) {
Loading
Loading
Loading
Loading
@@ -107,6 +107,6 @@ class Projects::SnippetsController < Projects::ApplicationController
end
 
def snippet_params
params.require(:project_snippet).permit(:title, :content, :file_name, :private, :visibility_level)
params.require(:project_snippet).permit(:title, :content, :file_name, :private, :visibility_level, :description)
end
end
Loading
Loading
@@ -45,6 +45,8 @@ class SnippetsController < ApplicationController
 
@snippet = CreateSnippetService.new(nil, current_user, create_params).execute
 
move_temporary_files if params[:files]
recaptcha_check_with_fallback { render :new }
end
 
Loading
Loading
@@ -124,6 +126,12 @@ class SnippetsController < ApplicationController
end
 
def snippet_params
params.require(:personal_snippet).permit(:title, :content, :file_name, :private, :visibility_level)
params.require(:personal_snippet).permit(:title, :content, :file_name, :private, :visibility_level, :description)
end
def move_temporary_files
params[:files].each do |file|
FileMover.new(file, @snippet).execute
end
end
end
Loading
Loading
@@ -9,6 +9,8 @@ class UploadsController < ApplicationController
private
 
def find_model
return nil unless params[:id]
return render_404 unless upload_model && upload_mount
 
@model = upload_model.find(params[:id])
Loading
Loading
@@ -33,6 +35,8 @@ class UploadsController < ApplicationController
end
 
def authorize_create_access!
return unless model
# for now we support only personal snippets comments
authorized = can?(current_user, :comment_personal_snippet, model)
 
Loading
Loading
Loading
Loading
@@ -128,7 +128,7 @@ module GitlabRoutingHelper
 
def preview_markdown_path(project, *args)
if @snippet.is_a?(PersonalSnippet)
preview_markdown_snippet_path(@snippet)
preview_markdown_snippets_path
else
preview_markdown_namespace_project_path(project.namespace, project, *args)
end
Loading
Loading
Loading
Loading
@@ -10,6 +10,7 @@ class Snippet < ActiveRecord::Base
include Spammable
 
cache_markdown_field :title, pipeline: :single_line
cache_markdown_field :description
cache_markdown_field :content
 
# Aliases to make application_helper#edited_time_ago_with_tooltip helper work properly with snippets.
Loading
Loading
class FileMover
attr_reader :secret, :file_name, :model
def initialize(file_path, model, update_field = :description)
@secret = File.split(File.dirname(file_path)).last
@file_name = File.basename(file_path)
@model = model
end
def execute
move
update_markdown
end
private
def move
FileUtils.mkdir_p(file_path)
FileUtils.move(temp_file_path, file_path)
end
def update_markdown(field = :description)
updated_text = model.send(field).sub(temp_file_uploader.to_markdown, uploader.to_markdown)
model.update_attribute(field, updated_text)
end
def temp_file_path
temp_file_uploader.retrieve_from_store!(file_name)
temp_file_uploader.file.path
end
def file_path
return @file_path if @file_path
uploader.retrieve_from_store!(file_name)
@file_path = uploader.file.path
end
def uploader
@uploader ||= PersonalFileUploader.new(model, secret)
end
def temp_file_uploader
@temp_file_uploader ||= PersonalFileUploader.new(nil, secret)
end
end
Loading
Loading
@@ -10,6 +10,10 @@ class PersonalFileUploader < FileUploader
end
 
def self.model_path(model)
File.join("/#{base_dir}", model.class.to_s.underscore, model.id.to_s)
if model
File.join("/#{base_dir}", model.class.to_s.underscore, model.id.to_s)
else
File.join("/#{base_dir}", 'temp')
end
end
end
- header_title "Snippets", snippets_path
 
- content_for :page_specific_javascripts do
- if @snippet&.persisted? && current_user
- if @snippet && current_user
:javascript
window.uploads_path = "#{upload_path('personal_snippet', @snippet)}";
window.preview_markdown_path = "#{preview_markdown_snippet_path(@snippet)}";
window.uploads_path = "#{upload_path('personal_snippet', id: @snippet.id)}";
 
= render template: "layouts/application"
- project = local_assigns.fetch(:project)
- issuable = local_assigns.fetch(:issuable)
- model = local_assigns.fetch(:model)
- form = local_assigns.fetch(:form)
- supports_slash_commands = issuable.new_record?
- supports_slash_commands = !model.persisted?
 
- if supports_slash_commands
- preview_url = preview_markdown_path(project, slash_commands_target_type: issuable.class.name)
- preview_url = preview_markdown_path(project, slash_commands_target_type: model.class.name)
- else
- preview_url = preview_markdown_path(project)
 
Loading
Loading
Loading
Loading
@@ -17,7 +17,7 @@
= render 'shared/issuable/form/template_selector', issuable: issuable
= render 'shared/issuable/form/title', issuable: issuable, form: form, has_wip_commits: commits && commits.detect(&:work_in_progress?)
 
= render 'shared/issuable/form/description', issuable: issuable, form: form, project: project
= render 'shared/form_elements/description', model: issuable, form: form, project: project
 
- if issuable.respond_to?(:confidential)
.form-group
Loading
Loading
Loading
Loading
@@ -3,7 +3,7 @@
= page_specific_javascript_bundle_tag('snippet')
 
.snippet-form-holder
= form_for @snippet, url: url, html: { class: "form-horizontal snippet-form js-requires-input js-quick-submit" } do |f|
= form_for @snippet, url: url, html: { class: "form-horizontal snippet-form js-requires-input js-quick-submit common-note-form" } do |f|
= form_errors(@snippet)
 
.form-group
Loading
Loading
@@ -11,6 +11,8 @@
.col-sm-10
= f.text_field :title, class: 'form-control', required: true, autofocus: true
 
= render 'shared/form_elements/description', model: @snippet, project: @project, form: f
= render 'shared/visibility_level', f: f, visibility_level: @snippet.visibility_level, can_change_visibility_level: true, form_model: @snippet
 
.file-editor
Loading
Loading
@@ -23,6 +25,9 @@
.file-content.code
%pre#editor= @snippet.content
= f.hidden_field :content, class: 'snippet-file-content'
- if params[:files]
- params[:files].each_with_index do |file, index|
= hidden_field_tag "files[]", file, id: "files_#{index}"
 
.form-actions
- if @snippet.new_record?
Loading
Loading
Loading
Loading
@@ -22,3 +22,10 @@
 
- if @snippet.updated_at != @snippet.created_at
= edited_time_ago_with_tooltip(@snippet, placement: 'bottom', html_class: 'snippet-edited-ago', exclude_author: true)
%div
- if @snippet.description.present?
.description
.wiki
= markdown_field(@snippet, :description)
%textarea.hidden.js-task-list-field
= @snippet.description
---
title: Support descriptions for snippets
merge_request:
author:
Loading
Loading
@@ -2,6 +2,9 @@ resources :snippets, concerns: :awardable do
member do
get :raw
post :mark_as_spam
end
collection do
post :preview_markdown
end
 
Loading
Loading
Loading
Loading
@@ -20,7 +20,7 @@ scope path: :uploads do
constraints: { namespace_id: /[a-zA-Z.0-9_\-]+/, project_id: /[a-zA-Z.0-9_\-]+/, filename: /[^\/]+/ }
 
# create uploads for models, snippets (notes) available for now
post ':model/:id/',
post ':model',
to: 'uploads#create',
constraints: { model: /personal_snippet/, id: /\d+/ },
as: 'upload'
Loading
Loading
class AddDescriptionToSnippets < ActiveRecord::Migration
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
disable_ddl_transaction!
def change
add_column :snippets, :description, :text
add_column :snippets, :description_html, :text
end
end
Loading
Loading
@@ -1153,6 +1153,8 @@ ActiveRecord::Schema.define(version: 20170523091700) do
t.text "title_html"
t.text "content_html"
t.integer "cached_markdown_version"
t.text "description"
t.text "description_html"
end
 
add_index "snippets", ["author_id"], name: "index_snippets_on_author_id", using: :btree
Loading
Loading
Loading
Loading
@@ -43,6 +43,7 @@ Parameters:
"id": 1,
"title": "test",
"file_name": "add.rb",
"description": "Ruby test snippet",
"author": {
"id": 1,
"username": "john_smith",
Loading
Loading
@@ -70,8 +71,9 @@ Parameters:
- `id` (required) - The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user
- `title` (required) - The title of a snippet
- `file_name` (required) - The name of a snippet file
- `description` (optional) - The description of a snippet
- `code` (required) - The content of a snippet
- `visibility` (required) - The snippet's visibility
- `visibility` (optional) - The snippet's visibility
 
## Update snippet
 
Loading
Loading
@@ -87,6 +89,7 @@ Parameters:
- `snippet_id` (required) - The ID of a project's snippet
- `title` (optional) - The title of a snippet
- `file_name` (optional) - The name of a snippet file
- `description` (optional) - The description of a snippet
- `code` (optional) - The content of a snippet
- `visibility` (optional) - The snippet's visibility
 
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment