Commit a8d33267 authored by Jay Swain's avatar Jay Swain

Whats new - create vue component and render to dom

Drawer component to eventually render "Whats New" content.

This is one of many commits/MR's that will eventually be the entire
feature. The drawer is hidden behind the :whats_new_drawer feature flag.

part of:
https://gitlab.com/groups/gitlab-org/-/epics/3556
https://gitlab.com/gitlab-org/growth/engineering/-/issues/5387
https://gitlab.com/gitlab-org/growth/engineering/-/issues/5388
parent 035c81a1
import $ from 'jquery'; import $ from 'jquery';
import ContextualSidebar from './contextual_sidebar'; import ContextualSidebar from './contextual_sidebar';
import initFlyOutNav from './fly_out_nav'; import initFlyOutNav from './fly_out_nav';
import initWhatsNew from '~/whats_new';
function hideEndFade($scrollingTabs) { function hideEndFade($scrollingTabs) {
$scrollingTabs.each(function scrollTabsLoop() { $scrollingTabs.each(function scrollTabsLoop() {
...@@ -20,6 +21,7 @@ export default function initLayoutNav() { ...@@ -20,6 +21,7 @@ export default function initLayoutNav() {
contextualSidebar.bindEvents(); contextualSidebar.bindEvents();
initFlyOutNav(); initFlyOutNav();
initWhatsNew();
// We need to init it on DomContentLoaded as others could also call it // We need to init it on DomContentLoaded as others could also call it
$(document).on('init.scrolling-tabs', () => { $(document).on('init.scrolling-tabs', () => {
......
<script>
import { mapState, mapActions } from 'vuex';
import { GlDrawer } from '@gitlab/ui';
export default {
components: {
GlDrawer,
},
computed: {
...mapState(['open']),
},
methods: {
...mapActions(['closeDrawer', 'openDrawer']),
},
};
</script>
<template>
<div>
<gl-drawer class="mt-6" :open="open" @close="closeDrawer">
<template #header>
<h4>{{ __("What's new at GitLab") }}</h4>
</template>
<template>
<div></div>
</template>
</gl-drawer>
</div>
</template>
<script>
import { mapActions } from 'vuex';
import { GlLink } from '@gitlab/ui';
export default {
components: {
GlLink,
},
methods: {
...mapActions(['openDrawer']),
},
};
</script>
<template>
<li>
<gl-link @click="openDrawer">{{ __("See what's new at GitLab") }}</gl-link>
</li>
</template>
import Vue from 'vue';
import App from './components/app.vue';
import Trigger from './components/trigger.vue';
import store from './store';
export default () => {
// eslint-disable-next-line no-new
new Vue({
el: document.getElementById('whats-new-app'),
store,
components: {
App,
},
render(createElement) {
return createElement('app');
},
});
// eslint-disable-next-line no-new
new Vue({
el: document.getElementById('whats-new-trigger'),
store,
components: {
Trigger,
},
render(createElement) {
return createElement('trigger');
},
});
};
export default {
closeDrawer({ commit }) {
commit('closeDrawer');
},
openDrawer({ commit }) {
commit('openDrawer');
},
};
import Vue from 'vue';
import Vuex from 'vuex';
import actions from './actions';
import mutations from './mutations';
import state from './state';
Vue.use(Vuex);
export default new Vuex.Store({
actions,
mutations,
state,
});
export default {
closeDrawer(state) {
state.open = false;
},
openDrawer(state) {
state.open = true;
},
};
...@@ -113,10 +113,6 @@ module EE ...@@ -113,10 +113,6 @@ module EE
show show
end end
def show_whats_new_dropdown_item?
::Gitlab.com? && ::Feature.enabled?(:whats_new_dropdown)
end
private private
def appearance def appearance
......
- if show_whats_new_dropdown_item? - if ::Feature.enabled?(:whats_new_dropdown)
%li - if ::Feature.enabled?(:whats_new_drawer)
= link_to _("See what's new at GitLab"), "#{promo_url}/releases/gitlab-com/", target: '_blank', rel: 'noopener noreferrer', data: { track_event: 'click_whats_new', track_property: 'question_menu' } #whats-new-trigger
- content_for :scripts_body do
#whats-new-app
- else
%li
= link_to _("See what's new at GitLab"), "#{promo_url}/releases/gitlab-com/", target: '_blank', rel: 'noopener noreferrer', data: { track_event: 'click_whats_new', track_property: 'question_menu' }
...@@ -214,26 +214,4 @@ RSpec.describe ApplicationHelper do ...@@ -214,26 +214,4 @@ RSpec.describe ApplicationHelper do
it { is_expected.to be(app_setting && is_admin) } it { is_expected.to be(app_setting && is_admin) }
end end
end end
describe '#show_whats_new_dropdown_item?' do
using RSpec::Parameterized::TableSyntax
subject { helper.show_whats_new_dropdown_item? }
where(:feature_flag, :gitlab_com, :result) do
true | true | true
true | false | false
false | true | false
false | false | false
end
with_them do
before do
stub_feature_flags(whats_new_dropdown: feature_flag)
allow(::Gitlab).to receive(:com?).and_return(gitlab_com)
end
it { is_expected.to be(result) }
end
end
end end
...@@ -27340,6 +27340,9 @@ msgstr "" ...@@ -27340,6 +27340,9 @@ msgstr ""
msgid "What describes you best?" msgid "What describes you best?"
msgstr "" msgstr ""
msgid "What's new at GitLab"
msgstr ""
msgid "What’s your experience level?" msgid "What’s your experience level?"
msgstr "" msgstr ""
......
import { createLocalVue, mount } from '@vue/test-utils';
import Vuex from 'vuex';
import { GlDrawer } from '@gitlab/ui';
import App from '~/whats_new/components/app.vue';
const localVue = createLocalVue();
localVue.use(Vuex);
describe('App', () => {
let wrapper;
let store;
let actions;
let state;
beforeEach(() => {
actions = {
closeDrawer: jest.fn(),
};
state = {
open: true,
};
store = new Vuex.Store({
actions,
state,
});
wrapper = mount(App, {
localVue,
store,
});
});
afterEach(() => {
wrapper.destroy();
});
const getDrawer = () => wrapper.find(GlDrawer);
it('contains a drawer', () => {
expect(getDrawer().exists()).toBe(true);
});
it('dispatches closeDrawer when clicking close', () => {
getDrawer().vm.$emit('close');
expect(actions.closeDrawer).toHaveBeenCalled();
});
it.each([true, false])('passes open property', async openState => {
wrapper.vm.$store.state.open = openState;
await wrapper.vm.$nextTick();
expect(getDrawer().props('open')).toBe(openState);
});
});
import { createLocalVue, mount } from '@vue/test-utils';
import Vuex from 'vuex';
import Trigger from '~/whats_new/components/trigger.vue';
const localVue = createLocalVue();
localVue.use(Vuex);
describe('Trigger', () => {
let wrapper;
let store;
let actions;
let state;
beforeEach(() => {
actions = {
openDrawer: jest.fn(),
};
state = {
open: true,
};
store = new Vuex.Store({
actions,
state,
});
wrapper = mount(Trigger, {
localVue,
store,
});
});
afterEach(() => {
wrapper.destroy();
});
it('dispatches openDrawer when clicking close', () => {
wrapper.find('a').trigger('click');
expect(actions.openDrawer).toHaveBeenCalled();
});
});
import testAction from 'helpers/vuex_action_helper';
import actions from '~/whats_new/store/actions';
describe('whats new actions', () => {
describe('openDrawer', () => {
it('should commit openDrawer', () => {
testAction(actions.openDrawer, {}, {}, [{ type: 'openDrawer' }]);
});
});
describe('closeDrawer', () => {
it('should commit closeDrawer', () => {
testAction(actions.closeDrawer, {}, {}, [{ type: 'closeDrawer' }]);
});
});
});
import mutations from '~/whats_new/store/mutations';
import createState from '~/whats_new/store/state';
describe('whats new mutations', () => {
let state;
beforeEach(() => {
state = createState;
});
describe('openDrawer', () => {
it('sets open to true', () => {
mutations.openDrawer(state);
expect(state.open).toBe(true);
});
});
describe('closeDrawer', () => {
it('sets open to false', () => {
mutations.closeDrawer(state);
expect(state.open).toBe(false);
});
});
});
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