diff --git a/.eslintrc.yml b/.eslintrc.yml index 1e6df6f5a77..fddaf4929fe 100644 --- a/.eslintrc.yml +++ b/.eslintrc.yml @@ -48,3 +48,4 @@ overrides: - '**/spec/**/*' rules: "@gitlab/require-i18n-strings": off + "@gitlab/no-runtime-template-compiler": off diff --git a/app/assets/javascripts/admin/cohorts/components/usage_ping_disabled.vue b/app/assets/javascripts/admin/users/components/usage_ping_disabled.vue similarity index 100% rename from app/assets/javascripts/admin/cohorts/components/usage_ping_disabled.vue rename to app/assets/javascripts/admin/users/components/usage_ping_disabled.vue diff --git a/app/assets/javascripts/admin/users/index.js b/app/assets/javascripts/admin/users/index.js index f35b57c4e1a..00a84259c22 100644 --- a/app/assets/javascripts/admin/users/index.js +++ b/app/assets/javascripts/admin/users/index.js @@ -1,8 +1,9 @@ import Vue from 'vue'; import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils'; +import UsagePingDisabled from './components/usage_ping_disabled.vue'; import AdminUsersApp from './components/app.vue'; -export default function (el = document.querySelector('#js-admin-users-app')) { +export const initAdminUsersApp = (el = document.querySelector('#js-admin-users-app')) => { if (!el) { return false; } @@ -19,4 +20,24 @@ export default function (el = document.querySelector('#js-admin-users-app')) { }, }), }); -} +}; + +export const initCohortsEmptyState = (el = document.querySelector('#js-cohorts-empty-state')) => { + if (!el) { + return false; + } + + const { emptyStateSvgPath, enableUsagePingLink, docsLink } = el.dataset; + + return new Vue({ + el, + provide: { + svgPath: emptyStateSvgPath, + primaryButtonPath: enableUsagePingLink, + docsLink, + }, + render(h) { + return h(UsagePingDisabled); + }, + }); +}; diff --git a/app/assets/javascripts/admin/users/tabs.js b/app/assets/javascripts/admin/users/tabs.js new file mode 100644 index 00000000000..9ada77396c7 --- /dev/null +++ b/app/assets/javascripts/admin/users/tabs.js @@ -0,0 +1,23 @@ +import { historyPushState } from '~/lib/utils/common_utils'; +import { mergeUrlParams } from '~/lib/utils/url_utility'; + +const COHORTS_PANE = 'cohorts'; + +const tabClickHandler = (e) => { + const { hash } = e.currentTarget; + const tab = hash === `#${COHORTS_PANE}` ? COHORTS_PANE : null; + const newUrl = mergeUrlParams({ tab }, window.location.href); + historyPushState(newUrl); +}; + +const initTabs = () => { + const tabLinks = document.querySelectorAll('.js-users-tab-item a'); + + if (tabLinks.length) { + tabLinks.forEach((tabLink) => { + tabLink.addEventListener('click', (e) => tabClickHandler(e)); + }); + } +}; + +export default initTabs; diff --git a/app/assets/javascripts/boards/components/board_sidebar.js b/app/assets/javascripts/boards/components/board_sidebar.js index bf3dc5c608f..32640f83b83 100644 --- a/app/assets/javascripts/boards/components/board_sidebar.js +++ b/app/assets/javascripts/boards/components/board_sidebar.js @@ -1,4 +1,7 @@ -/* eslint-disable no-new */ +// This is a true violation of @gitlab/no-runtime-template-compiler, as it +// relies on app/views/shared/boards/components/_sidebar.html.haml for its +// template. +/* eslint-disable no-new, @gitlab/no-runtime-template-compiler */ import $ from 'jquery'; import Vue from 'vue'; diff --git a/app/assets/javascripts/boards/components/toggle_focus.vue b/app/assets/javascripts/boards/components/toggle_focus.vue new file mode 100644 index 00000000000..59ee47937c9 --- /dev/null +++ b/app/assets/javascripts/boards/components/toggle_focus.vue @@ -0,0 +1,52 @@ + + + diff --git a/app/assets/javascripts/boards/toggle_focus.js b/app/assets/javascripts/boards/toggle_focus.js index 347deb81846..0a230f72dcc 100644 --- a/app/assets/javascripts/boards/toggle_focus.js +++ b/app/assets/javascripts/boards/toggle_focus.js @@ -1,45 +1,17 @@ -import $ from 'jquery'; import Vue from 'vue'; -import { GlIcon } from '@gitlab/ui'; -import { hide } from '~/tooltips'; +import ToggleFocus from './components/toggle_focus.vue'; -export default (ModalStore, boardsStore) => { - const issueBoardsContent = document.querySelector('.content-wrapper > .js-focus-mode-board'); +export default () => { + const issueBoardsContentSelector = '.content-wrapper > .js-focus-mode-board'; return new Vue({ - el: document.getElementById('js-toggle-focus-btn'), - components: { - GlIcon, + el: '#js-toggle-focus-btn', + render(h) { + return h(ToggleFocus, { + props: { + issueBoardsContentSelector, + }, + }); }, - data: { - modal: ModalStore.store, - store: boardsStore.state, - isFullscreen: false, - }, - methods: { - toggleFocusMode() { - const $el = $(this.$refs.toggleFocusModeButton); - hide($el); - - issueBoardsContent.classList.toggle('is-focused'); - - this.isFullscreen = !this.isFullscreen; - }, - }, - template: ` -
- - - -
- `, }); }; diff --git a/app/assets/javascripts/cycle_analytics/cycle_analytics_bundle.js b/app/assets/javascripts/cycle_analytics/cycle_analytics_bundle.js index bd5a6cc40c4..ddec09e3165 100644 --- a/app/assets/javascripts/cycle_analytics/cycle_analytics_bundle.js +++ b/app/assets/javascripts/cycle_analytics/cycle_analytics_bundle.js @@ -1,3 +1,7 @@ +// This is a true violation of @gitlab/no-runtime-template-compiler, as it +// relies on app/views/projects/cycle_analytics/show.html.haml for its +// template. +/* eslint-disable @gitlab/no-runtime-template-compiler */ import $ from 'jquery'; import Vue from 'vue'; import Cookies from 'js-cookie'; diff --git a/app/assets/javascripts/filtered_search/recent_searches_root.js b/app/assets/javascripts/filtered_search/recent_searches_root.js index 6c8e77a7fe5..1182cb34210 100644 --- a/app/assets/javascripts/filtered_search/recent_searches_root.js +++ b/app/assets/javascripts/filtered_search/recent_searches_root.js @@ -28,19 +28,18 @@ class RecentSearchesRoot { const { state } = this.store; this.vm = new Vue({ el: this.wrapperElement, - components: { - RecentSearchesDropdownContent, - }, data() { return state; }, - template: ` - - `, + render(h) { + return h(RecentSearchesDropdownContent, { + props: { + items: this.recentSearches, + isLocalStorageAvailable: this.isLocalStorageAvailable, + allowedKeys: this.allowedKeys, + }, + }); + }, }); } diff --git a/app/assets/javascripts/merge_conflicts/components/diff_file_editor.js b/app/assets/javascripts/merge_conflicts/components/diff_file_editor.js index 064c0f38464..87642c7a698 100644 --- a/app/assets/javascripts/merge_conflicts/components/diff_file_editor.js +++ b/app/assets/javascripts/merge_conflicts/components/diff_file_editor.js @@ -1,4 +1,7 @@ -/* eslint-disable no-param-reassign */ +// This is a true violation of @gitlab/no-runtime-template-compiler, as it relies on +// app/views/projects/merge_requests/conflicts/components/_diff_file_editor.html.haml +// for its template. +/* eslint-disable no-param-reassign, @gitlab/no-runtime-template-compiler */ import Vue from 'vue'; import { debounce } from 'lodash'; diff --git a/app/assets/javascripts/merge_conflicts/components/inline_conflict_lines.js b/app/assets/javascripts/merge_conflicts/components/inline_conflict_lines.js index bc926cb9155..47214e288ae 100644 --- a/app/assets/javascripts/merge_conflicts/components/inline_conflict_lines.js +++ b/app/assets/javascripts/merge_conflicts/components/inline_conflict_lines.js @@ -1,4 +1,7 @@ -/* eslint-disable no-param-reassign */ +// This is a true violation of @gitlab/no-runtime-template-compiler, as it relies on +// app/views/projects/merge_requests/conflicts/components/_inline_conflict_lines.html.haml +// for its template. +/* eslint-disable no-param-reassign, @gitlab/no-runtime-template-compiler */ import Vue from 'vue'; import actionsMixin from '../mixins/line_conflict_actions'; diff --git a/app/assets/javascripts/merge_conflicts/components/parallel_conflict_lines.js b/app/assets/javascripts/merge_conflicts/components/parallel_conflict_lines.js index bb306e74825..1d5946cd78a 100644 --- a/app/assets/javascripts/merge_conflicts/components/parallel_conflict_lines.js +++ b/app/assets/javascripts/merge_conflicts/components/parallel_conflict_lines.js @@ -15,6 +15,9 @@ import utilsMixin from '../mixins/line_conflict_utils'; required: true, }, }, + // This is a true violation of @gitlab/no-runtime-template-compiler, as it + // has a template string. + // eslint-disable-next-line @gitlab/no-runtime-template-compiler template: ` diff --git a/app/assets/javascripts/merge_conflicts/merge_conflicts_bundle.js b/app/assets/javascripts/merge_conflicts/merge_conflicts_bundle.js index 229f6f3e339..2bd907cad40 100644 --- a/app/assets/javascripts/merge_conflicts/merge_conflicts_bundle.js +++ b/app/assets/javascripts/merge_conflicts/merge_conflicts_bundle.js @@ -1,3 +1,7 @@ +// This is a true violation of @gitlab/no-runtime-template-compiler, as it +// relies on app/views/projects/merge_requests/conflicts/show.html.haml for its +// template. +/* eslint-disable @gitlab/no-runtime-template-compiler */ import $ from 'jquery'; import Vue from 'vue'; import FileIcon from '~/vue_shared/components/file_icon.vue'; diff --git a/app/assets/javascripts/monitoring/monitoring_app.js b/app/assets/javascripts/monitoring/monitoring_app.js index 307154c9a84..2f8c3e2a0c4 100644 --- a/app/assets/javascripts/monitoring/monitoring_app.js +++ b/app/assets/javascripts/monitoring/monitoring_app.js @@ -26,7 +26,24 @@ export default (props = {}) => { dashboardProps: { ...dataProps, ...props }, }; }, - template: ``, + render(h) { + return h('RouterView', { + // This is attrs rather than props because: + // 1. RouterView only actually defines one prop: `name`. + // 2. The RouterView [throws away other props][1] given to it, in + // favour of those configured in the route config/params. + // 3. The Vue template compiler itself in general compiles anything + // like into roughly + // h('some-component', { attrs: { foo: bar } }). Then later, Vue + // [extract props from attrs and merges them with props][2], + // matching them up according to the component's definition. + // [1]: https://github.com/vuejs/vue-router/blob/v3.4.9/src/components/view.js#L124 + // [2]: https://github.com/vuejs/vue/blob/v2.6.12/src/core/vdom/helpers/extract-props.js#L12-L50 + attrs: { + dashboardProps: this.dashboardProps, + }, + }); + }, }); } }; diff --git a/app/assets/javascripts/onboarding_issues/index.js b/app/assets/javascripts/onboarding_issues/index.js index b23a10c9254..f5f971f7bb5 100644 --- a/app/assets/javascripts/onboarding_issues/index.js +++ b/app/assets/javascripts/onboarding_issues/index.js @@ -35,16 +35,16 @@ const showPopover = (el, path, footer, options) => { boundary: 'window', html: true, placement: 'top', - template: `