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');
module.exports = { function NewNoteButton({ $rootScope, settings }) {
controllerAs: 'vm', const store = useStore(store => ({
//@ngInject frames: store.frames(),
controller: function($rootScope, store) { }));
this.onNewNoteBtnClick = function() {
const topLevelFrame = store.frames().find(f => !f.id);
const annot = {
target: [],
uri: topLevelFrame.uri,
};
$rootScope.$broadcast(events.BEFORE_ANNOTATION_CREATED, annot); const onNewNoteBtnClick = function() {
const topLevelFrame = store.frames.find(f => !f.id);
const annot = {
target: [],
uri: topLevelFrame.uri,
}; };
}, $rootScope.$broadcast(events.BEFORE_ANNOTATION_CREATED, annot);
bindings: {}, };
template: require('../templates/new-note-btn.html'),
return (
<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;
frames: sinon
.stub()
.returns([
{ id: null, uri: 'www.example.org' },
{ id: '1', uri: 'www.example.org' },
]),
};
before(function() { function createComponent() {
angular return shallow(
.module('app', []) <NewNoteButton
.component('selectionTabs', require('../selection-tabs')) $rootScope={fakeRootScope}
.component('newNoteBtn', require('../new-note-btn')); settings={fakeSettings}
}); store={fakeStore}
/>
).dive(); // dive() needed because this component uses `withServices`
}
beforeEach(function() { beforeEach(function() {
const fakeFeatures = { fakeRootScope = {
flagEnabled: sinon.stub().returns(true), $broadcast: sinon.stub(),
}; };
const fakeSettings = { theme: 'clean' }; fakeSettings = {
branding: {
angular.mock.module('app', { ctaBackgroundColor: '#00f',
store: fakeStore, },
features: fakeFeatures, };
settings: fakeSettings, fakeStore = {
createAnnotation: sinon.stub(),
frames: sinon
.stub()
.returns([
{ id: null, uri: 'www.example.org' },
{ id: '1', uri: 'www.example.org' },
]),
};
NewNoteButton.$imports.$mock({
'../store/use-store': callback => callback(fakeStore),
}); });
});
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'); it('should broadcast BEFORE_ANNOTATION_CREATED event when the new note button is clicked', () => {
elem.ctrl.onNewNoteBtnClick(); 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