diff --git a/.gitignore b/.gitignore index 09cf4415..4444c4da 100644 --- a/.gitignore +++ b/.gitignore @@ -18,6 +18,8 @@ backend/.settings/ backend/.mongoData/ backend/files +src/assets/img/team +src/assets/img/pageTemplates *.sublime-workspace # IDE - VSCode diff --git a/Dockerfile b/Dockerfile index 11d43f68..871a3186 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,3 +1,18 @@ -FROM nginx:1.15.8-alpine +FROM teracy/angular-cli as builder -COPY dist /usr/share/nginx/html +COPY . ./nieOS + +WORKDIR ./nieOS + +RUN rm -R ./backend/.settings || true + +RUN rm -R ./backend/files || true + +RUN npm install --global --force yarn + +# RUN npm install --save bcrypt-nodejs +RUN yarn --no-lockfile + +ENV PATH="$PATH:node_modules/@angular/cli/bin" + +# RUN ng build --prod --optimization=false diff --git a/README.md b/README.md index 23a25aea..4504bd36 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,10 @@ -## inseri - have a look! -To get a first impression what inseri does, please go here: [https://nie-ine.github.io/inseri/](https://nie-ine.github.io/inseri/) +Our signature presentation for you: [https://nie-ine.github.io/inseri/](https://nie-ine.github.io/inseri/) | Mandated by [swissuniversities](https://www.swissuniversities.ch/) -Mandated by [swissuniversities](https://www.swissuniversities.ch/) +------ -## Presented or mentioned at +#### Presented or mentioned + +[Open Access in Action | Swissuniversities Project Highlights 2020 | Switzerland](https://claireclivaz.hypotheses.org/930) [Virtual research environments and ancient manuscripts 2020/09 | University of Lausanne | Switzerland](https://claireclivaz.hypotheses.org/930) @@ -11,56 +12,24 @@ Mandated by [swissuniversities](https://www.swissuniversities.ch/) [Digitisation of newspapers collections 2020/04 | University of Luxembourg](https://impresso.github.io/eldorado/online-program/) -## Point of entry -[Check our user guide](https://github.com/nie-ine/inseri/tree/devel/Tutorials/Your%20scientific%20publication%20A-Z) - -## What can I do with inseri? -inseri is an online collaborative work and publish environment. - -## What can I publish with inseri? - -- You can create websites with inseri - - Websites consist of collages that display your data. - - This data can be text you entered directly in inseri, but also data from your database -- You can create online presentations with inseri - - Like in powerpoint, you can create online presentations in inseri. Slides are called collages in inseri and can visualise data from your database in d3.js data visualisations. - - Users can comment on each collage, which is helpful for instance in lectures that professors hold in front of 1000 students who might have further questions especially related to one collage. - - You can store each collage in a central way and integrate it in different presentations, thus no more copy and pasting slides with the same content, you can maintain everything in a central way! -- You can publish own frontend components in inseri - - If you wish to write own frontend components, for instance to enter data in your database or to create an individual d3.js data visualisations, you can do this very fast in inseri. Any npm - module can be integrated in inseri without any needed changes of the npm module you would like to integrate. - -## How can I work with inseri? - -- inseri can be used to work collaboratively - - If somebody in your team needs to enter data and another team member needs to review it, you can create a site with 2 collages in inseri, exactly tailored to your team-specific workflow -- Your can upload any of your data to inseri and always access it whereever you are, also over your phone. inseri also provides pdf readers and other apps that enable you to work with your data. -- You can display for example one pdf, one spreadsheet, and one texteditor on one collage and save this constellation. You can then come back to this collage and keep on working on your task, also collaboratively with colleagues. +------ -## Who is inseri for? +#### [User guide](https://github.com/nie-ine/inseri/tree/devel/Tutorials/Your%20scientific%20publication%20A-Z) -- Universities who would like to centrally maintain project and research specific online presentations of data and research output. Since maintaining thousands of different websites is too labor intensive for many IT departments, inseri offers projects to create websites in inseri which can be centrally maintained by the respective insitution. -- Online developers who would like to publish combineable frontend components. If a frontend developer for instance needs a SQL-entry-frontend-component fast, he/she is much faster adding it to inseri than creating a whole new project. He/She is able to maintain everything he/she does in a central, reusable and combineable way. -- Companies who write internal and external business applications can create their frontend components in inseri. This way the components are instantly reusable by other users and clients if desired. -- Universities who would like to create research specific data visualisations in a central way. A researcher or phd student who creates his/her data visualisations in inseri enables future researchers and phd students to reuse the visualisations for their research. -- Researchers and phd students who would like to visualise and publish their data online as part of their research publication. -- University projects who would like to publish their data and enable the user to visualise and create interesting subsets of the published data. For instance, a user can visualise data from one Library which published a RestFul API, visualise on the same collage data from another Library RestFul API, visualise on the same collage data from a University project, and add his/her own notes, thus working on his/her research. +----- +## Start inseri with docker-compose -# Get it up and running - -[![Build Status](https://travis-ci.org/nie-ine/NIE-OS.svg?branch=devel)](https://travis-ci.org/nie-ine/inseri) -![Docker pulls](https://img.shields.io/docker/pulls/nieine/nieos.svg) - -## Get it up and running to use it locally with docker +If you want to use it locally or on your server, but you don't want to contribute own code. If questions appear, don't hesitate to contact jan.stoffregen@uzh.ch. - ``git clone https://github.com/nie-ine/inseri.git`` - ``cd inseri`` - -1. ```mv ./backend/settings_default ./backend/.settings``` -2. ```docker-compose up``` -3. Wait until the mongodb - conatiner has a first terminal output, then restart the nieine/mean container, the last terminal output of the node container should say "connected to database" - -So, in another terminal, type: + - ```mv ./backend/settings_default ./backend/.settings``` + - replace salt in ./backend/.settings/slat.js to own secret string + - ```docker-compose up``` + + +Wait until the mongodb - container has a first terminal output, then restart the nieine/mean container, the last terminal output of the node container should say "connected to database". So, in another terminal, type: ```docker ps``` to find out the < container id > of nieine/mean @@ -73,26 +42,24 @@ Inseri: [http://localhost:4200](http://localhost:4200) MongoDB - Admin - Interface: [http://localhost:8081](http://localhost:8081) ## Get it up and running for development +If you want to contribute own code. If questions appear, don't hesiate to contact jan.stoffregen@uzh.ch. -### Clone inseri +#### Clone inseri - ``git clone https://github.com/nie-ine/inseri.git`` - ``cd inseri`` + - ```mv ./backend/settings_default ./backend/.settings``` + - replace salt in ./backend/.settings/slat.js to own secret string -## 1. Create MongoDB instance: +#### Create MongoDB instance: -### Alternative 1: Create your own MongoDB instance: - - Create a sandbox on Mongodb, choose a free instance. + - Create a sandbox on [the mongoDB cloud](https://account.mongodb.com/account/login), choose a free instance. - In this sandbox, add your IP to the whitelist - Get the server-connect string, similiar to this: ```mongodb+srv://user:dfgsdbdtrgr@cluster567-7kilp.mongodb.net/node-angular``` via klick on Connect, klick on connect your application, klick one nodejs -### Alternative 2: Contact jan.stoffregen@uzh.ch +#### Connect inseri to MongoDB: + - In the folder .settings, change the file mongodbServer.js Your file should look similar to the following: -## 2. Connect inseri to MongoDB: - - Create a folder .settings - - In the folder settings, create the file mongodbServer.js Your file should look similiar to the following: - - -``` + ``` const mongodbServer = 'mongodb+srv://user:dfgsdbdtrgr@cluster567-7kilp.mongodb.net/node-angular'; module.exports = { @@ -100,63 +67,14 @@ module.exports = { }; ``` -- another file in this folder should be mailDetails, where you can put the information for your email - server, it should look like the following: - -``` -const emailAdress = ''; -const pw = ''; -const recipient = ''; -const type = ''; - -module.exports = { - emailAdress: emailAdress, - pw: pw, - recipient: recipient, - type: type -}; -``` - -- another file is nieOsServer.js: - -``` -const nieOSServer = 'http://localhost:4200'; - -module.exports = { - nieOSServer: nieOSServer -}; - -``` - -- another file is salt.js - - -``` -const salt = 'your_secret_that_should_be_very_long'; - - -module.exports = { - salt: salt -}; - -``` - - -## 3. Start Angular and Node.js +#### Install and start Angular and Node.js - ``yarn`` - ``ng s`` -## 4. Start node.js +#### Start node.js ```npm run start:server``` -## Running unit tests - -Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io). - -## Technical Documentation: - -https://nie-ine.github.io/inseri/ - ## Generate documentation npm run compodoc diff --git a/backend/models/page.js b/backend/models/page.js index e303e11d..60f9cc51 100644 --- a/backend/models/page.js +++ b/backend/models/page.js @@ -13,10 +13,11 @@ const pageSchema = mongoose.Schema({ showDataBrowserOnPublish: { type: Boolean }, tiles: { type: Boolean }, chosenWidth: { type: Number }, - hasSubPages: [{ type: mongoose.Schema.Types.ObjectId, ref: 'SubPage' }], + hasSubPages: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Page' }], jsonId: { type: String }, ownQuery: { type: String }, - publishedAsTemplate: { type: Boolean } + publishedAsTemplate: { type: Boolean }, + templatePhotoURL: {type: String} }); module.exports = mongoose.model('Page', pageSchema); diff --git a/backend/models/userGroups.js b/backend/models/userGroups.js index 2f62573b..c504201a 100644 --- a/backend/models/userGroups.js +++ b/backend/models/userGroups.js @@ -1,13 +1,20 @@ const mongoose = require('mongoose'); const userGroup = mongoose.Schema({ - title: { type: String, required: true }, - description: { type: String, required: true }, - users: [{type: String}], - owner: { type: mongoose.Schema.Types.ObjectId, ref: 'User', require: true }, - hasPages: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Page' }], - hasPageSets: [{ type: mongoose.Schema.Types.ObjectId, ref: 'PageSet' }], - hasActions: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Action' }] + title: {type: String, required: true}, + description: {type: String, required: true}, + users: [{type: mongoose.Schema.Types.ObjectId, ref: 'User'}], + adminsUsers: [{type: mongoose.Schema.Types.ObjectId, ref: 'User'}], + //owner: { type: mongoose.Schema.Types.ObjectId, ref: 'User', require: true }, + hasPages: [{type: mongoose.Schema.Types.ObjectId, ref: 'Page'}], + //hasPageSets: [{ type: mongoose.Schema.Types.ObjectId, ref: 'PageSet' }], + //hasActions: [{type: mongoose.Schema.Types.ObjectId, ref: 'Action'}], + hasActions: [{ + actionId: {type: mongoose.Schema.Types.ObjectId, ref: 'Action'}, + //pageSetId: {type: mongoose.Schema.Types.ObjectId, ref: 'PageSet'}, + hasPages: [{type: mongoose.Schema.Types.ObjectId, ref: 'Page'}] + }] + }); module.exports = mongoose.model('userGroup', userGroup); diff --git a/backend/routes/action.js b/backend/routes/action.js index e5406508..1b136343 100644 --- a/backend/routes/action.js +++ b/backend/routes/action.js @@ -42,6 +42,33 @@ router.get('', checkAuth, (req, res, next) => { }) }); +router.get('/allActionsAndItsPages/:userId', (req, res, next)=>{ + Action.find({creator: req.params.userId}).populate('hasPage') + .populate({ + path: 'hasPageSet', + populate: { + path: 'hasPages' + } + }).then(actions => { + let message; + if (actions.length === 0) { + message = 'No actions were found' + } else { + message = 'All actions were found' + } + res.status(200).json({ + message: message, + actions: JSON.parse(JSON.stringify(actions)) + }); + }) + .catch(error => { + res.status(500).json({ + message: 'Fetching all actions failed', + error: error + }) + }) +}); + router.get('/:id', checkAuth2, (req, res, next) => { // Authorisation (only if user is also the creator of the action) if (req.loggedIn === true) { @@ -106,10 +133,9 @@ if(arrayOfItems.length ==0){ } for (let i = 0; i < arrayOfItems.length; i++) { - console.log(arrayOfItems[i]._id); - console.log(itemToSearch._id); + if (arrayOfItems[i]._id.toString() == itemToSearch._id.toString()) { - console.log(i); + return i; } } @@ -121,18 +147,18 @@ function addFiles(req, res,oldHostUrl, newHostUrl) { let filesJsonExported = JSON.parse(JSON.parse(JSON.stringify(req.body.filesJson.split(oldHostUrl).join(newHostUrl)))); let projectFiles = req.body.projectFiles; - console.log('req.body.projectFiles'); + //console.log('req.body.projectFiles'); //console.log(req.body.projectFiles); let newFiles = filesJsonExported.slice(); - console.log(newFiles); + ///console.log(newFiles); let filesIndices = []; if (projectFiles.length != 0 || filesJsonExported) { filesJsonExported.forEach(file => { filesIndices.push(file._id); }); Files.find({_id: {$in: filesIndices}}).then(foundFiles => { - console.log("foundFiles " + foundFiles); + //console.log("foundFiles " + foundFiles); foundFiles.forEach(item => { let index = searchItemInArray(item, newFiles); if (index != -1) { @@ -141,12 +167,12 @@ function addFiles(req, res,oldHostUrl, newHostUrl) { }); if (newFiles.length != 0) { Files.insertMany(newFiles, {ordered: false}).then(filesInserted => { - console.log("files inserted"); - console.log(filesInserted); + // console.log("files inserted"); + // console.log(filesInserted); let counter = projectFiles.length; projectFiles.forEach(file => { let path = 'backend/files/' + file.fileName; - console.log(path); + //console.log(path); //console.log(file.fileContent); //const data = new Uint8Array(Buffer.from(file.fileContent)); var buf = new Buffer(file.fileContent, 'binary'); //base64 @@ -158,7 +184,7 @@ function addFiles(req, res,oldHostUrl, newHostUrl) { error: err }); } - console.log(file.fileName + "has been added to the server"); + // console.log(file.fileName + "has been added to the server"); counter--; }); }); @@ -186,22 +212,15 @@ function addFiles(req, res,oldHostUrl, newHostUrl) { } function addFolders(req, res,oldHostUrl,newHostUrl) { - console.log("add Folders started"); if(req.body.foldersJson) { - - let foldersJsonExported = JSON.parse(JSON.parse(JSON.stringify(req.body.foldersJson))); let newFolders = foldersJsonExported.slice(); - console.log("newFolders"); - console.log(newFolders); let folderIndices = []; if (foldersJsonExported) { foldersJsonExported.forEach(folder => { folderIndices.push(folder._id); }); Folder.find({_id: {$in: folderIndices}}).then(foundFolders => { - console.log("foundFolders"); - console.log(foundFolders); foundFolders.forEach(item => { let index = searchItemInArray(item, newFolders); if (index != -1) { @@ -209,11 +228,7 @@ function addFolders(req, res,oldHostUrl,newHostUrl) { } }); if (newFolders && newFolders.length > 0) { - console.log("newFolders"); - console.log(newFolders); Folder.insertMany(newFolders, {ordered: false}).then(foldersResults => { - console.log("folders inserted"); - console.log(foldersResults); addFiles(req, res, oldHostUrl, newHostUrl); }).catch(foundFoldersError => { res.status(500).json({ @@ -226,7 +241,6 @@ function addFolders(req, res,oldHostUrl,newHostUrl) { } }).catch(foldersError => { - // tempError=true; res.status(500).json({ message: 'Something happened while Searching for the Folders', error: foldersError @@ -235,19 +249,16 @@ function addFolders(req, res,oldHostUrl,newHostUrl) { } } else{ - console.log( "The project has no Folders"); addFiles(req, res, oldHostUrl, newHostUrl); } } function addMyOwnJsons(req, res, oldHostUrl, newHostUrl) { - console.log("start addMyOwnJson"); if(req.body.jsonQueries) { let myOwnJsonExported = JSON.parse(JSON.parse(JSON.stringify(req.body.jsonQueries.split(oldHostUrl).join(newHostUrl)))); - console.log(myOwnJsonExported); let newMyOwnJsons = myOwnJsonExported.slice(); let myOwnJsonIndices = []; if (myOwnJsonExported) { @@ -260,14 +271,11 @@ if(req.body.jsonQueries) { let index = searchItemInArray(item, newMyOwnJsons); if (index != -1) { newMyOwnJsons.splice(index, 1); - console.log(newMyOwnJsons); } }); if (newMyOwnJsons && newMyOwnJsons.length > 0) { - console.log("start inserting myOwnJsons"); - console.log(newMyOwnJsons); + MyOwnJSON.insertMany(newMyOwnJsons, {ordered: false}).then(jsonsInserted => { - console.log("my Json inserted successfully "); addFolders(req, res, oldHostUrl, newHostUrl); }).catch(jsonsInserted => { @@ -277,7 +285,6 @@ if(req.body.jsonQueries) { }); }); } else { - console.log("else in addMyOwnJson"); addFolders(req, res, oldHostUrl, newHostUrl); } }).catch(jsonsSearchError => { @@ -288,13 +295,11 @@ if(req.body.jsonQueries) { }); } else{ - console.log( "The project has no Jsons"); addFolders(req, res, oldHostUrl, newHostUrl); } } function addQueries( req, res, oldHostUrl,newHostUrl) { - console.log("start adding the queries"); if(req.body.queries){ let queriesExported = JSON.parse(JSON.parse(JSON.stringify(req.body.queries.split(oldHostUrl).join(newHostUrl)))); let queriesIndices=[]; @@ -312,10 +317,7 @@ function addQueries( req, res, oldHostUrl,newHostUrl) { } }); if(newQueries && newQueries.length>0){ - console.log("newQueries is not empty, insert them "); - console.log(newQueries); Query.insertMany(newQueries, {ordered: false}).then(queriesInserted => { - console.log(queriesInserted); addMyOwnJsons(req, res, oldHostUrl,newHostUrl); }).catch(queriesInsertedError => { res.status(500).json({ @@ -336,7 +338,6 @@ function addQueries( req, res, oldHostUrl,newHostUrl) { }); } else{ - console.log( "The project has no queries"); addMyOwnJsons(req, res, oldHostUrl,newHostUrl); } @@ -345,7 +346,6 @@ function addQueries( req, res, oldHostUrl,newHostUrl) { function addPages( req, res, oldHostUrl, newHostUrl) { let pagesExported = JSON.parse(JSON.parse(JSON.stringify(req.body.pages.split(oldHostUrl).join(newHostUrl)))); Page.insertMany(pagesExported).then(pagesInserted => { - //console.log(pagesInserted); addQueries(req, res, oldHostUrl, newHostUrl); return res.status(201).json({ message: 'Project created successfully', @@ -359,9 +359,8 @@ function addPages( req, res, oldHostUrl, newHostUrl) { } function addComments(req, res, oldHostUrl, newHostUrl) { - console.log("I am here in add comments"); + if(req.body.comments){ - //console.log(req.body.comments); let commentsExported= JSON.parse(JSON.parse(JSON.stringify(req.body.comments.split(oldHostUrl).join(newHostUrl)))); let newComments = commentsExported.slice(); let commentsIndices=[]; @@ -395,17 +394,16 @@ function addComments(req, res, oldHostUrl, newHostUrl) { } } else{ - console.log("No Comments were found, start adding the pages"); addPages( req, res, oldHostUrl, newHostUrl); } } router.post('/createProject/', checkAuth, (req, res, next) => { - //console.log(req.body); + let oldHostUrl = req.body.oldHostUrl; let newHostUrl = req.protocol + "://" + req.get("host"); - console.log(req.body.action); + let actionExported = new Action(JSON.parse(JSON.parse(JSON.stringify(req.body.action.split(oldHostUrl).join(newHostUrl))))); let pageSetExported = new PageSet(JSON.parse(JSON.parse(JSON.stringify(req.body.pageSet.split(oldHostUrl).join(newHostUrl))))); actionExported.save() @@ -435,7 +433,7 @@ router.post('/createProject/', checkAuth, (req, res, next) => { }); router.post('/reloadProject/', checkAuth, (req, res, next) => { - console.log(req.body.pageSetId); + let pageSet_id = req.body.pageSetId; const newAction = new Action({ title: '', @@ -446,9 +444,9 @@ router.post('/reloadProject/', checkAuth, (req, res, next) => { deleted: false }); PageSet.find({_id: pageSet_id}).then(pageSet => { - console.log(pageSet); + Page.findOne({_id: pageSet[0].hasPages[0]}).then(mainPage => { - console.log(mainPage); + newAction.title = mainPage.title; newAction.description = mainPage.description; newAction.hasPageSet = pageSet[0]._id; @@ -456,16 +454,16 @@ router.post('/reloadProject/', checkAuth, (req, res, next) => { Page.find({_id: {$in: pageSet[0].hasPages}}).then(allPages => { let queries = []; if (allPages) { - console.log(allPages); + for (let i = 0; i < allPages.length; i++) { allPages[i].queries.forEach(query => { queries.push(query); }); } - console.log(queries); + if (queries.length != 0) { Query.find({_id: {$in: queries}}, {creator: 1}).then(creatorResults => { - console.log(creatorResults); + newAction.creator = creatorResults[0].creator; newAction.save().then(newActionCreated => { res.status(201).json({ @@ -473,14 +471,14 @@ router.post('/reloadProject/', checkAuth, (req, res, next) => { action: newActionCreated }); }).catch(newActionError => { - console.log(newActionError); + res.status(500).json({ message: 'Error while saving new Action', error: newActionError }); }) }).catch(creatorError => { - console.log(creatorError); + res.status(500).json({ message: 'Error retrieving Creator', error: creatorError @@ -489,21 +487,20 @@ router.post('/reloadProject/', checkAuth, (req, res, next) => { } } }).catch(allPagesError => { - console.log(allPagesError); + res.status(500).json({ message: 'Error retrieving All Pages', error: allPagesError }); }); }).catch(mainPageError => { - console.log(mainPageError); res.status(500).json({ message: 'Error retrieving main Page', error: mainPageError }); }); }).catch(pageSetErr => { - console.log(pageSetErr); + res.status(500).json({ message: 'Error retrieving PageSet', error: pageSetErr diff --git a/backend/routes/page-route.js b/backend/routes/page-route.js index 84668d10..c3fe6a07 100644 --- a/backend/routes/page-route.js +++ b/backend/routes/page-route.js @@ -1,3 +1,5 @@ + + const express = require('express'); const Page = require('../models/page'); @@ -8,7 +10,18 @@ const checkAuth2 = require('../middleware/check-auth-without-immediate-response' const router = express.Router(); const PageSet = require('../models/page-set'); const MyOwnJson = require('../models/myOwnJson'); - +const multer = require("multer"); + +const storage = multer.diskStorage({ + destination: (req, file, cb) => { + cb(null, "src/assets/img/pageTemplates"); + }, + filename: (req, file, cb) => { + const name = file.originalname; + console.log("The expected filename form the multer package = " + Date.now() + "-" + name); + cb(null, Date.now() + "-" + name); + } +}); router.get('/published', (req, res, next) => { Page.find( { publishedAsTemplate: true } ) @@ -589,4 +602,27 @@ function updatePage( pageResult, queries, res, req, oldAndNewServerUrls, oldAndN }); } +router.post('/addProfileTemplate/:pageID', multer({storage: storage}).single("file"), (req, res, next) => { + let filePath=''; + console.log(req.file); + console.log(req.body); + if (req.file) { + filePath = req.body.host + "/assets/img/pageTemplates/" + req.file.filename; + } + Page.findOneAndUpdate({_id: req.params.pageID}, {templatePhotoURL: filePath} ) + .then(updatedPage => { + res.status(201).json({ + message: 'Page updated successfully', + page: updatedPage + }); + }) + .catch(errorUpdatePage => { + res.status(500).json({ + message: 'Updated page failed', + error: errorUpdatePage + }); + }); +}); + + module.exports = router; diff --git a/backend/routes/user.js b/backend/routes/user.js index 82b8f8b1..49bcc7b1 100644 --- a/backend/routes/user.js +++ b/backend/routes/user.js @@ -338,6 +338,21 @@ router.get('/:email/reset-password', (req, res, next) => { }); }); +router.get('/:email/getUserByEmail', (req, res, next) => { + User.findOne({email: req.params.email}) + .then(result => { + res.status(201).json({ + message: 'User Successfully found ', + user: result + }); + }) + .catch(err => { + return res.status(401).json({ + message: 'Did not find user' + }); + }); +}); + router.post('/:email/reset-password-set-new-password', (req, res, next) => { User.findOne({email: req.params.email}) .then(result => { @@ -480,9 +495,6 @@ router.get('/:id/queries', checkAuth, (req, res, next) => { router.post('/signup/:newsLetter', multer({storage: storage}).single("file"), (req, res, next) => { // Tests if email address is invalid const emailPattern = /^\S+[@]\S+[.]\S+$/; - console.log(req.body); - console.log(req.param); - console.log(req); if (!emailPattern.test(req.body.email)) { return res.status(400).json({ message: 'Your email address is invalid!' @@ -505,10 +517,9 @@ router.post('/signup/:newsLetter', multer({storage: storage}).single("file"), (r .then(hashPwd => { let filePath = req.body.usrProfileFilePath; if (req.file) { - console.log("uploaded a file "); - console.log((req.file.filename)); + filePath = req.body.host + "/assets/img/team/" + req.file.filename; - console.log(filePath); + } const user = new User({ email: req.body.email, @@ -520,7 +531,7 @@ router.post('/signup/:newsLetter', multer({storage: storage}).single("file"), (r }); user.save() .then(result => { - console.log(result); + res.status(201).json({ message: 'User was created', result: result @@ -542,7 +553,7 @@ router.post('/signup/:newsLetter', multer({storage: storage}).single("file"), (r router.post('/login', (req, res, next) => { let fetchedUser; - console.log('Login'); + User.findOne({email: req.body.email}) .then(user => { if (!user) { @@ -581,7 +592,7 @@ router.post('/login', (req, res, next) => { }); }) .catch(err => { - console.log(err); + return res.status(401).json({ message: 'Auth failed' }); @@ -590,7 +601,6 @@ router.post('/login', (req, res, next) => { router.post('/updateUsrProfilePic/:email', multer({storage: storage}).single("file"), (req, res, next) => { let filePath = ""; - console.log(" final file Path is " + filePath); User.findOne({email: req.params.email}).then(userFound => { if (req.file) { filePath = req.body.hostname + "/assets/img/team/" + req.file.filename; diff --git a/backend/routes/userGroups.js b/backend/routes/userGroups.js index 3c032c8b..d796544d 100644 --- a/backend/routes/userGroups.js +++ b/backend/routes/userGroups.js @@ -1,16 +1,17 @@ const express = require('express'); const User = require('../models/user'); -const UserGroup=require('../models/userGroups'); +const UserGroup = require('../models/userGroups'); const checkAuth = require('../middleware/check-auth'); const checkAuth2 = require('../middleware/check-auth-without-immediate-response'); //const generatedHash = require('../middleware/hash-generator'); const Page = require('../models/page'); const PageSet = require('../models/page-set'); const router = express.Router(); +const Action = require('../models/action'); -router.post('',checkAuth, (req, res, next) => { +router.post('', checkAuth, (req, res, next) => { // done with the new logic console.log(req.body); - UserGroup.find({title: req.body.title, owner:req.userData.userId}) + UserGroup.find({title: req.body.title, adminsUsers: {$in: req.userData.userId}}) .then((result) => { // Checks if other owner has the same group name if (result.length > 0) { @@ -21,14 +22,13 @@ router.post('',checkAuth, (req, res, next) => { const newGroup = new UserGroup({ title: req.body.title, description: req.body.description, - users:[req.userData.email], - owner:req.userData.userId, - hasPages:[], - hasPageSets:[], + users: [req.userData.userId], + adminsUsers: [req.userData.userId], + hasPages: [], hasActions: [] }); newGroup.save() - .then (resultQuery => { + .then(resultQuery => { res.status(201).json({ message: 'Group was created successfully', query: resultQuery @@ -43,10 +43,11 @@ router.post('',checkAuth, (req, res, next) => { }); }); -router.get('', checkAuth, (req, res, next) => { - UserGroup.find({$or: [ - {owner: req.userData.userId}, - {users: {$in: req.userData.email}} +router.get('', checkAuth, (req, res, next) => { // done with the new logic + UserGroup.find({ + $or: [ + {adminsUsers: {$in: req.userData.userId}}, + {users: {$in: req.userData.userId}} ] }) .then(groups => { @@ -69,7 +70,7 @@ router.get('', checkAuth, (req, res, next) => { }) }); -router.get('/:title/listGroupMembers',checkAuth, (req, res, next) => { +router.get('/:title/listGroupMembers', checkAuth, (req, res, next) => { UserGroup.find({ owner: req.userData.userId, title: req.params.title @@ -99,76 +100,103 @@ router.get('/:title/listGroupMembers',checkAuth, (req, res, next) => { router.post('/addMember', (req, res, next) => { console.log(req.body); + if(req.body.admin){ + UserGroup.update({_id: req.body.groupId}, {$addToSet: {adminsUsers: req.body.memberToAdd}}) + .then(result => { + res.status(201).json({ + message: 'User group updated', + result: result + }); + }) + .catch(error => { + res.status(500).json({ + message: 'Error while updating the group', + error: error + }); + }) + } + else{ + UserGroup.update({_id: req.body.groupId}, {$addToSet: {users: req.body.memberToAdd}}) + .then(result => { + res.status(201).json({ + message: 'User group updated', + result: result + }); + }) + .catch(error => { + res.status(500).json({ + message: 'Error while updating the group', + error: error + }); + }) + } - User.findOne({email: req.body.memberToAdd}) - .then((result) => { - let message; - if (result.length === 0) { - message = 'User not found' - console.log(message); +}); + +router.post('/removeMember', checkAuth, (req, res, next) => { + if(req.body.admin){ + UserGroup.update({_id: req.body.groupId}, {$pull: {adminsUsers: req.body.memberToRemove}}) + .then(result => { + res.status(201).json({ + message: 'User group updated', + result: result + }); + }) + .catch(error => { + res.status(500).json({ + message: 'Error while updating the group', + error: error + }); + }) + } + else{ + UserGroup.update({_id: req.body.groupId}, {$pull: {users: req.body.memberToRemove, adminsUsers: req.body.memberToRemove}}) + .then(result => { + res.status(201).json({ + message: 'User group updated', + result: result + }); + }) + .catch(error => { + res.status(500).json({ + message: 'Error while updating the group', + error: error + }); + }) + } +}); + +router.post('/removeProject', checkAuth, (req, res, next) => { + //console.log(req.userData.userId); + console.log(req.body); + UserGroup.updateOne( + {_id: req.body.groupId}, + {$pull: {hasActions:{actionId: req.body.actionId}}}) + .then((updatedDocument) => { + if (updatedDocument.n === 0) { + res.status(400).json({ + message: 'User cannot be removed from the group.' + }); } else { - message = 'User has been found' - console.log(req.body.memberToAdd); - UserGroup.update({_id: req.body.groupId}, {$addToSet: {users: req.body.memberToAdd}}) - .then(result => { - res.status(201).json({ - message: 'User group updated', - }); - }) - .catch(error => { - res.status(500).json({ - message: 'Error while updating the group', - error: error - }); - }) + return res.status(200).json({ + message: 'User has been removed successfully from the group.', + updatedGroup: updatedDocument + }); } }) .catch(error => { res.status(500).json({ - message: 'Error while retrieving the user', + message: 'Updating group failed.', error: error - }); + }) }); }); -router.post('/removeMember',checkAuth, (req, res, next) => { - UserGroup.find({ - _id: req.body.groupId, - users: {$in: req.body.memberToRemove} - }, - {_id: 1}) - .then(result => { - let message; - if (result.length === 0) { - message = 'User is not one of the group members.'; - } else { - message = 'User has been found.'; - UserGroup.update({_id: req.body.groupId}, {$pull: {users: req.body.memberToRemove}}) - .then(updateResult => { - res.status(201).json({ - message : 'User has been successfully removed from the group.' - }); - }) - .catch(error => { - res.status(500).json({ - message: 'Retrieving member failed', - error: error - }) - }); - } - }).catch(error => { - res.status(500).json({ - message: 'Error while retrieving the user', - error: error - }); - }); -}); -router.post('/:groupToDelete',checkAuth, (req, res, next) => { +router.post('/deleteGroup', checkAuth, (req, res, next) => { UserGroup.deleteOne({ - owner: req.userData.userId, - title: req.params.groupToDelete - }) + _id: req.body.id + }) .then((deletedGroup) => { if (deletedGroup.n === 0) { return res.status(400).json({ @@ -188,102 +216,178 @@ router.post('/:groupToDelete',checkAuth, (req, res, next) => { }); }); -router.post('/removeCurrentUserFromGroup/:groupId',checkAuth, (req, res, next) => { - console.log(req.userData.userId); - UserGroup.updateOne({$and:[ - {owner: {$ne: req.userData.userId}}, - {_id: req.params.groupId} - ]}, - {$pull: {users: req.userData.email}}) - .then((updatedDocument) => { - if (updatedDocument.n === 0) { - res.status(400).json({ - message: 'User cannot be removed from the group.' - }); - } else { - return res.status(200).json({ - message: 'User has been removed successfully from the group.', - updatedGroup: updatedDocument - }); - } + + +router.post('/addPageToProject', (req, res, next) => { + UserGroup.update( + {_id: req.body.groupId , 'hasActions.actionId': req.body.actionId}, + {$addToSet: {'hasActions.$.hasPages' : req.body.pageId}}) + .then(updateResult => { + console.log(updateResult); + res.status(201).json({ + message: 'User group updated', //+ result[0]._id, + result: updateResult + }); }) .catch(error => { res.status(500).json({ - message: 'Updating group failed.', + message: 'Error while updating the group', error: error - }) - }); + }); + }) }); -router.post('/assignNewOwner/:groupId&:email',checkAuth, (req, res, next) => { - console.log(req.userData.userId); - console.log(req.params.groupId||" "|| req.params.email); - User.find({email: req.params.email}) - .then((result) => { - let message; - if (result.length === 0) { - message = 'User not found' - } else { - message = 'User has been found' - console.log(message); - UserGroup.updateOne( - {_id: req.params.groupId}, - {$set: {owner: result[0]._id}, $addToSet: {users: req.params.email}}) - .then(updateResult => { - res.status(201).json({ +// router.post('/removeCurrentUserFromGroup/:groupId', checkAuth, (req, res, next) => { +// console.log(req.userData.userId); +// UserGroup.updateOne({ +// $and: [ +// {owner: {$ne: req.userData.userId}}, +// {_id: req.params.groupId} +// ] +// }, +// {$pull: {users: req.userData.email}}) +// .then((updatedDocument) => { +// if (updatedDocument.n === 0) { +// res.status(400).json({ +// message: 'User cannot be removed from the group.' +// }); +// } else { +// return res.status(200).json({ +// message: 'User has been removed successfully from the group.', +// updatedGroup: updatedDocument +// }); +// } +// }) +// .catch(error => { +// res.status(500).json({ +// message: 'Updating group failed.', +// error: error +// }) +// }); +// }); - message: 'User group updated' //+ result[0]._id, - }); - }) - .catch(error => { - res.status(500).json({ - message: 'Error while updating the group', - error: error - }); - }) - } + + +// router.post('/assignNewOwner/:groupId&:email', checkAuth, (req, res, next) => { +// console.log(req.userData.userId); +// console.log(req.params.groupId || " " || req.params.email); +// User.find({email: req.params.email}) +// .then((result) => { +// let message; +// if (result.length === 0) { +// message = 'User not found' +// +// } else { +// message = 'User has been found' +// console.log(message); +// UserGroup.updateOne( +// {_id: req.params.groupId}, +// {$set: {owner: result[0]._id}, $addToSet: {users: req.params.email}}) +// .then(updateResult => { +// res.status(201).json({ +// +// message: 'User group updated' //+ result[0]._id, +// }); +// }) +// .catch(error => { +// res.status(500).json({ +// message: 'Error while updating the group', +// error: error +// }); +// }) +// } +// }) +// .catch(error => { +// res.status(500).json({ +// message: 'Error while retrieving the user', +// error: error +// }); +// }); +// }); +router.post('/updateUserGroup/:title&:description', checkAuth, (req, res, next) => { + UserGroup.update( + {owner: req.userData.userId, _id: req.body.groupId}, + {$set: {title: req.params.title, description: req.params.description}}) + .then(updateResult => { + res.status(201).json({ + message: 'User group updated', //+ result[0]._id, + result: updateResult + }); }) .catch(error => { res.status(500).json({ - message: 'Error while retrieving the user', + message: 'Error while updating the group', error: error }); - }); + git + }) }); -router.post('/updateUserGroup/:title&:description',checkAuth, (req, res, next) => { - UserGroup.update( - {owner: req.userData.userId,_id: req.body.groupId}, - {$set: {title: req.params.title, description: req.params.description}}) - .then(updateResult => { - res.status(201).json({ - message: 'User group updated', //+ result[0]._id, - result: updateResult - }); - }) - .catch(error => { - res.status(500).json({ - message: 'Error while updating the group', - error: error - }); - }) - }); -router.get('/showUserGroupDetails/:groupId',checkAuth, (req, res, next) => { - console.log(req.params.groupId); -console.log(req.userData.userId); - UserGroup.findOne({$and: [{_id: req.params.groupId}, {owner: req.userData.userId}]} - ) - .then(result => { - if(result.length===0) { - message: 'Group not found, or you are not the owner of the group.' + +function searchInArray(arrayOfObjects, objId) { + for (let i = 0; i < arrayOfObjects.length; i++) { + if (arrayOfObjects[i]._id.toString() === objId.toString()) { + return true; + } + } + return false; +} + +router.get('/showUserGroupDetails/:groupId', checkAuth, (req, res, next) => { ///done editing with the new logic + let userAdmin = false; + UserGroup.findOne({_id: req.params.groupId})///({$and: [{_id: req.params.groupId}, {adminUsers:{$in: [req.userData.userId]}}]}) + .populate('adminsUsers') + .populate('users') + .populate('hasPages') + .populate('hasActions.actionId') + .populate({ + path: 'hasActions.actionId', + populate: { + path: 'hasPageSet', + populate: { + path: 'hasPages' + } } - else { - message = 'Group is found' + }) + .populate('hasActions.hasPages') + .then(result => { + let message = ''; + if (result.length === 0) { + message = 'Group not found, or you are not the owner of the group.'; + } else { + if (searchInArray(result.adminsUsers, req.userData.userId)) { + userAdmin = true; + message = 'Group is found and the user is admin, return all his projects as well.'; + ///Action.find({$or: [{_id: {$in: result.hasActions}}, {creator: req.userData.userId}]}) + Action.find({creator: req.userData.userId}) + .populate('hasActions') + .populate({ + path: 'hasPageSet', + populate: { + path: 'hasPages' + } + }) + .then(actions => { + if (actions.length != 0) { + res.status(200).json({ + message: message, + userGroup: result, + actions: actions, + userAdmin: userAdmin + }); + } + }) + } else { + message = 'Group is found and the user is not admin, return user group projects only'; res.status(200).json({ message: message, - result: result + userGroup: result, + userAdmin: userAdmin }); } + + + } }) .catch(error => { res.status(500).json({ @@ -294,7 +398,7 @@ console.log(req.userData.userId); }); //should we add the logic, if we found some shared pages that belongs to the pageSet to remove them as well as sharing the whole pageSet. router.post('/sharePageSet/:pageSetId&:groupId'/*,checkAuth*/, (req, res, next) => { - PageSet.find({_id:req.params.pageSetId}) + PageSet.find({_id: req.params.pageSetId}) .then((result) => { let message; if (result.length === 0) { @@ -319,15 +423,15 @@ router.post('/sharePageSet/:pageSetId&:groupId'/*,checkAuth*/, (req, res, next) }) } }) - .catch(error => { - res.status(500).json({ - message: 'Error while retrieving the PageSet', - error: error - }); + .catch(error => { + res.status(500).json({ + message: 'Error while retrieving the PageSet', + error: error }); - }); + }); +}); router.post('/sharePage/:pageId&:groupId'/*,checkAuth*/, (req, res, next) => { - Page.find({_id:req.params.pageId}) + Page.find({_id: req.params.pageId}) .then((result) => { let message; if (result.length === 0) { @@ -340,7 +444,7 @@ router.post('/sharePage/:pageId&:groupId'/*,checkAuth*/, (req, res, next) => { {$addToSet: {hasPages: req.params.pageId}}) .then(updateResult => { res.status(201).json({ - message: 'User group updated' ,//+ result[0]._id, + message: 'User group updated',//+ result[0]._id, result: updateResult }); }) @@ -361,7 +465,7 @@ router.post('/sharePage/:pageId&:groupId'/*,checkAuth*/, (req, res, next) => { }); router.get('/showPageSets/:groupId'/*,checkAuth*/, (req, res, next) => { UserGroup.find( - {_id: req.params.groupId}, {_id:0, hasPageSets:1}) + {_id: req.params.groupId}, {_id: 0, hasPageSets: 1}) .then(updateResult => { res.status(201).json({ message: 'PageSets retrieved', @@ -377,7 +481,7 @@ router.get('/showPageSets/:groupId'/*,checkAuth*/, (req, res, next) => { }); router.get('/showPages/:groupId'/*,checkAuth*/, (req, res, next) => { UserGroup.find( - {_id: req.params.groupId}, {_id:0, hasPages:1}) + {_id: req.params.groupId}, {_id: 0, hasPages: 1}) .then(updateResult => { res.status(201).json({ message: 'Pages retrieved', @@ -391,5 +495,44 @@ router.get('/showPages/:groupId'/*,checkAuth*/, (req, res, next) => { }); }) }); + +router.post('/addProjectToUserGroup/:groupId', checkAuth, (req, res, next) => { + UserGroup.update( + {_id: req.params.groupId}, + {$addToSet: {hasActions: {actionId: req.body.actionId, hasPages: req.body.hasPages}}}) + .then(updateResult => { + res.status(201).json({ + message: 'User group updated', //+ result[0]._id, + result: updateResult + }); + }) + .catch(error => { + res.status(500).json({ + message: 'Error while updating the group', + error: error + }); + }) +}); + +router.post('/removePageFromProject/', checkAuth, (req, res, next) => { + UserGroup.update( + {_id: req.body.groupId , 'hasActions.actionId': req.body.actionId}, + {$pull: {'hasActions.$.hasPages' : req.body.pageId}}) + .then(updateResult => { + console.log(updateResult); + res.status(201).json({ + message: 'User group updated', //+ result[0]._id, + result: updateResult + }); + }) + .catch(error => { + res.status(500).json({ + message: 'Error while updating the group', + error: error + }); + }) +}); + + module.exports = router; diff --git a/backend/settings_default/mailDetails.js b/backend/settings_default/mailDetails.js new file mode 100644 index 00000000..c7a15829 --- /dev/null +++ b/backend/settings_default/mailDetails.js @@ -0,0 +1,11 @@ +const emailAdress = ''; +const pw = ''; +const recipient = ''; +const type = ''; + +module.exports = { + emailAdress: emailAdress, + pw: pw, + recipient: recipient, + type: type +}; diff --git a/backend/settings_default/mongodbServer.js b/backend/settings_default/mongodbServer.js new file mode 100644 index 00000000..88160465 --- /dev/null +++ b/backend/settings_default/mongodbServer.js @@ -0,0 +1,7 @@ +// mongodb://mongodb:27017/node-angular + +const mongodbServer = 'mongodb://mongodb:27017/node-angular'; + +module.exports = { + mongodbServer: mongodbServer +}; diff --git a/backend/settings_default/nieOsServer.js b/backend/settings_default/nieOsServer.js new file mode 100644 index 00000000..b04c88c4 --- /dev/null +++ b/backend/settings_default/nieOsServer.js @@ -0,0 +1,5 @@ +const nieOSServer = 'http://localhost:4200'; + +module.exports = { + nieOSServer: nieOSServer +}; diff --git a/backend/settings_default/salt.js b/backend/settings_default/salt.js new file mode 100644 index 00000000..c4dc4a7c --- /dev/null +++ b/backend/settings_default/salt.js @@ -0,0 +1,5 @@ +const salt = 'my_secret_secret'; + +module.exports = { + salt: salt +}; diff --git a/builtAndPublishDockerImages.sh b/builtAndPublishDockerImages.sh index 06593ec6..0cf7de90 100755 --- a/builtAndPublishDockerImages.sh +++ b/builtAndPublishDockerImages.sh @@ -6,8 +6,8 @@ docker login ng build --optimization=false docker build -t nieos . -docker tag nieos:latest nieine/nieos:${DATE} -docker push nieine/nieos:${DATE} +docker tag nieos:latest nieine/nieos:latest +docker push nieine/nieos:latest ng build --optimization=false --configuration=production docker build -t nieos-production-instance . diff --git a/docker-compose.yml b/docker-compose.yml index 4e9a7cd3..652e0839 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -4,7 +4,7 @@ services: nieos_production: # build: . #image: nieine/nieos:2019-07-31 - image: nieine/nieos:19-08-04 + image: nieine/nieos:latest ports: - 4200:80 volumes: @@ -16,7 +16,7 @@ services: node: # image: mean:latest - image: mean:latest + image: nieine/mean:latest ports: - 3000:3000 entrypoint: npm run start:server diff --git a/documentation/css/agency.min.css b/documentation/css/agency.min.css index dc25fb9a..b6816bd5 100644 --- a/documentation/css/agency.min.css +++ b/documentation/css/agency.min.css @@ -256,7 +256,7 @@ header .intro-text .intro-heading { header .intro-text .intro-heading { font-family: Montserrat, "Helvetica Neue", Helvetica, Arial, sans-serif; text-transform: uppercase; - font-weight: 700; + font-weight: 500; font-size: 75px; line-height: 75px; margin-bottom: 50px @@ -279,7 +279,7 @@ section h3.section-subheading { text-transform: none; font-style: italic; font-weight: 400; - margin-bottom: 75px + margin-bottom: 15px } @media (min-width: 768px) { diff --git a/documentation/gulpfile.js b/documentation/gulpfile.js new file mode 100644 index 00000000..55e1b680 --- /dev/null +++ b/documentation/gulpfile.js @@ -0,0 +1,105 @@ +var gulp = require('gulp'); +var less = require('gulp-less'); +var sass = require('gulp-sass'); +var browserSync = require('browser-sync').create(); +var header = require('gulp-header'); +var cleanCSS = require('gulp-clean-css'); +var rename = require("gulp-rename"); +var uglify = require('gulp-uglify'); +var pkg = require('./package.json'); + +// Set the banner content +var banner = ['/*!\n', + ' * Start Bootstrap - <%= pkg.title %> v<%= pkg.version %> (<%= pkg.homepage %>)\n', + ' * Copyright 2013-' + (new Date()).getFullYear(), ' <%= pkg.author %>\n', + ' * Licensed under <%= pkg.license.type %> (<%= pkg.license.url %>)\n', + ' */\n', + '' +].join(''); + +// Compile LESS files from /less into /css +gulp.task('less', function() { + return gulp.src('less/agency.less') + .pipe(less()) + .pipe(header(banner, { pkg: pkg })) + .pipe(gulp.dest('css')) + .pipe(browserSync.reload({ + stream: true + })) +}); + +// Minify compiled CSS +gulp.task('minify-css', ['less'], function() { + return gulp.src('css/agency.css') + .pipe(cleanCSS({ compatibility: 'ie8' })) + .pipe(rename({ suffix: '.min' })) + .pipe(gulp.dest('css')) + .pipe(browserSync.reload({ + stream: true + })) +}); + +// Minify JS +gulp.task('minify-js', function() { + return gulp.src('js/agency.js') + .pipe(uglify()) + .pipe(header(banner, { pkg: pkg })) + .pipe(rename({ suffix: '.min' })) + .pipe(gulp.dest('js')) + .pipe(browserSync.reload({ + stream: true + })) +}); + +// Copy vendor libraries from /node_modules into /vendor +gulp.task('copy', function() { + gulp.src(['node_modules/bootstrap/dist/**/*', '!**/npm.js', '!**/bootstrap-theme.*', '!**/*.map']) + .pipe(gulp.dest('vendor/bootstrap')) + + gulp.src(['node_modules/jquery/dist/jquery.js', 'node_modules/jquery/dist/jquery.min.js']) + .pipe(gulp.dest('vendor/jquery')) + + gulp.src([ + 'node_modules/font-awesome/**', + '!node_modules/font-awesome/**/*.map', + '!node_modules/font-awesome/.npmignore', + '!node_modules/font-awesome/*.txt', + '!node_modules/font-awesome/*.md', + '!node_modules/font-awesome/*.json' + ]) + .pipe(gulp.dest('vendor/font-awesome')) +}) + +// Run everything +gulp.task('default', ['less', 'minify-css', 'minify-js', 'copy']); + +// Configure the browserSync task +gulp.task('browserSync', function() { + browserSync.init({ + server: { + baseDir: '' + }, + }) +}) + +// Dev task with browserSync +gulp.task('dev', ['browserSync', 'less', 'minify-css', 'minify-js'], function() { + gulp.watch('less/*.less', ['less']); + gulp.watch('css/*.css', ['minify-css']); + gulp.watch('js/*.js', ['minify-js']); + // Reloads the browser whenever HTML or JS files change + gulp.watch('*.html', browserSync.reload); + gulp.watch('js/**/*.js', browserSync.reload); +}); + +// Compiles SCSS files from /scss into /css +// NOTE: This theme uses LESS by default. To swtich to SCSS you will need to update this gulpfile by changing the 'less' tasks to run 'sass'! +gulp.task('sass', function() { + return gulp.src('scss/agency.scss') + .pipe(sass()) + .pipe(header(banner, { pkg: pkg })) + .pipe(gulp.dest('css')) + .pipe(browserSync.reload({ + stream: true + })) +}); diff --git a/documentation/img/background_image_webapps.png b/documentation/img/background_image_webapps.png new file mode 100644 index 00000000..4b8eece3 Binary files /dev/null and b/documentation/img/background_image_webapps.png differ diff --git a/documentation/img/cloudStorage.gif b/documentation/img/cloudStorage.gif new file mode 100644 index 00000000..30894b4d Binary files /dev/null and b/documentation/img/cloudStorage.gif differ diff --git a/documentation/img/cloudStorage.png b/documentation/img/cloudStorage.png new file mode 100644 index 00000000..c1992c34 Binary files /dev/null and b/documentation/img/cloudStorage.png differ diff --git a/documentation/img/dasch.png b/documentation/img/dasch.png new file mode 100644 index 00000000..c4024104 Binary files /dev/null and b/documentation/img/dasch.png differ diff --git a/documentation/img/gifs/microservice.gif b/documentation/img/gifs/microservice.gif new file mode 100644 index 00000000..613cb63b Binary files /dev/null and b/documentation/img/gifs/microservice.gif differ diff --git a/documentation/img/gifs/ownData.png b/documentation/img/gifs/ownData.png index 124357ef..bd061ca9 100644 Binary files a/documentation/img/gifs/ownData.png and b/documentation/img/gifs/ownData.png differ diff --git a/documentation/img/institutions_vision.png b/documentation/img/institutions_vision.png new file mode 100644 index 00000000..0b266455 Binary files /dev/null and b/documentation/img/institutions_vision.png differ diff --git a/documentation/img/microserivces.png b/documentation/img/microserivces.png new file mode 100644 index 00000000..8a7436dd Binary files /dev/null and b/documentation/img/microserivces.png differ diff --git a/documentation/img/s3it.jpg b/documentation/img/s3it.jpg new file mode 100644 index 00000000..3dbee29a Binary files /dev/null and b/documentation/img/s3it.jpg differ diff --git a/documentation/img/swissuniversities.jpg b/documentation/img/swissuniversities.jpg new file mode 100644 index 00000000..bb505c5c Binary files /dev/null and b/documentation/img/swissuniversities.jpg differ diff --git a/documentation/img/ubasel.jpg b/documentation/img/ubasel.jpg new file mode 100644 index 00000000..62560ae4 Binary files /dev/null and b/documentation/img/ubasel.jpg differ diff --git a/documentation/img/ubbasel.png b/documentation/img/ubbasel.png new file mode 100644 index 00000000..5f92b51c Binary files /dev/null and b/documentation/img/ubbasel.png differ diff --git a/documentation/img/ubern.jpg b/documentation/img/ubern.jpg new file mode 100644 index 00000000..31b790ce Binary files /dev/null and b/documentation/img/ubern.jpg differ diff --git a/documentation/img/ubern.png b/documentation/img/ubern.png new file mode 100644 index 00000000..abf2c059 Binary files /dev/null and b/documentation/img/ubern.png differ diff --git a/documentation/img/uzh.png b/documentation/img/uzh.png new file mode 100644 index 00000000..43f59a9d Binary files /dev/null and b/documentation/img/uzh.png differ diff --git a/documentation/img/zb.png b/documentation/img/zb.png new file mode 100644 index 00000000..e6899760 Binary files /dev/null and b/documentation/img/zb.png differ diff --git a/documentation/index.html b/documentation/index.html index 62d50341..18e50062 100644 --- a/documentation/index.html +++ b/documentation/index.html @@ -9,7 +9,7 @@ - Agency - Start Bootstrap Theme + inseri use cases @@ -18,8 +18,7 @@ - + @@ -28,141 +27,488 @@ - + + + - + + + + + +
-
-