summaryrefslogtreecommitdiff
path: root/app/assets
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets')
-rw-r--r--app/assets/javascripts/blob/file_template_selector.js2
-rw-r--r--app/assets/javascripts/blob/template_selectors/license_selector.js1
-rw-r--r--app/assets/javascripts/boards/components/board_card_layout.vue4
-rw-r--r--app/assets/javascripts/deprecated_jquery_dropdown/gl_dropdown.js1
-rw-r--r--app/assets/javascripts/editor/extensions/editor_ci_schema_ext.js10
-rw-r--r--app/assets/javascripts/ide/stores/actions/file.js21
-rw-r--r--app/assets/javascripts/incidents_settings/constants.js2
-rw-r--r--app/assets/javascripts/issue_show/components/app.vue7
-rw-r--r--app/assets/javascripts/issue_show/components/fields/description_template.vue11
-rw-r--r--app/assets/javascripts/issue_show/components/form.vue11
-rw-r--r--app/assets/javascripts/issue_show/issue.js1
-rw-r--r--app/assets/javascripts/issue_show/stores/index.js2
-rw-r--r--app/assets/javascripts/pipeline_editor/components/lint/ci_lint.vue15
-rw-r--r--app/assets/javascripts/pipeline_editor/components/lint/ci_lint_results_value.vue2
-rw-r--r--app/assets/javascripts/pipeline_editor/graphql/mutations/lint_ci.mutation.graphql2
-rw-r--r--app/assets/javascripts/pipeline_editor/graphql/resolvers.js2
-rw-r--r--app/assets/javascripts/pipeline_editor/pipeline_editor_app.vue36
-rw-r--r--app/assets/javascripts/pipelines/graphql/fragments/pipeline_stages_connection.fragment.graphql13
-rw-r--r--app/assets/javascripts/templates/issuable_template_selector.js23
-rw-r--r--app/assets/stylesheets/page_bundles/oncall_schedules.scss8
20 files changed, 112 insertions, 62 deletions
diff --git a/app/assets/javascripts/blob/file_template_selector.js b/app/assets/javascripts/blob/file_template_selector.js
index 2532aeea989..a5c8050b772 100644
--- a/app/assets/javascripts/blob/file_template_selector.js
+++ b/app/assets/javascripts/blob/file_template_selector.js
@@ -66,6 +66,8 @@ export default class FileTemplateSelector {
reportSelectionName(options) {
const opts = options;
opts.query = options.selectedObj.name;
+ opts.data = options.selectedObj;
+ opts.data.source_template_project_id = options.selectedObj.project_id;
this.reportSelection(opts);
}
diff --git a/app/assets/javascripts/blob/template_selectors/license_selector.js b/app/assets/javascripts/blob/template_selectors/license_selector.js
index affa20997e9..7e32ede96df 100644
--- a/app/assets/javascripts/blob/template_selectors/license_selector.js
+++ b/app/assets/javascripts/blob/template_selectors/license_selector.js
@@ -30,6 +30,7 @@ export default class BlobLicenseSelector extends FileTemplateSelector {
const data = {
project: this.$dropdown.data('project'),
fullname: this.$dropdown.data('fullname'),
+ source_template_project_id: query.project_id,
};
this.reportSelection({
diff --git a/app/assets/javascripts/boards/components/board_card_layout.vue b/app/assets/javascripts/boards/components/board_card_layout.vue
index 350d709abfd..8b0265237ba 100644
--- a/app/assets/javascripts/boards/components/board_card_layout.vue
+++ b/app/assets/javascripts/boards/components/board_card_layout.vue
@@ -4,7 +4,7 @@ import IssueCardInnerDeprecated from './issue_card_inner_deprecated.vue';
import boardsStore from '../stores/boards_store';
export default {
- name: 'BoardsIssueCard',
+ name: 'BoardCardLayout',
components: {
IssueCardInner: gon.features?.graphqlBoardLists ? IssueCardInner : IssueCardInnerDeprecated,
},
@@ -81,7 +81,7 @@ export default {
:data-issue-iid="issue.iid"
:data-issue-path="issue.referencePath"
data-testid="board_card"
- class="board-card p-3 rounded"
+ class="board-card gl-p-5 gl-rounded-base"
@mousedown="mouseDown"
@mousemove="mouseMove"
@mouseup="showIssue($event)"
diff --git a/app/assets/javascripts/deprecated_jquery_dropdown/gl_dropdown.js b/app/assets/javascripts/deprecated_jquery_dropdown/gl_dropdown.js
index 99351231520..98858f20518 100644
--- a/app/assets/javascripts/deprecated_jquery_dropdown/gl_dropdown.js
+++ b/app/assets/javascripts/deprecated_jquery_dropdown/gl_dropdown.js
@@ -437,6 +437,7 @@ export class GitLabDropdown {
groupName = el.data('group');
if (groupName) {
selectedIndex = el.data('index');
+ this.selectedIndex = selectedIndex;
selectedObject = this.renderedData[groupName][selectedIndex];
} else {
selectedIndex = el.closest('li').index();
diff --git a/app/assets/javascripts/editor/extensions/editor_ci_schema_ext.js b/app/assets/javascripts/editor/extensions/editor_ci_schema_ext.js
index 05d938c57ce..eb47c20912e 100644
--- a/app/assets/javascripts/editor/extensions/editor_ci_schema_ext.js
+++ b/app/assets/javascripts/editor/extensions/editor_ci_schema_ext.js
@@ -17,15 +17,21 @@ export class CiSchemaExtension extends EditorLiteExtension {
* @param {String?} opts.ref - Current ref. Defaults to master
*/
registerCiSchema({ projectNamespace, projectPath, ref = 'master' } = {}) {
- const ciSchemaUri = Api.buildUrl(Api.projectFileSchemaPath)
+ const ciSchemaPath = Api.buildUrl(Api.projectFileSchemaPath)
.replace(':namespace_path', projectNamespace)
.replace(':project_path', projectPath)
.replace(':ref', ref)
.replace(':filename', EXTENSION_CI_SCHEMA_FILE_NAME_MATCH);
+ // In order for workers loaded from `data://` as the
+ // ones loaded by monaco editor, we use absolute URLs
+ // to fetch schema files, hence the `gon.gitlab_url`
+ // reference. This prevents error:
+ // "Failed to execute 'fetch' on 'WorkerGlobalScope'"
+ const absoluteSchemaUrl = gon.gitlab_url + ciSchemaPath;
const modelFileName = this.getModel().uri.path.split('/').pop();
registerSchema({
- uri: ciSchemaUri,
+ uri: absoluteSchemaUrl,
fileMatch: [modelFileName],
});
}
diff --git a/app/assets/javascripts/ide/stores/actions/file.js b/app/assets/javascripts/ide/stores/actions/file.js
index 004e38b0a25..42668dec63a 100644
--- a/app/assets/javascripts/ide/stores/actions/file.js
+++ b/app/assets/javascripts/ide/stores/actions/file.js
@@ -17,15 +17,8 @@ export const closeFile = ({ commit, state, dispatch, getters }, file) => {
const indexOfClosedFile = state.openFiles.findIndex((f) => f.key === file.key);
const fileWasActive = file.active;
- if (file.pending) {
- commit(types.REMOVE_PENDING_TAB, file);
- } else {
- commit(types.TOGGLE_FILE_OPEN, path);
- commit(types.SET_FILE_ACTIVE, { path, active: false });
- }
-
- if (state.openFiles.length > 0 && fileWasActive) {
- const nextIndexToOpen = indexOfClosedFile === 0 ? 0 : indexOfClosedFile - 1;
+ if (state.openFiles.length > 1 && fileWasActive) {
+ const nextIndexToOpen = indexOfClosedFile === 0 ? 1 : indexOfClosedFile - 1;
const nextFileToOpen = state.openFiles[nextIndexToOpen];
if (nextFileToOpen.pending) {
@@ -35,14 +28,22 @@ export const closeFile = ({ commit, state, dispatch, getters }, file) => {
keyPrefix: nextFileToOpen.staged ? 'staged' : 'unstaged',
});
} else {
+ dispatch('setFileActive', nextFileToOpen.path);
dispatch('router/push', getters.getUrlForPath(nextFileToOpen.path), { root: true });
}
- } else if (!state.openFiles.length) {
+ } else if (state.openFiles.length === 1) {
dispatch('router/push', `/project/${state.currentProjectId}/tree/${state.currentBranchId}/`, {
root: true,
});
}
+ if (file.pending) {
+ commit(types.REMOVE_PENDING_TAB, file);
+ } else {
+ commit(types.TOGGLE_FILE_OPEN, path);
+ commit(types.SET_FILE_ACTIVE, { path, active: false });
+ }
+
eventHub.$emit(`editor.update.model.dispose.${file.key}`);
};
diff --git a/app/assets/javascripts/incidents_settings/constants.js b/app/assets/javascripts/incidents_settings/constants.js
index fcac9c519c2..818af4ecb90 100644
--- a/app/assets/javascripts/incidents_settings/constants.js
+++ b/app/assets/javascripts/incidents_settings/constants.js
@@ -51,7 +51,7 @@ export const NO_ISSUE_TEMPLATE_SELECTED = { key: '', name: __('No template selec
export const TAKING_INCIDENT_ACTION_DOCS_LINK =
'/help/operations/metrics/alerts#trigger-actions-from-alerts';
export const ISSUE_TEMPLATES_DOCS_LINK =
- '/help/user/project/description_templates#creating-issue-templates';
+ '/help/user/project/description_templates#create-an-issue-template';
/* PagerDuty integration settings constants */
diff --git a/app/assets/javascripts/issue_show/components/app.vue b/app/assets/javascripts/issue_show/components/app.vue
index d569ad573a2..87dc31e6292 100644
--- a/app/assets/javascripts/issue_show/components/app.vue
+++ b/app/assets/javascripts/issue_show/components/app.vue
@@ -132,6 +132,10 @@ export default {
type: String,
required: true,
},
+ projectId: {
+ type: Number,
+ required: true,
+ },
projectNamespace: {
type: String,
required: true,
@@ -303,7 +307,7 @@ export default {
});
},
- updateAndShowForm(templates = []) {
+ updateAndShowForm(templates = {}) {
if (!this.showForm) {
this.showForm = true;
this.store.setFormState({
@@ -419,6 +423,7 @@ export default {
:markdown-docs-path="markdownDocsPath"
:markdown-preview-path="markdownPreviewPath"
:project-path="projectPath"
+ :project-id="projectId"
:project-namespace="projectNamespace"
:show-delete-button="showDeleteButton"
:can-attach-file="canAttachFile"
diff --git a/app/assets/javascripts/issue_show/components/fields/description_template.vue b/app/assets/javascripts/issue_show/components/fields/description_template.vue
index 71299381aae..f23bb394683 100644
--- a/app/assets/javascripts/issue_show/components/fields/description_template.vue
+++ b/app/assets/javascripts/issue_show/components/fields/description_template.vue
@@ -13,14 +13,18 @@ export default {
required: true,
},
issuableTemplates: {
- type: Array,
+ type: Object,
required: false,
- default: () => [],
+ default: () => {},
},
projectPath: {
type: String,
required: true,
},
+ projectId: {
+ type: Number,
+ required: true,
+ },
projectNamespace: {
type: String,
required: true,
@@ -48,11 +52,12 @@ export default {
</script>
<template>
- <div class="dropdown js-issuable-selector-wrap" data-issuable-type="issue">
+ <div class="dropdown js-issuable-selector-wrap" data-issuable-type="issues">
<button
ref="toggle"
:data-namespace-path="projectNamespace"
:data-project-path="projectPath"
+ :data-project-id="projectId"
:data-data="issuableTemplatesJson"
class="dropdown-menu-toggle js-issuable-selector"
type="button"
diff --git a/app/assets/javascripts/issue_show/components/form.vue b/app/assets/javascripts/issue_show/components/form.vue
index d48bf1fe7a9..9d1ce01116b 100644
--- a/app/assets/javascripts/issue_show/components/form.vue
+++ b/app/assets/javascripts/issue_show/components/form.vue
@@ -26,9 +26,9 @@ export default {
required: true,
},
issuableTemplates: {
- type: Array,
+ type: Object,
required: false,
- default: () => [],
+ default: () => {},
},
issuableType: {
type: String,
@@ -46,6 +46,10 @@ export default {
type: String,
required: true,
},
+ projectId: {
+ type: Number,
+ required: true,
+ },
projectNamespace: {
type: String,
required: true,
@@ -68,7 +72,7 @@ export default {
},
computed: {
hasIssuableTemplates() {
- return this.issuableTemplates.length;
+ return Object.values(Object(this.issuableTemplates)).length;
},
showLockedWarning() {
return this.formState.lockedWarningVisible && !this.formState.updateLoading;
@@ -127,6 +131,7 @@ export default {
:form-state="formState"
:issuable-templates="issuableTemplates"
:project-path="projectPath"
+ :project-id="projectId"
:project-namespace="projectNamespace"
/>
</div>
diff --git a/app/assets/javascripts/issue_show/issue.js b/app/assets/javascripts/issue_show/issue.js
index 83fd1355f26..a93abbf64df 100644
--- a/app/assets/javascripts/issue_show/issue.js
+++ b/app/assets/javascripts/issue_show/issue.js
@@ -54,6 +54,7 @@ export function initIssueHeaderActions(store) {
issueType: el.dataset.issueType,
newIssuePath: el.dataset.newIssuePath,
projectPath: el.dataset.projectPath,
+ projectId: el.dataset.projectId,
reportAbusePath: el.dataset.reportAbusePath,
submitAsSpamPath: el.dataset.submitAsSpamPath,
},
diff --git a/app/assets/javascripts/issue_show/stores/index.js b/app/assets/javascripts/issue_show/stores/index.js
index 06bbd406e3a..a50913d3455 100644
--- a/app/assets/javascripts/issue_show/stores/index.js
+++ b/app/assets/javascripts/issue_show/stores/index.js
@@ -11,7 +11,7 @@ export default class Store {
lockedWarningVisible: false,
updateLoading: false,
lock_version: 0,
- issuableTemplates: [],
+ issuableTemplates: {},
};
}
diff --git a/app/assets/javascripts/pipeline_editor/components/lint/ci_lint.vue b/app/assets/javascripts/pipeline_editor/components/lint/ci_lint.vue
index 22f734be5aa..b27ab9a39d3 100644
--- a/app/assets/javascripts/pipeline_editor/components/lint/ci_lint.vue
+++ b/app/assets/javascripts/pipeline_editor/components/lint/ci_lint.vue
@@ -1,4 +1,5 @@
<script>
+import { flatten } from 'lodash';
import { CI_CONFIG_STATUS_VALID } from '../../constants';
import CiLintResults from './ci_lint_results.vue';
@@ -25,14 +26,18 @@ export default {
return this.ciConfig?.stages || [];
},
jobs() {
- return this.stages.reduce((acc, { groups, name: stageName }) => {
+ const groupedJobs = this.stages.reduce((acc, { groups, name: stageName }) => {
return acc.concat(
- groups.map(({ name: groupName }) => ({
- stage: stageName,
- name: groupName,
- })),
+ groups.map(({ jobs }) => {
+ return jobs.map((job) => ({
+ stage: stageName,
+ ...job,
+ }));
+ }),
);
}, []);
+
+ return flatten(groupedJobs);
},
},
};
diff --git a/app/assets/javascripts/pipeline_editor/components/lint/ci_lint_results_value.vue b/app/assets/javascripts/pipeline_editor/components/lint/ci_lint_results_value.vue
index 6c7e03e4920..e2529613844 100644
--- a/app/assets/javascripts/pipeline_editor/components/lint/ci_lint_results_value.vue
+++ b/app/assets/javascripts/pipeline_editor/components/lint/ci_lint_results_value.vue
@@ -14,7 +14,7 @@ export default {
},
computed: {
tagList() {
- return this.item.tagList?.join(', ');
+ return this.item.tags?.join(', ');
},
onlyPolicy() {
return this.item.only ? this.item.only.refs.join(', ') : this.item.only;
diff --git a/app/assets/javascripts/pipeline_editor/graphql/mutations/lint_ci.mutation.graphql b/app/assets/javascripts/pipeline_editor/graphql/mutations/lint_ci.mutation.graphql
index 496036f690f..5091d63111f 100644
--- a/app/assets/javascripts/pipeline_editor/graphql/mutations/lint_ci.mutation.graphql
+++ b/app/assets/javascripts/pipeline_editor/graphql/mutations/lint_ci.mutation.graphql
@@ -15,7 +15,7 @@ mutation lintCI($endpoint: String, $content: String, $dry: Boolean) {
}
afterScript
stage
- tagList
+ tags
when
}
}
diff --git a/app/assets/javascripts/pipeline_editor/graphql/resolvers.js b/app/assets/javascripts/pipeline_editor/graphql/resolvers.js
index ec55191c946..81e75c32846 100644
--- a/app/assets/javascripts/pipeline_editor/graphql/resolvers.js
+++ b/app/assets/javascripts/pipeline_editor/graphql/resolvers.js
@@ -27,7 +27,7 @@ export const resolvers = {
beforeScript: job.before_script,
script: job.script,
afterScript: job.after_script,
- tagList: job.tag_list,
+ tags: job.tag_list,
environment: job.environment,
when: job.when,
allowFailure: job.allow_failure,
diff --git a/app/assets/javascripts/pipeline_editor/pipeline_editor_app.vue b/app/assets/javascripts/pipeline_editor/pipeline_editor_app.vue
index 9217466a0b5..d6884ae121f 100644
--- a/app/assets/javascripts/pipeline_editor/pipeline_editor_app.vue
+++ b/app/assets/javascripts/pipeline_editor/pipeline_editor_app.vue
@@ -3,6 +3,7 @@ import { GlAlert, GlLoadingIcon, GlTabs, GlTab } from '@gitlab/ui';
import { __, s__, sprintf } from '~/locale';
import { mergeUrlParams, redirectTo } from '~/lib/utils/url_utility';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
+import httpStatusCodes from '~/lib/utils/http_status';
import PipelineGraph from '~/pipelines/components/pipeline_graph/pipeline_graph.vue';
import CiLint from './components/lint/ci_lint.vue';
@@ -23,7 +24,6 @@ const COMMIT_FAILURE = 'COMMIT_FAILURE';
const COMMIT_SUCCESS = 'COMMIT_SUCCESS';
const DEFAULT_FAILURE = 'DEFAULT_FAILURE';
const LOAD_FAILURE_NO_FILE = 'LOAD_FAILURE_NO_FILE';
-const LOAD_FAILURE_NO_REF = 'LOAD_FAILURE_NO_REF';
const LOAD_FAILURE_UNKNOWN = 'LOAD_FAILURE_UNKNOWN';
export default {
@@ -125,6 +125,9 @@ export default {
isBlobContentLoading() {
return this.$apollo.queries.content.loading;
},
+ isBlobContentError() {
+ return this.failureType === LOAD_FAILURE_NO_FILE || this.failureType === LOAD_FAILURE_UNKNOWN;
+ },
isCiConfigDataLoading() {
return this.$apollo.queries.ciConfigData.loading;
},
@@ -144,14 +147,11 @@ export default {
},
failure() {
switch (this.failureType) {
- case LOAD_FAILURE_NO_REF:
- return {
- text: this.$options.alertTexts[LOAD_FAILURE_NO_REF],
- variant: 'danger',
- };
case LOAD_FAILURE_NO_FILE:
return {
- text: this.$options.alertTexts[LOAD_FAILURE_NO_FILE],
+ text: sprintf(this.$options.alertTexts[LOAD_FAILURE_NO_FILE], {
+ filePath: this.ciConfigPath,
+ }),
variant: 'danger',
};
case LOAD_FAILURE_UNKNOWN:
@@ -182,9 +182,8 @@ export default {
[COMMIT_FAILURE]: s__('Pipelines|The GitLab CI configuration could not be updated.'),
[COMMIT_SUCCESS]: __('Your changes have been successfully committed.'),
[DEFAULT_FAILURE]: __('Something went wrong on our end.'),
- [LOAD_FAILURE_NO_FILE]: s__('Pipelines|No CI file found in this repository, please add one.'),
- [LOAD_FAILURE_NO_REF]: s__(
- 'Pipelines|Repository does not have a default branch, please set one.',
+ [LOAD_FAILURE_NO_FILE]: s__(
+ 'Pipelines|There is no %{filePath} file in this repository, please add one and visit the Pipeline Editor again.',
),
[LOAD_FAILURE_UNKNOWN]: s__('Pipelines|The CI configuration was not loaded, please try again.'),
},
@@ -193,12 +192,13 @@ export default {
const { networkError } = error;
const { response } = networkError;
- if (response?.status === 404) {
- // 404 for missing CI file
+ // 404 for missing CI file
+ // 400 for blank projects with no repository
+ if (
+ response?.status === httpStatusCodes.NOT_FOUND ||
+ response?.status === httpStatusCodes.BAD_REQUEST
+ ) {
this.reportFailure(LOAD_FAILURE_NO_FILE);
- } else if (response?.status === 400) {
- // 400 for a missing ref when no default branch is set
- this.reportFailure(LOAD_FAILURE_NO_REF);
} else {
this.reportFailure(LOAD_FAILURE_UNKNOWN);
}
@@ -299,9 +299,9 @@ export default {
<li v-for="reason in failureReasons" :key="reason">{{ reason }}</li>
</ul>
</gl-alert>
- <div class="gl-mt-4">
- <gl-loading-icon v-if="isBlobContentLoading" size="lg" class="gl-m-3" />
- <div v-else class="file-editor gl-mb-3">
+ <gl-loading-icon v-if="isBlobContentLoading" size="lg" class="gl-m-3" />
+ <div v-else-if="!isBlobContentError" class="gl-mt-4">
+ <div class="file-editor gl-mb-3">
<div class="info-well gl-display-none gl-display-sm-block">
<validation-segment
class="well-segment"
diff --git a/app/assets/javascripts/pipelines/graphql/fragments/pipeline_stages_connection.fragment.graphql b/app/assets/javascripts/pipelines/graphql/fragments/pipeline_stages_connection.fragment.graphql
index 683e0ee6a14..f93908aeb04 100644
--- a/app/assets/javascripts/pipelines/graphql/fragments/pipeline_stages_connection.fragment.graphql
+++ b/app/assets/javascripts/pipelines/graphql/fragments/pipeline_stages_connection.fragment.graphql
@@ -8,6 +8,19 @@ fragment PipelineStagesConnection on CiConfigStageConnection {
jobs {
nodes {
name
+ script
+ beforeScript
+ afterScript
+ environment
+ allowFailure
+ tags
+ when
+ only {
+ refs
+ }
+ except {
+ refs
+ }
needs {
nodes {
name
diff --git a/app/assets/javascripts/templates/issuable_template_selector.js b/app/assets/javascripts/templates/issuable_template_selector.js
index 22bbd083a5d..bcae79c9679 100644
--- a/app/assets/javascripts/templates/issuable_template_selector.js
+++ b/app/assets/javascripts/templates/issuable_template_selector.js
@@ -9,6 +9,7 @@ export default class IssuableTemplateSelector extends TemplateSelector {
constructor(...args) {
super(...args);
+ this.projectId = this.dropdown.data('projectId');
this.projectPath = this.dropdown.data('projectPath');
this.namespacePath = this.dropdown.data('namespacePath');
this.issuableType = this.$dropdownContainer.data('issuableType');
@@ -81,21 +82,21 @@ export default class IssuableTemplateSelector extends TemplateSelector {
}
requestFile(query) {
+ const callback = (currentTemplate) => {
+ this.currentTemplate = currentTemplate;
+ this.stopLoadingSpinner();
+ this.setInputValueToTemplateContent();
+ };
+
this.startLoadingSpinner();
- Api.issueTemplate(
- this.namespacePath,
- this.projectPath,
- query.name,
+ Api.projectTemplate(
+ this.projectId,
this.issuableType,
- (err, currentTemplate) => {
- this.currentTemplate = currentTemplate;
- this.stopLoadingSpinner();
- if (err) return; // Error handled by global AJAX error handler
- this.setInputValueToTemplateContent();
- },
+ query.name,
+ { source_template_project_id: query.project_id },
+ callback,
);
- return;
}
setInputValueToTemplateContent() {
diff --git a/app/assets/stylesheets/page_bundles/oncall_schedules.scss b/app/assets/stylesheets/page_bundles/oncall_schedules.scss
index c7e90ba3451..2ab3bdcc474 100644
--- a/app/assets/stylesheets/page_bundles/oncall_schedules.scss
+++ b/app/assets/stylesheets/page_bundles/oncall_schedules.scss
@@ -32,13 +32,17 @@
.rotations-modal {
.gl-card {
min-width: 75%;
- width: fit-content;
- @include gl-bg-gray-10;
}
&.gl-modal .modal-md {
max-width: 640px;
}
+
+ // TODO: move to gitlab/ui utilities
+ // https://gitlab.com/gitlab-org/gitlab/-/issues/297502
+ .gl-w-fit-content {
+ width: fit-content;
+ }
}
//// Copied from roadmaps.scss - adapted for on-call schedules