diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-04-01 12:07:45 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-04-01 12:07:45 +0300 |
commit | b11f7057d067885619ee3e513751f180b2e8ad85 (patch) | |
tree | dfb3077ea8716ed217f5ce4324be4e25a450c599 /app | |
parent | e50050a8756a20b6aa118edbad3369674e4c63ba (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
11 files changed, 100 insertions, 82 deletions
diff --git a/app/assets/javascripts/diffs/components/diff_file_header.vue b/app/assets/javascripts/diffs/components/diff_file_header.vue index d4270960f57..c51f711fb81 100644 --- a/app/assets/javascripts/diffs/components/diff_file_header.vue +++ b/app/assets/javascripts/diffs/components/diff_file_header.vue @@ -172,7 +172,6 @@ export default { /> <a v-once - id="diffFile.file_path" ref="titleWrapper" class="append-right-4" :href="titleLink" diff --git a/app/assets/javascripts/snippets/components/snippet_blob_edit.vue b/app/assets/javascripts/snippets/components/snippet_blob_edit.vue index af1574f98d9..624ca18eec9 100644 --- a/app/assets/javascripts/snippets/components/snippet_blob_edit.vue +++ b/app/assets/javascripts/snippets/components/snippet_blob_edit.vue @@ -7,21 +7,18 @@ export default { BlobHeaderEdit, BlobContentEdit, }, + inheritAttrs: false, props: { - content: { - type: String, - required: true, - }, fileName: { type: String, - required: true, + required: false, + default: '', }, }, - data() { - return { - name: this.fileName, - blobContent: this.content, - }; + methods: { + emitFileNameChange(newFileName) { + this.$emit('name-change', newFileName); + }, }, }; </script> @@ -29,8 +26,8 @@ export default { <div class="form-group file-editor"> <label>{{ s__('Snippets|File') }}</label> <div class="file-holder snippet"> - <blob-header-edit v-model="name" /> - <blob-content-edit v-model="blobContent" :file-name="name" /> + <blob-header-edit :value="fileName" @input="emitFileNameChange" /> + <blob-content-edit v-bind="$attrs" :file-name="fileName" v-on="$listeners" /> </div> </div> </template> diff --git a/app/assets/javascripts/snippets/components/snippet_description_edit.vue b/app/assets/javascripts/snippets/components/snippet_description_edit.vue index 5b70ac5b715..68810f8ab3f 100644 --- a/app/assets/javascripts/snippets/components/snippet_description_edit.vue +++ b/app/assets/javascripts/snippets/components/snippet_description_edit.vue @@ -9,11 +9,6 @@ export default { MarkdownField, }, props: { - description: { - type: String, - default: '', - required: false, - }, markdownPreviewPath: { type: String, required: true, @@ -22,11 +17,11 @@ export default { type: String, required: true, }, - }, - data() { - return { - text: this.description, - }; + value: { + type: String, + required: false, + default: '', + }, }, mounted() { setupCollapsibleInputs(); @@ -37,7 +32,7 @@ export default { <div class="form-group js-description-input"> <label>{{ s__('Snippets|Description (optional)') }}</label> <div class="js-collapsible-input"> - <div class="js-collapsed" :class="{ 'd-none': text }"> + <div class="js-collapsed" :class="{ 'd-none': value }"> <gl-form-input class="form-control" :placeholder=" @@ -50,20 +45,21 @@ export default { </div> <markdown-field class="js-expanded" - :class="{ 'd-none': !text }" + :class="{ 'd-none': !value }" :markdown-preview-path="markdownPreviewPath" :markdown-docs-path="markdownDocsPath" > <textarea id="snippet-description" slot="textarea" - v-model="text" class="note-textarea js-gfm-input js-autosize markdown-area qa-description-textarea" dir="auto" data-supports-quick-actions="false" + :value="value" :aria-label="__('Description')" :placeholder="__('Write a comment or drag your files hereā¦')" + @input="$emit('input', $event.target.value)" > </textarea> </markdown-field> diff --git a/app/assets/javascripts/snippets/components/snippet_visibility_edit.vue b/app/assets/javascripts/snippets/components/snippet_visibility_edit.vue index 93cd2b58c11..80710a88bb2 100644 --- a/app/assets/javascripts/snippets/components/snippet_visibility_edit.vue +++ b/app/assets/javascripts/snippets/components/snippet_visibility_edit.vue @@ -1,6 +1,6 @@ <script> import { GlIcon, GlFormGroup, GlFormRadio, GlFormRadioGroup, GlLink } from '@gitlab/ui'; -import { SNIPPET_VISIBILITY } from '~/snippets/constants'; +import { SNIPPET_VISIBILITY, SNIPPET_VISIBILITY_PRIVATE } from '~/snippets/constants'; export default { components: { @@ -21,48 +21,22 @@ export default { required: false, default: false, }, - visibilityLevel: { + value: { type: String, - default: '0', required: false, + default: SNIPPET_VISIBILITY_PRIVATE, }, }, - data() { - return { - selected: this.visibilityLevel, - }; - }, computed: { visibilityOptions() { - return [ - { - value: '0', - icon: 'lock', - text: SNIPPET_VISIBILITY.private.label, - description: this.isProjectSnippet - ? SNIPPET_VISIBILITY.private.description_project - : SNIPPET_VISIBILITY.private.description, - }, - { - value: '1', - icon: 'shield', - text: SNIPPET_VISIBILITY.internal.label, - description: SNIPPET_VISIBILITY.internal.description, - }, - { - value: '2', - icon: 'earth', - text: SNIPPET_VISIBILITY.public.label, - description: SNIPPET_VISIBILITY.public.description, - }, - ]; - }, - }, - methods: { - updateSelectedOption(newVal) { - if (newVal !== this.selected) { - this.selected = newVal; - } + const options = []; + Object.keys(SNIPPET_VISIBILITY).forEach(key => { + options.push({ + value: key, + ...SNIPPET_VISIBILITY[key], + }); + }); + return options; }, }, }; @@ -76,18 +50,22 @@ export default { /></gl-link> </label> <gl-form-group id="visibility-level-setting"> - <gl-form-radio-group :checked="selected" stacked @change="updateSelectedOption"> + <gl-form-radio-group v-bind="$attrs" :checked="value" stacked v-on="$listeners"> <gl-form-radio v-for="option in visibilityOptions" - :key="option.icon" + :key="option.value" :value="option.value" class="mb-3" > <div class="d-flex align-items-center"> <gl-icon :size="16" :name="option.icon" /> - <span class="font-weight-bold ml-1">{{ option.text }}</span> + <span class="font-weight-bold ml-1 js-visibility-option">{{ option.label }}</span> </div> - <template #help>{{ option.description }}</template> + <template #help>{{ + isProjectSnippet && option.description_project + ? option.description_project + : option.description + }}</template> </gl-form-radio> </gl-form-radio-group> </gl-form-group> diff --git a/app/assets/javascripts/snippets/constants.js b/app/assets/javascripts/snippets/constants.js index ed2f1156292..7fd5e5b8ee4 100644 --- a/app/assets/javascripts/snippets/constants.js +++ b/app/assets/javascripts/snippets/constants.js @@ -5,17 +5,20 @@ export const SNIPPET_VISIBILITY_INTERNAL = 'internal'; export const SNIPPET_VISIBILITY_PUBLIC = 'public'; export const SNIPPET_VISIBILITY = { - private: { + [SNIPPET_VISIBILITY_PRIVATE]: { label: __('Private'), + icon: 'lock', description: __('The snippet is visible only to me.'), description_project: __('The snippet is visible only to project members.'), }, - internal: { + [SNIPPET_VISIBILITY_INTERNAL]: { label: __('Internal'), + icon: 'shield', description: __('The snippet is visible to any logged in user.'), }, - public: { + [SNIPPET_VISIBILITY_PUBLIC]: { label: __('Public'), + icon: 'earth', description: __('The snippet can be accessed without any authentication.'), }, }; diff --git a/app/assets/stylesheets/pages/note_form.scss b/app/assets/stylesheets/pages/note_form.scss index 43c7c03fa58..57afe45a74b 100644 --- a/app/assets/stylesheets/pages/note_form.scss +++ b/app/assets/stylesheets/pages/note_form.scss @@ -281,7 +281,7 @@ table { display: table; svg { - fill: $gray-darkest; + fill: $gray-700; } .btn-group { diff --git a/app/assets/stylesheets/pages/notes.scss b/app/assets/stylesheets/pages/notes.scss index 25d8fc1f9a3..8b51ba7ae62 100644 --- a/app/assets/stylesheets/pages/notes.scss +++ b/app/assets/stylesheets/pages/notes.scss @@ -855,7 +855,7 @@ $note-form-margin-left: 72px; line-height: $gl-line-height; svg { - fill: $gray-darkest; + fill: $gray-700; } &.discussion-create-issue-btn { @@ -893,7 +893,7 @@ $note-form-margin-left: 72px; .line-resolve-btn { margin-right: 5px; - color: $gray-darkest; + color: $gray-700; svg { vertical-align: middle; diff --git a/app/finders/projects_finder.rb b/app/finders/projects_finder.rb index 961694bd91f..2c3611875a2 100644 --- a/app/finders/projects_finder.rb +++ b/app/finders/projects_finder.rb @@ -21,6 +21,8 @@ # non_archived: boolean # archived: 'only' or boolean # min_access_level: integer +# last_activity_after: datetime +# last_activity_before: datetime # class ProjectsFinder < UnionFinder include CustomAttributesFilter @@ -73,6 +75,8 @@ class ProjectsFinder < UnionFinder collection = by_archived(collection) collection = by_custom_attributes(collection) collection = by_deleted_status(collection) + collection = by_last_activity_after(collection) + collection = by_last_activity_before(collection) collection end @@ -179,6 +183,22 @@ class ProjectsFinder < UnionFinder params[:without_deleted].present? ? items.without_deleted : items end + def by_last_activity_after(items) + if params[:last_activity_after].present? + items.where("last_activity_at > ?", params[:last_activity_after]) # rubocop: disable CodeReuse/ActiveRecord + else + items + end + end + + def by_last_activity_before(items) + if params[:last_activity_before].present? + items.where("last_activity_at < ?", params[:last_activity_before]) # rubocop: disable CodeReuse/ActiveRecord + else + items + end + end + def sort(items) params[:sort].present? ? items.sort_by_attribute(params[:sort]) : items.projects_order_id_desc end diff --git a/app/models/label.rb b/app/models/label.rb index d9c5fe0bb39..652b5e23490 100644 --- a/app/models/label.rb +++ b/app/models/label.rb @@ -159,6 +159,11 @@ class Label < ApplicationRecord on_project_boards(project_id).where(id: label_id).exists? end + # Generate a hex color based on hex-encoded value + def self.color_for(value) + "##{Digest::MD5.hexdigest(value)[0..5]}" + end + def open_issues_count(user = nil) issues_count(user, state: 'opened') end diff --git a/app/workers/gitlab/jira_import/import_issue_worker.rb b/app/workers/gitlab/jira_import/import_issue_worker.rb index 832916a03b6..7ace0a35fd9 100644 --- a/app/workers/gitlab/jira_import/import_issue_worker.rb +++ b/app/workers/gitlab/jira_import/import_issue_worker.rb @@ -9,8 +9,8 @@ module Gitlab include Gitlab::Import::DatabaseHelpers def perform(project_id, jira_issue_id, issue_attributes, waiter_key) - issue_id = insert_and_return_id(issue_attributes, Issue) - cache_issue_mapping(issue_id, jira_issue_id, project_id) + issue_id = create_issue(issue_attributes, project_id) + JiraImport.cache_issue_mapping(issue_id, jira_issue_id, project_id) rescue => ex # Todo: Record jira issue id(or better jira issue key), # so that we can report the list of failed to import issues to the user @@ -27,9 +27,31 @@ module Gitlab private - def cache_issue_mapping(issue_id, jira_issue_id, project_id) - cache_key = JiraImport.jira_issue_cache_key(project_id, jira_issue_id) - Gitlab::Cache::Import::Caching.write(cache_key, issue_id) + def create_issue(issue_attributes, project_id) + issue_id = insert_and_return_id(issue_attributes, Issue) + + label_issue(project_id, issue_id) + + issue_id + end + + def label_issue(project_id, issue_id) + label_id = JiraImport.get_import_label_id(project_id) + return unless label_id + + label_link_attrs = build_label_attrs(issue_id, label_id.to_i) + insert_and_return_id(label_link_attrs, LabelLink) + end + + def build_label_attrs(issue_id, label_id) + time = Time.now + { + label_id: label_id, + target_id: issue_id, + target_type: 'Issue', + created_at: time, + updated_at: time + } end end end diff --git a/app/workers/gitlab/jira_import/stage/import_labels_worker.rb b/app/workers/gitlab/jira_import/stage/import_labels_worker.rb index b96bb1bbdda..0499749198a 100644 --- a/app/workers/gitlab/jira_import/stage/import_labels_worker.rb +++ b/app/workers/gitlab/jira_import/stage/import_labels_worker.rb @@ -9,10 +9,8 @@ module Gitlab private def import(project) - # fake labels import workers for now - # new job waiter will have zero jobs_remaining by default, so it will just pass on to next stage - fake_waiter = JobWaiter.new - Gitlab::JiraImport::AdvanceStageWorker.perform_async(project.id, { fake_waiter.key => fake_waiter.jobs_remaining }, :issues) + job_waiter = Gitlab::JiraImport::LabelsImporter.new(project).execute + Gitlab::JiraImport::AdvanceStageWorker.perform_async(project.id, { job_waiter.key => job_waiter.jobs_remaining }, :issues) end end end |