summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/assets/javascripts/diffs/components/diff_file_header.vue1
-rw-r--r--app/assets/javascripts/snippets/components/snippet_blob_edit.vue21
-rw-r--r--app/assets/javascripts/snippets/components/snippet_description_edit.vue22
-rw-r--r--app/assets/javascripts/snippets/components/snippet_visibility_edit.vue60
-rw-r--r--app/assets/javascripts/snippets/constants.js9
-rw-r--r--app/assets/stylesheets/pages/note_form.scss2
-rw-r--r--app/assets/stylesheets/pages/notes.scss4
-rw-r--r--app/finders/projects_finder.rb20
-rw-r--r--app/models/label.rb5
-rw-r--r--app/workers/gitlab/jira_import/import_issue_worker.rb32
-rw-r--r--app/workers/gitlab/jira_import/stage/import_labels_worker.rb6
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