Unverified Commit f08e7eae authored by Kyle Keating's avatar Kyle Keating Committed by GitHub

Merge pull request #1256 from hypothesis/react-new-note-btn-conversion

Convert new-note-btn to preact
parents b0dfce31 f8a0eeb0
'use strict'; 'use strict';
const { createElement } = require('preact');
const propTypes = require('prop-types');
const events = require('../events'); const events = require('../events');
const useStore = require('../store/use-store');
const { applyTheme } = require('../util/theme');
const { withServices } = require('../util/service-context');
function NewNoteButton({ $rootScope, settings }) {
const store = useStore(store => ({
frames: store.frames(),
}));
module.exports = { const onNewNoteBtnClick = function() {
controllerAs: 'vm', const topLevelFrame = store.frames.find(f => !f.id);
//@ngInject
controller: function($rootScope, store) {
this.onNewNoteBtnClick = function() {
const topLevelFrame = store.frames().find(f => !f.id);
const annot = { const annot = {
target: [], target: [],
uri: topLevelFrame.uri, uri: topLevelFrame.uri,
}; };
$rootScope.$broadcast(events.BEFORE_ANNOTATION_CREATED, annot); $rootScope.$broadcast(events.BEFORE_ANNOTATION_CREATED, annot);
}; };
},
bindings: {}, return (
template: require('../templates/new-note-btn.html'), <button
style={applyTheme(['ctaBackgroundColor'], settings)}
className="new-note__create"
onClick={onNewNoteBtnClick}
>
+ New note
</button>
);
}
NewNoteButton.propTypes = {
// Injected services.
$rootScope: propTypes.object.isRequired,
settings: propTypes.object.isRequired,
}; };
NewNoteButton.injectedProps = ['$rootScope', 'settings'];
module.exports = withServices(NewNoteButton);
'use strict'; 'use strict';
const angular = require('angular'); const { shallow } = require('enzyme');
const { createElement } = require('preact');
const events = require('../../events'); const events = require('../../events');
const util = require('../../directive/test/util'); const NewNoteButton = require('../new-note-btn');
describe('newNoteBtn', function() { describe('NewNoteButton', function() {
let $rootScope; let fakeStore;
const sandbox = sinon.sandbox.create(); let fakeSettings;
const fakeStore = { let fakeRootScope;
function createComponent() {
return shallow(
<NewNoteButton
$rootScope={fakeRootScope}
settings={fakeSettings}
store={fakeStore}
/>
).dive(); // dive() needed because this component uses `withServices`
}
beforeEach(function() {
fakeRootScope = {
$broadcast: sinon.stub(),
};
fakeSettings = {
branding: {
ctaBackgroundColor: '#00f',
},
};
fakeStore = {
createAnnotation: sinon.stub(),
frames: sinon frames: sinon
.stub() .stub()
.returns([ .returns([
...@@ -16,49 +39,39 @@ describe('newNoteBtn', function() { ...@@ -16,49 +39,39 @@ describe('newNoteBtn', function() {
{ id: '1', uri: 'www.example.org' }, { id: '1', uri: 'www.example.org' },
]), ]),
}; };
NewNoteButton.$imports.$mock({
before(function() { '../store/use-store': callback => callback(fakeStore),
angular
.module('app', [])
.component('selectionTabs', require('../selection-tabs'))
.component('newNoteBtn', require('../new-note-btn'));
}); });
beforeEach(function() {
const fakeFeatures = {
flagEnabled: sinon.stub().returns(true),
};
const fakeSettings = { theme: 'clean' };
angular.mock.module('app', {
store: fakeStore,
features: fakeFeatures,
settings: fakeSettings,
}); });
angular.mock.inject(function(_$componentController_, _$rootScope_) { afterEach(() => {
$rootScope = _$rootScope_; NewNoteButton.$imports.$restore();
});
}); });
afterEach(function() { it('creates the component', () => {
sandbox.restore(); const wrapper = createComponent();
assert.include(wrapper.text(), 'New note');
}); });
it('should broadcast BEFORE_ANNOTATION_CREATED event when the new note button is clicked', function() { it("has a backgroundColor equal to the setting's ctaBackgroundColor color", () => {
const annot = { const wrapper = createComponent();
target: [], assert.equal(
uri: 'www.example.org', wrapper.prop('style').backgroundColor,
}; fakeSettings.branding.ctaBackgroundColor
const elem = util.createDirective(document, 'newNoteBtn', { );
store: fakeStore,
}); });
sandbox.spy($rootScope, '$broadcast');
elem.ctrl.onNewNoteBtnClick(); it('should broadcast BEFORE_ANNOTATION_CREATED event when the new note button is clicked', () => {
const wrapper = createComponent();
wrapper.find('button').simulate('click');
const topLevelFrame = fakeStore.frames().find(f => !f.id);
assert.calledWith( assert.calledWith(
$rootScope.$broadcast, fakeRootScope.$broadcast,
events.BEFORE_ANNOTATION_CREATED, events.BEFORE_ANNOTATION_CREATED,
annot {
target: [],
uri: topLevelFrame.uri,
}
); );
}); });
}); });
...@@ -180,11 +180,14 @@ function startAngularApp(config) { ...@@ -180,11 +180,14 @@ function startAngularApp(config) {
'moderationBanner', 'moderationBanner',
wrapReactComponent(require('./components/moderation-banner')) wrapReactComponent(require('./components/moderation-banner'))
) )
.component('newNoteBtn', require('./components/new-note-btn'))
.component( .component(
'searchStatusBar', 'searchStatusBar',
wrapReactComponent(require('./components/search-status-bar')) wrapReactComponent(require('./components/search-status-bar'))
) )
.component(
'newNoteBtn',
wrapReactComponent(require('./components/new-note-btn'))
)
.component('selectionTabs', require('./components/selection-tabs')) .component('selectionTabs', require('./components/selection-tabs'))
.component('sidebarContent', require('./components/sidebar-content')) .component('sidebarContent', require('./components/sidebar-content'))
.component( .component(
......
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