diff options
Diffstat (limited to 'afb-client/app')
35 files changed, 278 insertions, 572 deletions
diff --git a/afb-client/app/Backend/RestApis/PostMockApi.js b/afb-client/app/Backend/RestApis/PostMockApi.js deleted file mode 100644 index 022f774..0000000 --- a/afb-client/app/Backend/RestApis/PostMockApi.js +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (C) 2015 "IoT.bzh" - * Author "Fulup Ar Foll" - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * - * References: https://github.com/expressjs/multer - */ - -var fs = require('fs'); -var multer = require('multer'); - -function NewApi(handle, prefix) { - var scope=this; // make sure not to loose object context in async callback - - // defined upload directory and check it's a valid one - var upload = multer({ dest: handle.config.UPLOAD_DIR}); - // WARNING: single('avatar') should match with <upload-image name="avatar"> - handle.app.post(prefix +'/upload-image', upload.single('avatar'), function (req, res) { - - handle.trace (scope, 1, "%s/upload file=%s dest=%s/%s", prefix, req.file.originalname, req.file.destination, req.file.filename); - res.send({"jtype": "TEST_message", "status": "success", "info": "done"}); - }); - - // WARNING: single('music') should match with <upload-audio name="music"> - handle.app.post(prefix +'/upload-music', upload.single('music'), function (req, res) { - - handle.trace (scope, 1, "%s/upload file=%s dest=%s/%s", prefix, req.file.originalname, req.file.destination, req.file.filename); - res.send({"jtype": "TEST_message", "status": "success", "info": "done"}); - }); - - // WARNING: single('appli') should match with <upload-audio name="appli"> - handle.app.post(prefix +'/upload-appli', upload.single('appli'), function (req, res) { - - handle.trace (scope, 1, "%s/upload file=%s dest=%s/%s", prefix, req.file.originalname, req.file.destination, req.file.filename); - res.send({"jtype": "TEST_message", "status": "success", "info": "done"}); - }); - -} - -// Export Class -module.exports = NewApi;
\ No newline at end of file diff --git a/afb-client/app/Backend/RestApis/TokenMockApi.js b/afb-client/app/Backend/RestApis/TokenMockApi.js deleted file mode 100644 index 9e6406e..0000000 --- a/afb-client/app/Backend/RestApis/TokenMockApi.js +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright (C) 2015 "IoT.bzh" - * Author "Fulup Ar Foll" - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -/* ---------------------------------------------------------------------- - * This module simulate Application Framework Binder - * - * /api/afbs/create - * /api/afbs/check?token=123456789 - * /api/afbs/refresh?token=123456789-xxxxx - * /api/afbs/reset?123456789-xxxxx - * - * Note: this MOCK api does not handle any session login. It only returns - * a fake valid or false message depending on call order. - * Its goal is to get a quick way to check you HTML5 client rendering & behaviour. - * - * When you're happy with you HTML5 client OnePageApp check it with afb-daemon - * ----------------------------------------------------------------------*/ - - -function NewApi(handle, prefix) { - var scope=this; // I hate JavaScript - scope.connected=false; - - // Simulate Client Context Session Creation - handle.app.get(prefix +'/create', function (req, res) { - handle.trace (scope, 1, "%s/create body=%s", prefix, req.body.action); - var okResponse= '{ "jtype": "AJB_reply"' + - ', "request": { "prefix": "afbs", "api": "create", "uuid": "e4ef5e66-xxxx", "token": "123456789-xxxxx", "status": "processed" }'+ - ', "response": { "token": "Token was refreshed" }'+ - '}'; - - var fxResponse= '{ "jtype": "AJB_reply" ' + - ', "request": { "prefix": "afbs", "api": "create", "status": "fail", "info": "AFB_SESSION_REFRESH Not Initial Token Chain" }'+ - '}'; - - if (scope.connected) res.status(401).send(fxResponse); - else { - res.send(okResponse); - scope.connected=true; - } - }); - - - // Simulate Client Context Check - handle.app.get(prefix +'/check', function (req, res) { - handle.trace (scope, 1, "%s/check query=%s", prefix, req.query.token); - var okResponse= '{"jtype":"AJB_reply"'+ - ',"request":{"prefix":"afbs","api":"check", "status":"processed"}'+ - ',"response":{"isvalid":true}'+ - '}'; - - var fxResponse= '{"jtype":"AJB_reply",'+ - '"request":{"prefix":"afbs","api":"check","status":"empty","info":"AFB_SESSION_CHECK Not a Valid Active Token"}'+ - '}'; - - if (!scope.connected) res.status(401).send(fxResponse); - else res.send(okResponse); - }); - - // Simulate Client Context Check - handle.app.get(prefix +'/refresh', function (req, res) { - handle.trace (scope, 1, "%s/refresh query=%s", prefix, req.query.token); - var okResponse= '{"jtype":"AJB_reply"'+ - ',"request":{"prefix":"afbs","api":"refresh","uuid": "e4ef5e66-xxxx", "token": "123456789-xxxxx","status":"processed"}'+ - ',"response":{"isvalid":true}'+ - '}'; - - var fxResponse= '{"jtype":"AJB_reply",'+ - '"request":{"prefix":"afbs","api":"refresh","status":"empty","info":"AFB_SESSION_REFRESH Not a Valid Active Token"}'+ - '}'; - - if (!scope.connected) res.status(401).send(fxResponse); - else res.send(okResponse); - }); - - // Simulate Client Context Session Closing - handle.app.get(prefix +'/reset', function (req, res) { - handle.trace (scope, 1, "%s/reset query=%s", prefix, req.query.token); - var okResponse= '{"jtype":"AJB_reply"'+ - ',"request":{"prefix":"afbs","api":"reset","uuid": "e4ef5e66-xxxx","status":"processed"}'+ - ',"response":{"uuid":"b028b883-8b47-4c6d-9c6e-e79b9e2b81b9"}'+ - '}'; - - var fxResponse= '{"jtype":"AJB_reply",'+ - '"request":{"prefix":"afbs","api":"reset","status":"empty","info":"AFB_SESSION_CLOSE Not a Valid Access Token"}'+ - '}'; - - if (!scope.connected) res.status(401).send(fxResponse); - else { - res.send(okResponse); - scope.connected=false; - } - }); - - -} - -// Export Class -module.exports = NewApi;
\ No newline at end of file diff --git a/afb-client/app/Backend/RestApis/_all.js b/afb-client/app/Backend/RestApis/_all.js deleted file mode 100644 index aacf19e..0000000 --- a/afb-client/app/Backend/RestApis/_all.js +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (C) 2015 "IoT.bzh" - * Author "Fulup Ar Foll" - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - */ -PostMockApi = require ('./PostMockApi'); -TokenMockApi = require ('./TokenMockApi'); - -// Include here every application APIs routes modules. -function Initialise (handle) { - - this.sample= new TokenMockApi (handle, config.APIBASE + 'token'); - this.sample= new PostMockApi (handle, config.APIBASE + 'post'); -} - -module.exports = Initialise; - diff --git a/afb-client/app/Backend/server.js b/afb-client/app/Backend/server.js deleted file mode 100644 index 11c5486..0000000 --- a/afb-client/app/Backend/server.js +++ /dev/null @@ -1,58 +0,0 @@ -var config = require('../etc/_Config'); -var trace = require('../etc/_Trace'); -var RestAPI = require('./RestApis/_all'); -var fs = require('fs'); - -var express = require('express'); -var session = require('express-session'); -var bodyParser = require('body-parser'); -var methodOverride = require('method-override'); - -// instanciate express HTTP server -var app = express(); - -// chose dev or prod rootdir -var staticdir = 'dist.dev'; -if (process.env.MODE) staticdir = process.env.MODE === 'prod' ? 'dist.prod' : 'dist.dev'; -else staticdir = config.MODE === 'prod' ? 'dist.prod' : 'dist.dev'; - -var rootdir = __dirname + '/../../' + staticdir; -if (!fs.existsSync(rootdir)) { - console.log("### HOOPS Rootdir not found rootdir=%s\n", rootdir); - process.exit(); -} - -// get all data/stuff of the body (POST) parameters -app.use(bodyParser.json()); // parse application/json -app.use(methodOverride('X-HTTP-Method-Override')); // override with the X-HTTP-Method-Override header in the request. simulate DELETE/PUT - -// This handle should contain enough for application logic -var serverHandle = { - app : app, // Express server - config: config, - trace: config.DBG_LVL > 0 ? trace : function(){/*empty function */} -}; - -// set the static files location /public/img will be /img for users -app.use(express.static(rootdir)); - -// Load Mock APIs -var apirest = new RestAPI(serverHandle); - -app.get(config.URLBASE, function (req, res) { - console.log ("Angular OPA %s", req.originalUrl); - res.sendfile(config.URLBASE +"index.html", {root: rootdir}); -}); - -// rewrite requested URL to include Angular hashPrompt and set session flag for RestAPI -app.get(config.URLBASE + '*', function(req, res) { - // Warning redirect should be under exact "/opa/#!page" or a redirect to home will be done - var redirect=config.URLBASE + '#!' + req.originalUrl.substring(config.URLBASE.length); - res.redirect(redirect); - console.log ("Redirect to: ", redirect); -}); - - -// start app =============================================== -app.listen(config.EXPRESS_PORT, config.EXPRESS_HOST); -console.log('Server Listening http://%s:%d (rootdir=%s)', config.EXPRESS_HOST, config.EXPRESS_PORT, rootdir);
\ No newline at end of file diff --git a/afb-client/app/Frontend/app.js b/afb-client/app/Frontend/app.js index 91a8a72..e11c266 100644 --- a/afb-client/app/Frontend/app.js +++ b/afb-client/app/Frontend/app.js @@ -26,8 +26,7 @@ // Application Components 'AppConfig', 'JQueryEmu', - 'HomeModule', - 'SampleModule', + 'SampleHomeModule', 'UploadFiles', 'LinkButton', 'TokenRefresh', @@ -42,7 +41,7 @@ config.$inject = ['$urlRouterProvider', '$locationProvider']; function config($urlProvider, $locationProvider, AppConfig) { - $urlProvider.otherwise('/home'); + $urlProvider.otherwise('/sample-home'); // https://docs.angularjs.org/error/$location/nobase $locationProvider.html5Mode(true).hashPrefix('!'); diff --git a/afb-client/app/Frontend/etc/AppConfig.js b/afb-client/app/Frontend/etc/AppConfig.js index c8f1abe..382c0a3 100644 --- a/afb-client/app/Frontend/etc/AppConfig.js +++ b/afb-client/app/Frontend/etc/AppConfig.js @@ -10,9 +10,7 @@ var myConfig = { paths: { // Warning paths should end with / image : 'images/', - avatar: 'images/avatars/', - audio : 'images/audio/', - appli : 'images/appli/' + avatar: 'images/avatars/' }, session: { // Those data are updated by session service diff --git a/afb-client/app/Frontend/etc/routes.js b/afb-client/app/Frontend/etc/routes.js index c3c5ba4..f147789 100644 --- a/afb-client/app/Frontend/etc/routes.js +++ b/afb-client/app/Frontend/etc/routes.js @@ -1 +1 @@ -var foundationRoutes = [{"name":"mysample","url":"/sample","controller":"SampleController as ctrl","animationIn":"slideInRight","path":"pages/Sample/Sample.html"},{"name":"myhome","url":"/home","controller":"HomeController as ctrl","animationIn":"slideInRight","path":"pages/Home/Home.html"}]; +var foundationRoutes = [{"name":"PostSample","url":"/sample-post","controller":"SamplePostController as ctrl","animationIn":"slideInRight","path":"pages/SamplePost/SamplePost.html"},{"name":"SampleHome","url":"/sample-home","controller":"SampleHomeController as ctrl","animationIn":"slideInRight","path":"pages/SampleHome/SampleHome.html"}]; diff --git a/afb-client/app/Frontend/images/appli/isnotvalid.png b/afb-client/app/Frontend/images/appli/isnotvalid.png Binary files differdeleted file mode 100644 index 057c215..0000000 --- a/afb-client/app/Frontend/images/appli/isnotvalid.png +++ /dev/null diff --git a/afb-client/app/Frontend/images/appli/istoobig.png b/afb-client/app/Frontend/images/appli/istoobig.png Binary files differdeleted file mode 100644 index 5614073..0000000 --- a/afb-client/app/Frontend/images/appli/istoobig.png +++ /dev/null diff --git a/afb-client/app/Frontend/images/appli/upload-appli.png b/afb-client/app/Frontend/images/appli/upload-appli.png Binary files differdeleted file mode 100644 index a35fd3a..0000000 --- a/afb-client/app/Frontend/images/appli/upload-appli.png +++ /dev/null diff --git a/afb-client/app/Frontend/images/audio/istoobig.png b/afb-client/app/Frontend/images/audio/istoobig.png Binary files differdeleted file mode 100644 index 5614073..0000000 --- a/afb-client/app/Frontend/images/audio/istoobig.png +++ /dev/null diff --git a/afb-client/app/Frontend/images/audio/upload-music.png b/afb-client/app/Frontend/images/audio/upload-music.png Binary files differdeleted file mode 100644 index 2006ef0..0000000 --- a/afb-client/app/Frontend/images/audio/upload-music.png +++ /dev/null diff --git a/afb-client/app/Frontend/images/login/fb-logo.png b/afb-client/app/Frontend/images/login/fb-logo.png Binary files differdeleted file mode 100644 index fcf7847..0000000 --- a/afb-client/app/Frontend/images/login/fb-logo.png +++ /dev/null diff --git a/afb-client/app/Frontend/images/login/gg-logo.png b/afb-client/app/Frontend/images/login/gg-logo.png Binary files differdeleted file mode 100644 index 0c372eb..0000000 --- a/afb-client/app/Frontend/images/login/gg-logo.png +++ /dev/null diff --git a/afb-client/app/Frontend/images/login/gh-logo.png b/afb-client/app/Frontend/images/login/gh-logo.png Binary files differdeleted file mode 100644 index ff856fc..0000000 --- a/afb-client/app/Frontend/images/login/gh-logo.png +++ /dev/null diff --git a/afb-client/app/Frontend/images/login/iot-logo.png b/afb-client/app/Frontend/images/login/iot-logo.png Binary files differdeleted file mode 100644 index ca594d7..0000000 --- a/afb-client/app/Frontend/images/login/iot-logo.png +++ /dev/null diff --git a/afb-client/app/Frontend/images/login/lk-logo.png b/afb-client/app/Frontend/images/login/lk-logo.png Binary files differdeleted file mode 100644 index d9bc51f..0000000 --- a/afb-client/app/Frontend/images/login/lk-logo.png +++ /dev/null diff --git a/afb-client/app/Frontend/images/login/ms-logo.png b/afb-client/app/Frontend/images/login/ms-logo.png Binary files differdeleted file mode 100644 index d4f23eb..0000000 --- a/afb-client/app/Frontend/images/login/ms-logo.png +++ /dev/null diff --git a/afb-client/app/Frontend/images/login/og-logo.png b/afb-client/app/Frontend/images/login/og-logo.png Binary files differdeleted file mode 100644 index a6f6e9a..0000000 --- a/afb-client/app/Frontend/images/login/og-logo.png +++ /dev/null diff --git a/afb-client/app/Frontend/images/login/pp-logo.png b/afb-client/app/Frontend/images/login/pp-logo.png Binary files differdeleted file mode 100644 index dbb8866..0000000 --- a/afb-client/app/Frontend/images/login/pp-logo.png +++ /dev/null diff --git a/afb-client/app/Frontend/images/login/yh-logo.png b/afb-client/app/Frontend/images/login/yh-logo.png Binary files differdeleted file mode 100644 index 6ab90cf..0000000 --- a/afb-client/app/Frontend/images/login/yh-logo.png +++ /dev/null diff --git a/afb-client/app/Frontend/pages/Home/Home.html b/afb-client/app/Frontend/pages/SampleHome/SampleHome.html index 509bd6f..58474b2 100644 --- a/afb-client/app/Frontend/pages/Home/Home.html +++ b/afb-client/app/Frontend/pages/SampleHome/SampleHome.html @@ -1,8 +1,8 @@ <!-- Foundation Annotations generate tmp/route.js --> --- -name: myhome -url: /home -controller: HomeController as ctrl +name: SampleHome +url: /sample-home +controller: SampleHomeController as ctrl animationIn: slideInRight --- @@ -16,7 +16,7 @@ animationIn: slideInRight <div class="button-box box-content "> - <submit-button class="session-button {{ctrl.class.login}}" icon="fi-unlock" label="Login" clicked="ctrl.LoginClient" ></submit-button> + <submit-button class="session-button {{ctrl.class.connect}}" icon="fi-unlock" label="Connect" clicked="ctrl.ConnectClient" ></submit-button> <submit-button class="session-button {{ctrl.class.check}}" icon="fi-checkbox" label="Check" clicked="ctrl.CheckSession" ></submit-button> <submit-button class="session-button {{ctrl.class.refresh}}" icon="fi-arrows-compress" label="Refresh" clicked="ctrl.RefreshSession" ></submit-button> <submit-button class="session-button {{ctrl.class.logout}}" icon="fi-lock" label="Logout" clicked="ctrl.LogoutClient" ></submit-button> @@ -31,5 +31,5 @@ animationIn: slideInRight </div> -<link-button href="sample" icon="fi-home" label="sample"></link-button> +<link-button href="sample-post" icon="fi-home" label="SamplePost"></link-button> diff --git a/afb-client/app/Frontend/pages/Home/HomeModule.js b/afb-client/app/Frontend/pages/SampleHome/SampleHome.js index 1743654..bce1b47 100644 --- a/afb-client/app/Frontend/pages/Home/HomeModule.js +++ b/afb-client/app/Frontend/pages/SampleHome/SampleHome.js @@ -4,9 +4,9 @@ // WARNING: make sure than app/frontend/services/AppConfig.js match your server // list all rependencies within the page + controler if needed -angular.module('HomeModule', ['SubmitButton', 'TokenRefresh','ModalNotification']) +angular.module('SampleHomeModule', ['SamplePostModule', 'SubmitButton', 'TokenRefresh','ModalNotification']) - .controller('HomeController', function (AppCall, Notification) { + .controller('SampleHomeController', function (AppCall, Notification) { var scope = this; // I hate JavaScript scope.uuid ="none"; scope.token ="none"; @@ -23,20 +23,35 @@ angular.module('HomeModule', ['SubmitButton', 'TokenRefresh','ModalNotification' scope.request = jresp.request; scope.response = jresp.response; - if (jresp.request.status !== "success") { - Notification.error ({message: "Invalid API call:" + jresp.request.info , delay: 5000}); - scope.class [jresp.request.reqid]="fail"; - return; - } - - switch (jresp.request.reqid) { - case 'login': - case 'logout': - scope.class={}; + var action=jresp.request.reqid.toUpperCase(); + + switch (action) { + case 'CONNECT': + if (jresp.request.status !== "success") { + Notification.error ({message: action + ": Logout before reconnecting", delay: 5000}); + scope.class [jresp.request.reqid]="fail"; + return; + } + scope.class={}; // reset CSS buttons classes break; - case 'refresh': - case 'check': + case 'LOGOUT': + if (jresp.request.status !== "success") { + Notification.error ({message: action + ": Do connect first", delay: 5000}); + scope.class [jresp.request.reqid]="fail"; + return; + } + scope.class={}; // reset CSS buttons classes + break; + + case 'REFRESH': + case 'CHECK': + if (jresp.request.status !== "success") { + Notification.error ({message: action + ": Need to be Connected to check/refresh session", delay: 5000}); + scope.class [jresp.request.reqid]="fail"; + return; + } + break; default: @@ -58,9 +73,9 @@ angular.module('HomeModule', ['SubmitButton', 'TokenRefresh','ModalNotification' console.log ("FX: "+ JSON.stringify(response)); }; - scope.LoginClient = function() { - console.log ("LoginClient"); - AppCall.get ("auth", "login", {/*query*/}, scope.OnResponse, scope.InvalidApiCall); + scope.ConnectClient = function() { + console.log ("ConnectClient"); + AppCall.get ("auth", "connect", {/*query*/}, scope.OnResponse, scope.InvalidApiCall); }; scope.CheckSession = function() { @@ -80,8 +95,8 @@ angular.module('HomeModule', ['SubmitButton', 'TokenRefresh','ModalNotification' }; scope.Initialised = function () { - scope.class = {login: "success"}; - } + scope.class = {connect: "success"}; + }; }); diff --git a/afb-client/app/Frontend/pages/Home/HomeModule.scss b/afb-client/app/Frontend/pages/SampleHome/SampleHome.scss index 8bf04a1..8bf04a1 100644 --- a/afb-client/app/Frontend/pages/Home/HomeModule.scss +++ b/afb-client/app/Frontend/pages/SampleHome/SampleHome.scss diff --git a/afb-client/app/Frontend/pages/Sample/Sample.html b/afb-client/app/Frontend/pages/SamplePost/SamplePost.html index 03a4558..fa721c7 100644 --- a/afb-client/app/Frontend/pages/Sample/Sample.html +++ b/afb-client/app/Frontend/pages/SamplePost/SamplePost.html @@ -1,8 +1,8 @@ <!-- Foundation Annotations generate tmp/route.js --> --- -name: mysample -url: /sample -controller: SampleController as ctrl +name: PostSample +url: /sample-post +controller: SamplePostController as ctrl animationIn: slideInRight --- @@ -20,15 +20,9 @@ animationIn: slideInRight maxsize = [xxx] maximum size in KB [default max depend on upload-type] accept = [image] acceptable accept for upload --> - <upload-image name="avatar" category="avatar" thumbnail="tux-visitor.png" maxsize="100" + <upload-image category="avatar" thumbnail="tux-visitor.png" maxsize="100" posturl="/api/post/upload-image" callback="ctrl.FileUploaded" accept="image" title="Change your Avatar"> </upload-image> - - <!-- Warning: name=xxx should match with what server expect [used as xform input name --> - <upload-audio name="music" posturl="/api/post/upload-music" callback="ctrl.FileUploaded" title="Upload your Music"></upload-audio> - - <!-- Warning: name=xxx should match with what server expect [used as xform input name --> - <upload-appli name="appli" posturl="/api/post/upload-appli" callback="ctrl.FileUploaded" title="Upload AGL App"></upload-appli> </div> diff --git a/afb-client/app/Frontend/pages/Sample/SampleModule.js b/afb-client/app/Frontend/pages/SamplePost/SamplePost.js index 8ae82ea..e0c06de 100644 --- a/afb-client/app/Frontend/pages/Sample/SampleModule.js +++ b/afb-client/app/Frontend/pages/SamplePost/SamplePost.js @@ -2,9 +2,9 @@ 'use strict'; // list all rependencies within the page + controler if needed -angular.module('SampleModule', ['SubmitButton','UploadFiles']) +angular.module('SamplePostModule', ['SubmitButton','UploadFiles']) - .controller('SampleController', function ($http) { + .controller('SamplePostController', function ($http) { var scope = this; // I hate JavaScript console.log ("sample Init"); @@ -14,5 +14,5 @@ angular.module('SampleModule', ['SubmitButton','UploadFiles']) }; }); -console.log ("SampleControler Loaded"); +console.log ("PostSampleController Loaded"); })();
\ No newline at end of file diff --git a/afb-client/app/Frontend/pages/Sample/SampleModule.scss b/afb-client/app/Frontend/pages/SamplePost/SamplePost.scss index 7654424..7654424 100644 --- a/afb-client/app/Frontend/pages/Sample/SampleModule.scss +++ b/afb-client/app/Frontend/pages/SamplePost/SamplePost.scss diff --git a/afb-client/app/Frontend/widgets/Buttons/SubmitButtons/SubmitButtons.scss b/afb-client/app/Frontend/widgets/ActionButtons/ActionButtons.scss index 2150e4d..6cb8338 100644 --- a/afb-client/app/Frontend/widgets/Buttons/SubmitButtons/SubmitButtons.scss +++ b/afb-client/app/Frontend/widgets/ActionButtons/ActionButtons.scss @@ -19,4 +19,22 @@ @import "app/ibz-mixins"; // place here your submit buttons customization +appli-button { + @include ibz-button(grey,1rem) + img { + height: 3rem; + } + + + .disable>i { + text-decoration:none; // really not needed for the Top Bar, just for general technique + cursor: auto; + color: grey !important; + } +} +.appli-menu-start { + .start-start, .stop-stop { + i {color: grey;} + } +} diff --git a/afb-client/app/Frontend/widgets/ActionButtons/AppliButton.js b/afb-client/app/Frontend/widgets/ActionButtons/AppliButton.js new file mode 100644 index 0000000..269ee81 --- /dev/null +++ b/afb-client/app/Frontend/widgets/ActionButtons/AppliButton.js @@ -0,0 +1,205 @@ +/* + * Copyright (C) 2015 "IoT.bzh" + * Author "Fulup Ar Foll" + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * Bugs: Input with Callback SHOULD BE get 'required' class + */ + +(function () { + 'use strict'; + + var tmplAppli = '<div ng-click="clicked()">' + + '<img ng-src="{{icon}}">' + + '<span>{{label}}</span>' + + '</div>'; + + var tmplModal = + '<b class="close-button" ng-click="close()">×</b>' + + '<img ng-src="{{icon}}">' + + '<span class="modal-text">Application <b>{{label}}</b></span>' + + '<ul class="vertical icon-left primary menu-bar appli-menu-start">' + + '<li class=start-{{runstatus}}><a ng-click=action("start")><i class="fi-check"> Start</i></a></li>' + + '<li class=stop-{{runstatus}}><a ng-click=action("stop")><i class="fi-x"> Stop</i></a></li>' + + '<li><a ng-click=action("info")><i class="fi-info"> Info</i></a></li>' + + '<li class=start-{{runstatus}}><a ng-click=action("uninstall")><i class="fi-x"> Uninstall</i></a></li>' + + '</ul>' + + ''; + + var tmplDetail = + '<b class="close-button" ng-click="close()">×</b>' + + '<img ng-src="{{icon}}">' + + '<span class="modal-text">Application <b>{{label}}</b></span>' + + '<ul class="vertical icon-left appli-menu-info">' + + '<li><i class="fi-paperclip"> Name : {{detail.name}} </i></li>' + + '<li><i class="fi-info"> Description {{detail.description}}</i></li>' + + '<li><i class="fi-torso"> Author : {{detail.author}}</i></li>' + + '</ul>' + + ''; + + angular.module('AppliButton', []) + .directive('appliButton', function (AppConfig, AppCall, ModalFactory, Notification, $timeout, $window, $location, urlquery) { + + function mymethods(scope, elem, attrs) { + scope.runstatus = "stop"; + scope.runmode = urlquery.runmode || "auto"; + scope.clicked = function () { + + var notifyError = function(action, response) { + Notification.error ({message: "Fail /api/afm-main" + action + "=" + scope.label + " RunID="+ scope.appID, delay: 5000}); + elem.addClass ("fail"); + elem.removeClass ("success"); + scope.callback (scope.appID, action, response); + }; + + var notifySuccess = function (action, response) { + elem.removeClass ("fail"); + scope.runID = response.data.response.runid; + scope.callback (scope.appID, action, response); + }; + + var closeModApp = function() { + scope.modApp.deactivate(); + $timeout (function() {scope.modApp.destroy();}, 1000); + }; + + var closeModInfo = function() { + scope.modInfo.deactivate(); + $timeout (function() {scope.modInfo.destroy();}, 1000); + }; + + var actionModal = function(action) { + console.log ("Modal Action=%s", action); + switch (action) { + + case "start": + if (scope.runstatus !== "stop") return; + AppCall.get ("afm-main", "start", {id: scope.appID, mode: scope.runmode}, function(response) { + if (response.status !== 200 || response.data.jtype !== "afb-reply") { + notifyError ("start", response); + return; + } + scope.runstatus="start"; + notifySuccess (action, response); + if(response.data.response.uri) + scope.winapp= $window.open(response.data.response.uri.replace("%h", $location.host())); + }); + break; + + case "stop": + if (scope.runstatus !== "start") return; + + AppCall.get ("afm-main", "terminate", {runid: scope.runID}, function(response) { + if (response.status !== 200 || response.data.jtype !== "afb-reply") { + notifyError ("stop", response); + return; + } + scope.runstatus="stop"; + + // if a remote window app was open let's close it + if (scope.winapp) { + console.log ("Closing Application Window label=%s id=%s", scope.label, scope.appID); + scope.winapp.close(); + scope.winapp=false; + } + notifySuccess (action, response); + }); + break; + + case "info": + AppCall.get ("afm-main", "detail", {id: scope.appID}, function(response) { + if (response.status !== 200 || response.data.jtype !== "afb-reply") { + notifyError ("detail", response); + return; + } + + // reference http://foundation.zurb.com/apps/docs/#!/angular-modules + var config = { + animationIn: 'slideInFromTop', + contentScope: { + close : closeModInfo, + icon : scope.icon, + label : scope.appID, + detail : response.data.response + }, template : tmplDetail + }; + // Popup Modal to render application data + scope.modInfo = new ModalFactory(config); + scope.modInfo.activate (); + + }); + break; + + case "uninstall": + if (scope.runstatus !== "stop") return; + AppCall.get ("afm-main", "uninstall", {id: scope.appID}, function(response) { + if (response.status !== 200 || response.data.jtype !== "afb-reply") { + notifyError ("uninstall", response); + return; + } + + notifySuccess (action, response); + }); + break; + + default: + console.log ("ActionModal unknown action=[%s]", action); + break; + } + + closeModApp(); + }; + + // reference http://foundation.zurb.com/apps/docs/#!/angular-modules + var config = { + animationIn: 'slideInFromTop', + contentScope: { + action : actionModal, + runstatus: scope.runstatus, + close : closeModApp, + icon : scope.icon, + label : scope.label + }, template : tmplModal + }; + // Popup Modal to render application data + scope.modApp = new ModalFactory(config); + scope.modApp.activate (); + }; + + // extract application information from AppID+Store + if (attrs.handle && scope.store [attrs.handle].name) { + scope.icon = AppConfig.paths.icons + attrs.handle; //scope.store [attrs.handle].name.toLowerCase() + '-ico.png'; + scope.label = scope.store [attrs.handle].name; + scope.appID= attrs.handle; + } else { + scope.icon = AppConfig.paths.icons + 'w3c-ico.png'; + scope.label = attrs.handle; + } + + // add label as class + elem.addClass (scope.label.toLowerCase()); + + // note: clicked in imported and when template is clicked + // it will call clicked method passed in param. + } + + return { + restrict: 'E', + template: tmplAppli, + link: mymethods, + scope: {callback: '=', store: '='} + }; + }); +})(); diff --git a/afb-client/app/Frontend/widgets/Buttons/SubmitButtons/SubmitButtons.js b/afb-client/app/Frontend/widgets/ActionButtons/SubmitButton.js index cba2aeb..323cd46 100644 --- a/afb-client/app/Frontend/widgets/Buttons/SubmitButtons/SubmitButtons.js +++ b/afb-client/app/Frontend/widgets/ActionButtons/SubmitButton.js @@ -21,7 +21,7 @@ (function () { 'use strict'; - var tmpl = '<div ng-click="clicked()"> <span>' + + var tmpl = '<div ng-click="clicked()">' + '<i class="{{icon}}"></i>' + '<span>{{label}}</span>' + '</div>'; diff --git a/afb-client/app/Frontend/widgets/FormInput/InputPassword.js b/afb-client/app/Frontend/widgets/FormInput/InputPassword.js deleted file mode 100644 index 157009c..0000000 --- a/afb-client/app/Frontend/widgets/FormInput/InputPassword.js +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (C) 2015 "IoT.bzh" - * Author "Fulup Ar Foll" - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -(function() { -'use strict'; - -var tmpl = '<input-text class="password" tip="{{tip1}}" placeholder="{{place1}}"' + - 'label="{{label1}}" callback="valid1" name="{{name}}-1" value="pass1" required minlen="{{minlen}}" type="password" >' + - '</input-text>' + - '<input-text class="password" tip="tip2" placeholder="{{place2}}"' + - 'label="{{label2}}" callback="valid2" name="{{name}}-2" value="pass2" required minlen="{{minlen}}" type="password" > '+ - '</input-text>'; - -angular.module('InputPassword',[]) - -.directive('inputPassword', function() { - function mymethods(scope, elem, attrs) { - - scope.valid1 = function (name, value) { - console.log ("Clicked InputPassword1 name=%s value=%s", name, value); - scope.firstpwd = value; - }; - - scope.valid2 = function (name, value, done) { - console.log ("Clicked InputPassword2 name=%s value=%s", name, value); - - // if both passwd equal then call form CB - if (scope.firstpwd !== value) { - done({valid: false, status: 'invalid', errmsg: "both password should match"}); - } else { - scope.callback (attrs.name, value); - } - - }; - - // this method can be called from controller to update widget status - scope.done=function (data) { - console.log ("Text-Input Callback ID="+ attrs.name + " data=", data); - for (var i in data) scope[i] = data[i]; - }; - - // Export some attributes within directive scope for template - scope.name = attrs.name; - scope.label1 = attrs.label || 'Password'; - scope.label2 = attrs.label || 'Password Verification'; - scope.place1 = attrs.placeholder1 || 'User Password'; - scope.tip1 = attrs.tip || 'Choose a Password'; - scope.place2 = attrs.placeholder1 || 'Password Verification'; - scope.tip2 = attrs.tip || 'Confirme your Password'; - scope.minlen = attrs.minlen || 10; - - if ("required" in attrs) scope.required = 'required'; - - } - - return { - restrict: 'E', - template: tmpl, - link: mymethods, - scope: { - callback : '=', - } - }; -}); - -console.log ("InputPassword Loaded"); -})(); diff --git a/afb-client/app/Frontend/widgets/FormInput/InputText.js b/afb-client/app/Frontend/widgets/FormInput/InputText.js deleted file mode 100644 index 2653175..0000000 --- a/afb-client/app/Frontend/widgets/FormInput/InputText.js +++ /dev/null @@ -1,179 +0,0 @@ - -/* - * Copyright (C) 2015 "IoT.bzh" - * Author "Fulup Ar Foll" - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details.. - */ - - - -(function() { -'use strict'; - -var tmpl = '<tip-modal tip="tip"></tip-modal>' + - '<label for="{{name}}-intext">{{label}} <i ng-show="required" ng-click="ToBeDefined" ' + - 'class="required {{status}} fi-checkbox" title="Free Value But Mandatory Argument" alt="?"> </i></label>'+ - '<input '+ - ' type="{{type}}" id="{{name}}-intext" placeholder="{{placeholder}}" class="status-{{status}}"'+ - ' ng-model="value" ng-blur="validate()" ng-focus="selected()" '+ - ' ng-model-options="{ updateOn: \'default blur\', debounce: {default: 500, blur: 0} }"' + - '><alert data-ng-show="!valid&&errmsg">{{errmsg}}</alert>'; - -var emailpatern = /^(([^<>()[\]\.,;:\s@\"]+(\.[^<>()[\]\.,;:\s@\"]+)*)|(\".+\"))@(([^<>()[\]\.,;:\s@\"]+\.)+[^<>()[\]\.,;:\s@\"]{2,})$/i; - -angular.module('InputText',['JQueryEmu']) - -.directive('inputText', function(JQemu) { - function mymethods(scope, elem, attrs) { - - // default value at 1st rendering - scope.error = false; - scope.valid = false; - scope.status = 'untouch'; - - scope.input = elem.find ("input"); - scope.required = 0; - - // requirer is use to increment requested counter - if ("required" in attrs) { - scope.required = 1; - elem.addClass ("required"); - } - - // user enter input reset error status - scope.selected = function () { - scope.error=false; - scope.errmsg=false; - scope.status = 'touch'; - }; - - scope.validate = function () { - - // get value from input field bypassing Angular ng-model - console.log ("Clicked InputText name=%s value=%s valid=%s", scope.name, scope.value, scope.valid); - - // form is not untouched anymore - scope.parent.removeClass ("ng-pristine"); - - // if value not null clean up string - if (scope.value) { - scope.error=false; - // remove leading and trailling space - scope.value = scope.value.trim(); - - // remove any space is not allowed - if ('nospace' in attrs) { - scope.value=scope.value.replace(/\s/g, ''); - } - - if ('lowercase' in attrs) { - scope.value = scope.value.toLowerCase(); - } - - // check minimum lenght - if ("minlen" in attrs) { - if (scope.value.length < attrs.minlen) { - scope.status='invalid'; - scope.errmsg=scope.name + ': Mininum Lengh= ' + attrs.minlen + ' Characters'; - scope.error=true; - } - } - - if ('email' in attrs) { - if (!emailpatern.test (scope.value)) { - scope.status='invalid'; - scope.errmsg='invalid email address'; - scope.error=true; - } - } - - } else { - if (scope.required) { - scope.status='invalid'; - scope.errmsg=scope.name + ': Required Attribute'; - scope.error=true; - } - } - - // If local control fail let's refuse input - if (scope.error) { - if (scope.required && scope.valid) { - scope.valid = false; - if (scope.l4acounter.validated > 0) scope.l4acounter.validated --; - } - // use call to update form scope on form completeness - scope.callback (attrs.name, null, scope.done); - } else { - // localcheck is OK backup may nevertheless change status to false - if (scope.required && !scope.valid) scope.l4acounter.validated ++; - scope.status='valid'; - scope.valid=true; - scope.callback (attrs.name, scope.value, scope.done); - } - - }; - - // this method can be called from controller to update widget status - scope.done=function (data) { - console.log ("Text-Input Callback ID="+ attrs.name + " data=", data); - for (var i in data) scope[i] = data[i]; - }; - - // Export some attributes within directive scope for template - scope.label = attrs.label; - scope.name = attrs.name; - scope.placeholder = attrs.placeholder; - scope.type = attrs.type || "text"; - scope.tip = attrs.tip; - - // search for form within parent elemnts - scope.parent = JQemu.parent (elem, "FORM"); - - // email enforce lowercase and nospace - if ("email" in attrs) { - attrs.lowercase=true; - attrs.nospace=true; - attrs.minlen=6; - } - - if (scope.required) { - scope.l4acounter = scope.parent.data ("l4acounter"); - if (!scope.l4acounter) { - scope.l4acounter = {required:1, validated:0}; - console.log("Field "+scope.name+" is required (1st)"); - scope.parent.data ("l4acounter", scope.l4acounter); - } else { - console.log("Field "+scope.name+" is required"); - scope.l4acounter.required ++; - } - } - - // refresh validation each time controler update value - scope.$watch ('value', function(){ - if(scope.value) scope.validate(); } - ); - - } - - return { - restrict: 'E', - template: tmpl, - link: mymethods, - scope: { - callback : '=', - value: '=' - } - }; -}); - -console.log ("InputText Loaded"); -})(); diff --git a/afb-client/app/Frontend/widgets/FormInput/UploadFiles.js b/afb-client/app/Frontend/widgets/FormInput/UploadFiles.js index a23809f..90110c9 100644 --- a/afb-client/app/Frontend/widgets/FormInput/UploadFiles.js +++ b/afb-client/app/Frontend/widgets/FormInput/UploadFiles.js @@ -157,7 +157,7 @@ angular.module('UploadFiles',['AppConfig', 'ModalNotification', 'RangeSlider']) }; // Initiallize default values from attributes values - scope.name= attrs.name || 'avatar'; + scope.name= attrs.name || 'file'; scope.category= attrs.category || 'image'; scope.mimetype= (attrs.accept || 'image') + '/*'; scope.maxsize= attrs.maxsize || 100; // default max size 100KB diff --git a/afb-client/app/Frontend/widgets/Notifications/TokenRefreshSvc.js b/afb-client/app/Frontend/widgets/Notifications/TokenRefreshSvc.js index 3e5e8d6..4dee196 100644 --- a/afb-client/app/Frontend/widgets/Notifications/TokenRefreshSvc.js +++ b/afb-client/app/Frontend/widgets/Notifications/TokenRefreshSvc.js @@ -68,7 +68,7 @@ angular.module('TokenRefresh', ['AppConfig', 'ModalNotification']) scope.onsuccess = function(jresp, errcode) { if (errcode !== 200 || jresp.request.status !== "success") { - Notification.warning ({message: jresp.request.info, delay: 5000}); + Notification.warning ({message: "auto-connect :" + jresp.request.info, delay: 10000}); scope.offline(); return false; } @@ -111,7 +111,7 @@ angular.module('TokenRefresh', ['AppConfig', 'ModalNotification']) // Initial connection scope.loggin = function() { - AppCall.get (scope.plugin, "login", {token: AppConfig.session.initial}, function(jresp, errcode) { + AppCall.get (scope.plugin, "connect", {token: AppConfig.session.initial}, function(jresp, errcode) { if (!scope.onsuccess (jresp, errcode)) return; diff --git a/afb-client/app/etc/AppDefaults.js b/afb-client/app/etc/AppDefaults.js index b0eb1a8..8ed0a11 100644 --- a/afb-client/app/etc/AppDefaults.js +++ b/afb-client/app/etc/AppDefaults.js @@ -25,18 +25,7 @@ config = { FRONTEND: "Frontend", // HTML5 frontend [no leading ./] BACKEND : "Backend", // NodeJS Rest API [no leading ./] URLBASE : '/opa/', // HTML basedir when running in production [should end with a /] - APIBASE : '/api/', // Api url base dir [should end with a /] - DEBUG : 4001, // Node Debug Port - DBG_LVL : 5, // Debug Trace Level 0=no trace. - - UPLOAD_DIR: '/tmp/uploads', // directory destination for uploaded files [/api/post/upload] - - // EXPRESS WEB server config [note: URLBASE generate rewriting rules] - EXPRESS_HOST : 'localhost', // HTTP will only listen on related Internet interface - EXPRESS_PORT : 4000, // HTTP port - EXPRESS_LOGDIR : __dirname + '/../../log', // httpd log file - EXPRESS_SECRET : Math.random().toString(36).slice(2), // [default cookie session] - EXPRESS_SESSION : SESSION_TIMEOUT + APIBASE : '/api/' // Api url base dir [should end with a /] }; module.exports = config; |