Commit fa61df4a authored by GitLab Bot's avatar GitLab Bot

Automatic merge of gitlab-org/gitlab master

parents 6e56ad42 26c1972c
......@@ -12,31 +12,6 @@ export default {
required: true,
},
},
data() {
return {
currentlyHighlightedLine: null,
};
},
mounted() {
this.scrollToLine();
},
methods: {
scrollToLine(hash = window.location.hash) {
const lineToHighlight = hash && this.$el.querySelector(hash);
if (!lineToHighlight) {
return;
}
if (this.currentlyHighlightedLine) {
this.currentlyHighlightedLine.classList.remove('hll');
}
lineToHighlight.classList.add('hll');
this.currentlyHighlightedLine = lineToHighlight;
lineToHighlight.scrollIntoView({ behavior: 'smooth', block: 'center' });
},
},
};
</script>
<template>
......@@ -46,9 +21,9 @@ export default {
:id="`L${line}`"
:key="line"
class="diff-line-num"
:href="`#L${line}`"
:href="`#LC${line}`"
:data-line-number="line"
@click="scrollToLine(`#L${line}`)"
@click="$emit('select-line', `#LC${line}`)"
>
<gl-icon :size="12" name="link" />
{{ line }}
......
<script>
import { GlSafeHtmlDirective } from '@gitlab/ui';
import LineNumbers from '~/vue_shared/components/line_numbers.vue';
import { sanitize } from '~/lib/dompurify';
const LINE_SELECT_CLASS_NAME = 'hll';
export default {
components: {
......@@ -46,7 +49,12 @@ export default {
}
}
return highlightedContent;
return this.wrapLines(highlightedContent);
},
},
watch: {
highlightedContent() {
this.$nextTick(() => this.selectLine());
},
},
async mounted() {
......@@ -73,16 +81,39 @@ export default {
return languageDefinition;
},
wrapLines(content) {
return (
content &&
content
.split('\n')
.map((line, i) => `<span id="LC${i + 1}" class="line">${line}</span>`)
.join('\r\n')
);
},
selectLine(hash = sanitize(window.location.hash)) {
const lineToSelect = hash && this.$el.querySelector(hash);
if (!lineToSelect) {
return;
}
if (this.$options.currentlySelectedLine) {
this.$options.currentlySelectedLine.classList.remove(LINE_SELECT_CLASS_NAME);
}
lineToSelect.classList.add(LINE_SELECT_CLASS_NAME);
this.$options.currentlySelectedLine = lineToSelect;
lineToSelect.scrollIntoView({ behavior: 'smooth', block: 'center' });
},
},
userColorScheme: window.gon.user_color_scheme,
currentlySelectedLine: null,
};
</script>
<template>
<div class="file-content code" :class="$options.userColorScheme">
<line-numbers :lines="lineNumbers" />
<pre
class="code gl-pl-3!"
><code v-safe-html="highlightedContent" class="gl-white-space-pre-wrap!"></code>
<line-numbers :lines="lineNumbers" @select-line="selectLine" />
<pre class="code"><code v-safe-html="highlightedContent"></code>
</pre>
</div>
</template>
......@@ -22,10 +22,6 @@
}
}
.members-ldap {
align-self: center;
}
.card {
.card-header {
.badge.badge-pill {
......
# frozen_string_literal: true
class AddClusterAgentIdToVulnerabilityReads < Gitlab::Database::Migration[1.0]
# rubocop:disable Migration/AddLimitToTextColumns
# limit is added in 20211216134134_add_text_limit_to_vulnerability_reads_cluster_agent_id.rb
def change
add_column :vulnerability_reads, :cluster_agent_id, :text
end
# rubocop:enable Migration/AddLimitToTextColumns
end
# frozen_string_literal: true
class AddTextLimitToVulnerabilityReadsClusterAgentId < Gitlab::Database::Migration[1.0]
disable_ddl_transaction!
def up
add_text_limit :vulnerability_reads, :cluster_agent_id, 10
end
def down
remove_text_limit :vulnerability_reads, :cluster_agent_id
end
end
# frozen_string_literal: true
class AddIndexToClusterAgentId < Gitlab::Database::Migration[1.0]
disable_ddl_transaction!
INDEX_NAME = "index_vulnerability_reads_on_cluster_agent_id"
CLUSTER_IMAGE_SCANNING_REPORT_TYPE = 7
def up
add_concurrent_index :vulnerability_reads, :cluster_agent_id, where: "report_type = #{CLUSTER_IMAGE_SCANNING_REPORT_TYPE}", name: INDEX_NAME
end
def down
remove_concurrent_index_by_name :vulnerability_reads, INDEX_NAME
end
end
a0c3a9746250aa67ffa8d05486fb6997c8d839b8bce7e870c0415c25600c5434
\ No newline at end of file
c53a1e4405187620929b8fc6877786cb713d13218f7385d1b9b3daaf6072fa05
\ No newline at end of file
9b733363587957b4044bc6806dfbb9632ec7f5f6ffc8c82280e025012b8acb5a
\ No newline at end of file
......@@ -20893,7 +20893,9 @@ CREATE TABLE vulnerability_reads (
resolved_on_default_branch boolean DEFAULT false NOT NULL,
uuid uuid NOT NULL,
location_image text,
CONSTRAINT check_380451bdbe CHECK ((char_length(location_image) <= 2048))
cluster_agent_id text,
CONSTRAINT check_380451bdbe CHECK ((char_length(location_image) <= 2048)),
CONSTRAINT check_a105eb825a CHECK ((char_length(cluster_agent_id) <= 10))
);
CREATE SEQUENCE vulnerability_reads_id_seq
......@@ -27878,6 +27880,8 @@ CREATE UNIQUE INDEX index_vulnerability_occurrences_on_uuid ON vulnerability_occ
CREATE INDEX index_vulnerability_occurrences_on_vulnerability_id ON vulnerability_occurrences USING btree (vulnerability_id);
CREATE INDEX index_vulnerability_reads_on_cluster_agent_id ON vulnerability_reads USING btree (cluster_agent_id) WHERE (report_type = 7);
CREATE INDEX index_vulnerability_reads_on_location_image ON vulnerability_reads USING btree (location_image) WHERE (report_type = ANY (ARRAY[2, 7]));
CREATE INDEX index_vulnerability_reads_on_scanner_id ON vulnerability_reads USING btree (scanner_id);
- can_override = local_assigns.fetch(:can_override, false)
- if can_override
%span.badge.badge-info.members-ldap.d-sm-block.mr-md-4
LDAP
= gl_badge_tag 'LDAP', { variant: :info }, { class: 'gl-sm-display-block gl-align-self-center gl-md-mr-5' }
......@@ -88,7 +88,8 @@ RSpec.describe 'Database schema' do
users_star_projects: %w[user_id],
vulnerability_identifiers: %w[external_id],
vulnerability_scanners: %w[external_id],
security_scans: %w[pipeline_id] # foreign key is not added as ci_pipeline table will be moved into different db soon
security_scans: %w[pipeline_id], # foreign key is not added as ci_pipeline table will be moved into different db soon
vulnerability_reads: %w[cluster_agent_id]
}.with_indifferent_access.freeze
context 'for table' do
......
......@@ -13,7 +13,6 @@ describe('Line Numbers component', () => {
const findGlIcon = () => wrapper.findComponent(GlIcon);
const findLineNumbers = () => wrapper.findAllComponents(GlLink);
const findFirstLineNumber = () => findLineNumbers().at(0);
const findSecondLineNumber = () => findLineNumbers().at(1);
beforeEach(() => createComponent());
......@@ -24,7 +23,7 @@ describe('Line Numbers component', () => {
expect(findLineNumbers().length).toBe(lines);
expect(findFirstLineNumber().attributes()).toMatchObject({
id: 'L1',
href: '#L1',
href: '#LC1',
});
});
......@@ -37,35 +36,13 @@ describe('Line Numbers component', () => {
});
describe('clicking a line number', () => {
let firstLineNumber;
let firstLineNumberElement;
beforeEach(() => {
firstLineNumber = findFirstLineNumber();
firstLineNumberElement = firstLineNumber.element;
jest.spyOn(firstLineNumberElement, 'scrollIntoView');
jest.spyOn(firstLineNumberElement.classList, 'add');
jest.spyOn(firstLineNumberElement.classList, 'remove');
firstLineNumber.vm.$emit('click');
});
it('adds the highlight (hll) class', () => {
expect(firstLineNumberElement.classList.add).toHaveBeenCalledWith('hll');
jest.spyOn(wrapper.vm, '$emit');
findFirstLineNumber().vm.$emit('click');
});
it('removes the highlight (hll) class from a previously highlighted line', () => {
findSecondLineNumber().vm.$emit('click');
expect(firstLineNumberElement.classList.remove).toHaveBeenCalledWith('hll');
});
it('scrolls the line into view', () => {
expect(firstLineNumberElement.scrollIntoView).toHaveBeenCalledWith({
behavior: 'smooth',
block: 'center',
});
it('emits a select-line event', () => {
expect(wrapper.vm.$emit).toHaveBeenCalledWith('select-line', '#LC1');
});
});
});
......@@ -9,7 +9,7 @@ jest.mock('highlight.js/lib/core');
describe('Source Viewer component', () => {
let wrapper;
const content = `// Some source code`;
const highlightedContent = `<span data-testid='test-highlighted'>${content}</span>`;
const highlightedContent = `<span data-testid='test-highlighted' id='LC1'>${content}</span><span id='LC2'></span>`;
const language = 'javascript';
hljs.highlight.mockImplementation(() => ({ value: highlightedContent }));
......@@ -22,6 +22,7 @@ describe('Source Viewer component', () => {
const findLineNumbers = () => wrapper.findComponent(LineNumbers);
const findHighlightedContent = () => wrapper.findByTestId('test-highlighted');
const findFirstLine = () => wrapper.find('#LC1');
beforeEach(() => createComponent());
......@@ -56,4 +57,37 @@ describe('Source Viewer component', () => {
expect(findHighlightedContent().exists()).toBe(true);
});
});
describe('selecting a line', () => {
let firstLine;
let firstLineElement;
beforeEach(() => {
firstLine = findFirstLine();
firstLineElement = firstLine.element;
jest.spyOn(firstLineElement, 'scrollIntoView');
jest.spyOn(firstLineElement.classList, 'add');
jest.spyOn(firstLineElement.classList, 'remove');
findLineNumbers().vm.$emit('select-line', '#LC1');
});
it('adds the highlight (hll) class', () => {
expect(firstLineElement.classList.add).toHaveBeenCalledWith('hll');
});
it('removes the highlight (hll) class from a previously highlighted line', () => {
findLineNumbers().vm.$emit('select-line', '#LC2');
expect(firstLineElement.classList.remove).toHaveBeenCalledWith('hll');
});
it('scrolls the line into view', () => {
expect(firstLineElement.scrollIntoView).toHaveBeenCalledWith({
behavior: 'smooth',
block: 'center',
});
});
});
});
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment