Skip to content

Commit

Permalink
Update lock; change to main.js.
Browse files Browse the repository at this point in the history
  • Loading branch information
lloy0076 committed Jul 12, 2020
1 parent 38fb239 commit 7019603
Show file tree
Hide file tree
Showing 7 changed files with 1,851 additions and 418 deletions.
42 changes: 42 additions & 0 deletions karma.conf.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
// karma.conf.js
const webpack = require('webpack');

var webpackConfig = require('./webpack.config.js');

module.exports = function (config) {
config.set({
basePath: '.',
frameworks: ['mocha', 'chai'],
files: [
{ pattern: 'src/index.html', served: true },
'tests/app.spec.js',
],
preprocessors: {
'**/*.spec.js': ['webpack', 'sourcemap'],
},
webpack: webpackConfig,
reporters: ['spec'],
browsers: ['Chrome'],
plugins: [
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify('development')
}
}),
// Launchers
'karma-chrome-launcher',

// Test Libraries
'karma-mocha',
'karma-chai',

// Preprocessors
'karma-webpack',
'karma-sourcemap-loader',

// Reporters
'karma-spec-reporter',
'karma-coverage'
]
})
};
20 changes: 14 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,11 @@
"name": "backbone-bookshelf",
"version": "1.0.0",
"description": "A simple bookshelf written with backbonejs that uses bootstrap for styling",
"main": "app.js",
"main": "main.js",
"scripts": {
"dev": "webpack-dev-server",
"start": "webpack-dev-server",
"test": "echo \"Error: no test specified\" || exit 1",
"dev": "npm run run-dev",
"run-dev": "webpack --mode=development && node dist/app.js",
"run-prod": "webpack --mode=production && node dist/app.js",
"run": "node src/app.js"
"test": "./node_modules/.bin/karma start"
},
"author": "David LLoyd",
"license": "Apache-2.0",
Expand All @@ -30,17 +27,28 @@
},
"devDependencies": {
"bootstrap-loader": "^3.0.4",
"chai": "^4.2.0",
"clean-webpack-plugin": "^3.0.0",
"css-loader": "^3.5.3",
"html-loader": "^1.1.0",
"html-webpack-plugin": "^4.3.0",
"karma": "^5.0.5",
"karma-chai": "^0.1.0",
"karma-chrome-launcher": "^3.1.0",
"karma-coverage": "^2.0.2",
"karma-mocha": "^2.0.1",
"karma-sourcemap-loader": "^0.3.7",
"karma-spec-reporter": "^0.0.32",
"karma-webpack": "^4.0.2",
"mini-css-extract-plugin": "^0.9.0",
"mocha": "^7.1.2",
"no-op": "^1.0.3",
"node-sass": "^4.14.1",
"nunjucks-loader": "^3.0.0",
"nunjucks-webpack-loader": "^1.0.8",
"resolve-url-loader": "^3.1.1",
"sass-loader": "^8.0.2",
"sinon": "^9.0.2",
"style-loader": "^1.2.1",
"url-loader": "^4.1.0",
"webpack": "^4.43.0",
Expand Down
157 changes: 157 additions & 0 deletions src/App.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
const _ = require('lodash');
const moment = require('moment');
const winston = require('winston');

const Swal = require('sweetalert2');

const BookListComponent = require('./BookListComponent');
const AddComponent = require('./AddComponent');
const EditComponent = require('./EditComponent');

/**
* @class Main
*/
class App {
/**
* Construct an Main class.
*/
constructor(backbone = null) {
if (!backbone) {
throw new Error('Cannot start app without a configured backbone instance.');
}

this.backbone = backbone;

this.backbone.logger = winston.createLogger({
level: 'debug',
format: winston.format.combine(
winston.format.timestamp(),
winston.format.splat(),
winston.format.simple(),
// winston.format.prettyPrint(),
),
transports: [new winston.transports.Console()],
});

this.setupBookCollection();
this.setupRoutes();

this.routeObj = new this.Routes();
}

/**
* Setup the routes.
*/
setupRoutes() {
const that = this;

this.Routes = this.backbone.Router.extend({
routes: {
'add': 'add',
'list': 'defaultRoute',
'edit/:id': 'editRoute',
'': 'defaultRoute',
},
initialize() {
that.them.fetch();
},
defaultRoute: function () {
// Scatter the calls over 10 seconds.
const interval = Math.ceil(Math.random() * 10000) + (25 * 1000);
that.i = setInterval(() => that.them.fetch(), interval);

that.backbone.logger.debug('Default route, interval %d', Number.parseFloat(interval / 1000).toFixed(2));

const component = new BookListComponent(that.backbone, that.them).make();

that.renderIntoContainer(component);
},
add() {
const component = new AddComponent(that.backbone, that.them).make();

if (that.i) {
clearInterval(that.i);
}

that.renderIntoContainer(component);
},
editRoute(id) {
if (that.i) {
clearInterval(that.i);
}

that.them.fetch({
success(results) {
const model = results.get(id);

if (!model) {
Swal.fire({
title: 'Error',
text: `Unable to find model ${id}.`,
icon: 'error',
timer: 3000,
});
window.location('/#');
}

that.backbone.logger.debug('Found moodel:', { model });

const component = new EditComponent(that.backbone, model).make();
that.renderIntoContainer(component);
},
error(error) {
that.backbone.logger.error('Error!', { error });
},
});
},
});
}

/**
* Renders the given component into the DOM.
*
* @param component
* @param empty
* @param id
*/
renderIntoContainer(component = null, empty = true, id = '#container') {
if (!component) {
throw new Error(`Attempt to render an invalid component into the container ${id}.`);
}

const container = $(id);

if (container.length < 1) {
throw new Error(`Cannot find container ${id}.`);
}

if (empty) {
container.empty();
}

container.append(component.render().el);
}

/**
* Setup the book collection.
*
* @todo This should be in its own class or service.
*/
setupBookCollection() {
this.Book = this.backbone.Model.extend({});

_.extend(this.Book, this.backbone.Events);

this.backbone.logger.debug(`Starting at ${moment().format()}.`);

this.Books = this.backbone.Collection.extend({
model: this.Book,
url: SERVICE_URL,
comparator: 'title',
});

this.them = new this.Books();
}
}

module.exports = App;
66 changes: 66 additions & 0 deletions src/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/**
* Copyright 2020 David S. Lloyd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import('bootstrap');
import('bootstrap/dist/css/bootstrap.min.css');

require('gasparesganga-jquery-loading-overlay');

const _ = require('lodash');
const Swal = require('sweetalert2');

const backbone = require('backbone');
backbone.emulateHTTP = true;
backbone.$ = $;
backbone._ = _;

$.LoadingOverlay('show');

const App = require('./App');

$(() => {
const app = new App(backbone);
// new app.Routes();
app.backbone.history.start({
pushState: true,
route: '/',
});

$.LoadingOverlay('hide');

/**
* All navigation that is relative should be passed through the navigate
* method, to be processed by the router. If the link has a `data-bypass`
* attribute, bypass the delegation completely.
*/
$(document).on("click", "a[href]:not([data-bypass])", function (evt) {
// Get the absolute anchor href.
const href = { prop: $(this).prop("href"), attr: $(this).attr("href") };
// Get the absolute root.
const root = location.protocol + "//" + location.host + '/';

// Ensure the root is part of the anchor href, meaning it's relative.
if (href.prop.slice(0, root.length) === root) {
// Stop the default event to ensure the link will not cause a page
// refresh.
evt.preventDefault();

// `Backbone.history.navigate` is sufficient for all Routers and will
// trigger the correct events. The Router's internal `navigate` method
// calls this anyways. The fragment is sliced from the root.
app.backbone.history.navigate(href.attr, true);
}
});
});
Loading

0 comments on commit 7019603

Please sign in to comment.