This is the codeAbility Sharing Platform! Learn more about the codeAbility Sharing Platform.

Commit 3c84784b authored by Michael Breu's avatar Michael Breu 💬
Browse files

Intermediate commit

parent fa47b76e
......@@ -9,7 +9,7 @@
"baseName": "pluginDemo",
"packageName": "org.codeability.sharing.demo",
"packageFolder": "org/codeability/sharing/demo",
"serverPort": "8080",
"serverPort": "8082",
"authenticationType": "oauth2",
"cacheProvider": "ehcache",
"enableHibernateCache": true,
......
This diff is collapsed.
......@@ -8,27 +8,27 @@
"node_modules"
],
"dependencies": {
"@angular/common": "10.0.0",
"@angular/compiler": "10.0.0",
"@angular/core": "10.0.0",
"@angular/forms": "10.0.0",
"@angular/localize": "10.0.0",
"@angular/platform-browser": "10.0.0",
"@angular/platform-browser-dynamic": "10.0.0",
"@angular/router": "10.0.0",
"@fortawesome/angular-fontawesome": "0.6.1",
"@angular/common": "10.0.5",
"@angular/compiler": "10.0.5",
"@angular/core": "10.0.5",
"@angular/forms": "10.0.5",
"@angular/localize": "10.0.5",
"@angular/platform-browser": "10.0.5",
"@angular/platform-browser-dynamic": "10.0.5",
"@angular/router": "10.0.5",
"@fortawesome/angular-fontawesome": "0.7.0",
"@fortawesome/fontawesome-svg-core": "1.2.29",
"@fortawesome/free-solid-svg-icons": "5.13.1",
"@ng-bootstrap/ng-bootstrap": "6.1.0",
"@ngx-translate/core": "12.1.2",
"@ngx-translate/http-loader": "5.0.0",
"@ng-bootstrap/ng-bootstrap": "7.0.0",
"@ngx-translate/core": "13.0.0",
"@ngx-translate/http-loader": "6.0.0",
"bootstrap": "4.5.0",
"bootswatch": "4.5.0",
"moment": "2.27.0",
"ng-jhipster": "0.15.0",
"ngx-cookie-service": "3.0.4",
"ng-jhipster": "0.16.0",
"ngx-cookie-service": "10.1.1",
"ngx-infinite-scroll": "9.0.0",
"ngx-webstorage": "5.0.0",
"ngx-webstorage": "6.0.0",
"rxjs": "6.5.5",
"swagger-ui-dist": "3.25.1",
"tslib": "2.0.0",
......@@ -36,8 +36,8 @@
},
"devDependencies": {
"@angular/cli": "10.0.0",
"@angular/compiler-cli": "10.0.0",
"@ngtools/webpack": "10.0.0",
"@angular/compiler-cli": "10.0.5",
"@ngtools/webpack": "10.0.5",
"@openapitools/openapi-generator-cli": "1.0.13-4.3.1",
"@types/jest": "26.0.3",
"@types/node": "13.13.4",
......@@ -47,7 +47,7 @@
"autoprefixer": "9.8.4",
"browser-sync": "2.26.7",
"browser-sync-webpack-plugin": "2.2.2",
"codelyzer": "5.2.2",
"codelyzer": "6.0.1",
"copy-webpack-plugin": "6.0.2",
"css-loader": "3.6.0",
"eslint": "6.8.0",
......
......@@ -10,6 +10,11 @@
<name>Plugin Demo</name>
<repositories>
<repository>
<id>codabilitySharingAPIRepository</id>
<name>codability Sharing API Repository via git</name>
<url>https://sharing-codeability.uibk.ac.at/development/sharing/codeabilitysharingpluginapi/-/raw/master/target/</url>
</repository>
<!-- jhipster-needle-maven-repository -->
</repositories>
......@@ -22,7 +27,7 @@
<properties>
<!-- Build properties -->
<maven.version>3.3.9</maven.version>
<java.version>1.8</java.version>
<java.version>14</java.version>
<node.version>v12.16.1</node.version>
<npm.version>6.14.5</npm.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
......@@ -103,6 +108,12 @@
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.codeability.sharing</groupId>
<artifactId>SharingPluginPlatformAPI</artifactId>
<version>0.0.1</version>
</dependency>
<dependency>
<groupId>io.github.jhipster</groupId>
<artifactId>jhipster-framework</artifactId>
......@@ -135,7 +146,7 @@
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>test</scope>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
......
......@@ -86,6 +86,7 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
.and()
.authorizeRequests()
.antMatchers("/api/auth-info").permitAll()
.antMatchers("/api/sharingPluginConfig").permitAll()
.antMatchers("/api/**").authenticated()
.antMatchers("/management/health").permitAll()
.antMatchers("/management/info").permitAll()
......
package org.codeability.sharing.demo.service;
import org.codeability.sharing.plugins.api.SharingPluginConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
/**
* Service to support Sharing Plattform functionality as a plugin.
*/
@Service
public class SharingPluginService {
private final Logger log = LoggerFactory.getLogger(SharingPluginService.class);
public SharingPluginService() {
}
public SharingPluginConfig getPluginConfig(String baseAPIURI) {
SharingPluginConfig.Action actionCollection = new SharingPluginConfig.Action(
"DemoAction", "/sharingPluginLandingPage",
"Transfer Collection to Demo Plugin",
"metadata.type.externalName=='collections'"); // select for collections
SharingPluginConfig.Action actionProgExercise = new SharingPluginConfig.Action(
"DemoAction", "/sharingPluginLandingPage",
"Transfer Programming Exercise to Demo Plugin",
"metadata.type.externalName=='programming exercise'"); // select for programming exercise
// "Import to Artemis", "metadata.type.externalName=='programming exercise' || metadata.type.externalName=='collection'");
SharingPluginConfig pluginConfig = new SharingPluginConfig("Demo Sharing Plugin Connector",
new SharingPluginConfig.Action[]{actionCollection, actionProgExercise});
return pluginConfig;
}
}
package org.codeability.sharing.demo.web.rest;
import org.codeability.sharing.demo.service.SharingPluginService;
import org.codeability.sharing.plugins.api.SharingPluginConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* REST controller for Supporting Import and Export to Sharing Plattform.
*/
@Validated
@RestController
@RequestMapping("/api")
public class SharingSupportResource {
private final Logger log = LoggerFactory.getLogger(SharingSupportResource.class);
private SharingPluginService sharingPluginService;
public SharingSupportResource(SharingPluginService sharingPluginService) {
this.sharingPluginService = sharingPluginService;
}
/**
* Returns Sharing Plugin configuration
*
* @return Sharing Plugin configuration
*/
@GetMapping("/sharingPluginConfig")
public ResponseEntity<SharingPluginConfig> getConfig() {
return ResponseEntity.ok(sharingPluginService.getPluginConfig("/api"));
}
}
......@@ -116,11 +116,11 @@ spring:
client:
provider:
oidc:
issuer-uri: http://localhost:9080/auth/realms/jhipster
issuer-uri: https://sharing.codeability-austria.uibk.ac.at
registration:
oidc:
client-id: web_app
client-secret: web_app
client-id: 149276ac11138d9ba72fb3cd12815e3fa2f372866df0eac0f7d1aae5fdffea24
client-secret: 6f480635241f420a361581f4837594ea6f48f5ee6f515c1aa89f325dd922dbb0
server:
servlet:
......
......@@ -21,7 +21,12 @@ const LAYOUT_ROUTES = [navbarRoute, ...errorRoute];
canActivate: [UserRouteAccessService],
loadChildren: () => import('./admin/admin-routing.module').then(m => m.AdminRoutingModule),
},
...LAYOUT_ROUTES,
// ===== Sharing Import/Export =====
{
path: 'sharingPluginLandingPage/:basketToken',
loadChildren: () => import('./sharing/sharing.module' ).then((m) => m.SharingModule),
},
...LAYOUT_ROUTES,
],
{ enableTracing: DEBUG_INFO_ENABLED }
),
......
......@@ -14,6 +14,7 @@ import { FooterComponent } from './layouts/footer/footer.component';
import { PageRibbonComponent } from './layouts/profiles/page-ribbon.component';
import { ActiveMenuDirective } from './layouts/navbar/active-menu.directive';
import { ErrorComponent } from './layouts/error/error.component';
import { SharingInfo } from 'app/sharing/sharing.model';
@NgModule({
imports: [
......@@ -27,5 +28,6 @@ import { ErrorComponent } from './layouts/error/error.component';
],
declarations: [MainComponent, NavbarComponent, ErrorComponent, PageRibbonComponent, ActiveMenuDirective, FooterComponent],
bootstrap: [MainComponent],
providers: [SharingInfo],
})
export class PluginDemoAppModule {}
<body>
<div class="wrapper">
<div class="header">
<h1>Happy Sharing</h1>
</div>
<div class="content">
<div><b>This page is intentionally ugly :-)</b></div>
<div>basketToken: {{this.sharingInfo.basketToken}}</div>
<div>returnURL: {{this.sharingInfo.returnURL}}</div>
<div>apiBaseURL: {{this.sharingInfo.apiBaseURL}}</div>
<div *ngIf="!isInstuctor()">Please ensure to log in as instructor!</div>
</div>
</div>
</body>
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { SharingInfo } from './sharing.model';
@Component({
selector: 'jhi-sharing',
templateUrl: './sharing.component.html',
styleUrls: ['./sharing.scss'],
})
export class SharingComponent implements OnInit {
constructor(
private route: ActivatedRoute,
private router: Router,
public sharingInfo: SharingInfo,
) {
this.route.params.subscribe((params) => {
sharingInfo.basketToken = params['basketToken'];
});
this.route.queryParams.subscribe((qparam) => {
sharingInfo.returnURL = qparam['returnURL'];
sharingInfo.apiBaseURL = qparam['apiBaseURL'];
// }
});
}
/**
* Initialises the sharing page for import
*/
ngOnInit(): void {}
}
import { Injectable } from '@angular/core';
@Injectable()
export class SharingInfo {
public basketToken = '';
public returnURL = "";
public apiBaseURL = "";
public selectedExercise = 0;
public isAvailable(): boolean {
return this.basketToken !== null && this.basketToken !== '';
}
public clear(): void {
this.basketToken = '';
}
}
import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';
import { SharingComponent } from 'app/sharing/sharing.component';
import { featureOverviewState } from 'app/sharing/sharing.route';
const SHARING_ROUTES = [...featureOverviewState];
@NgModule({
imports: [RouterModule.forChild(SHARING_ROUTES)],
declarations: [SharingComponent],
})
export class SharingModule {}
import { Routes } from '@angular/router';
import { SharingComponent } from 'app/sharing/sharing.component';
export const sharingRoutes: Routes = [
{
path: '',
component: SharingComponent,
data: {
pageTitle: 'Sharing Tests',
},
},
];
const SHARING_ROUTES = [...sharingRoutes];
export const featureOverviewState: Routes = [
{
path: '',
children: SHARING_ROUTES,
},
];
body {
margin: 0;
padding: 0;
font-family: 'Ubuntu', sans-serif;
display: flex;
}
.header {
position: relative;
text-align: center;
background: #3070b3;
}
.curve {
fill: #fff;
height: 100px;
width: 100%;
position: absolute;
bottom: 0;
left: 0;
}
.header h1 {
color: #fff;
margin: 0;
padding: 1em 2em;
font-size: 5em;
text-shadow: 1px 1px 40px #333;
box-sizing: border-box;
}
.content {
padding: 20px;
}
.wrapper {
float: left;
align-content: center;
align-items: center;
box-sizing: border-box;
width: 100%;
background: #fff;
}
.features-overview {
margin: 0;
padding-left: 20%;
padding-right: 20%;
text-align: center;
color: #3070b3;
}
.content h2 {
margin: 0;
padding-left: 20%;
padding-right: 20%;
text-align: center;
color: #3070b3;
font-size: 3em;
padding-bottom: 1em;
box-sizing: border-box;
}
.container {
width: 1200px;
height: auto;
margin: 0 auto;
display: grid;
align-items: center;
align-self: center;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
grid-gap: 15px;
padding: 10px;
box-sizing: border-box;
cursor: pointer;
}
.feature-content {
margin: 0;
box-sizing: border-box;
padding-left: 35px;
padding-right: 35px;
}
.feature-content h3 {
margin: 0;
text-align: center;
color: #3070b3;
font-size: 2em;
padding: 1em 20% 0.5em;
box-sizing: border-box;
}
.feature-full-description {
overflow: auto;
padding: 35px;
}
.feature-full-description p {
width: 100%;
font-size: 18px;
line-height: 26px;
word-wrap: break-word;
overflow-wrap: break-word;
white-space: pre-wrap;
hyphens: auto;
}
.container .box {
position: relative;
height: 250px;
background: #3070b3;
padding: 15px 15px 15px;
text-align: left;
box-sizing: border-box;
overflow: hidden;
border-radius: 10px;
}
.container .box .icon {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: #f2f2f2;
transition: 0.5s;
z-index: 1;
}
.container .box:hover .icon {
top: 20px;
left: calc(50% - 40px);
width: 80px;
height: 80px;
border-radius: 50%;
cursor: pointer;
}
.container .box .icon .title {
position: absolute;
margin-left: 20px;
display: inline-block;
top: calc(50% + 10px);
padding: 20px 10px;
color: #3070b3;
font-size: 22px;
width: calc(100% - 40px);
text-align: center;
opacity: 1;
}
.container .box .icon .fa {
position: absolute;
top: calc(50% - 20px);
left: 50%;
transform: translate(-50%, -50%);
font-size: 80px;
transition: 0.5s;
color: #3070b3;
}
.container .box:hover .icon .fa {
top: 50%;
font-size: 40px;
}
.container .box:hover .icon .title {
opacity: 0;
}
.container .box .feature-short-description {
position: absolute;
top: 100%;
height: calc(100% - 120px);
width: calc(100% - 40px);
box-sizing: border-box;
font-size: 18px;
transition: 0.5s;
opacity: 0;
}
.container .box:hover .feature-short-description {
top: 100px;
opacity: 1;
text-align: center;
}
.container .box .feature-short-description h3 {
margin: 0;
padding: 0;
color: #fff;
font-size: 24px;
text-align: center;
}
.container .box .feature-short-description p {
margin: 0;
padding: 0;
color: #fff;
font-size: 20px;
}
hr.hr-gradient {
height: 10px;
position: relative;
width: calc(100% - 300px);
background: radial-gradient(ellipse farthest-side at top center, rgba(0, 0, 0, 0.06), transparent);
}
hr.hr-gradient::before {
content: '';
display: block;
position: absolute;
top: 0;
right: 0;
left: 0;
height: 3px;
background: linear-gradient(to left, transparent, rgba(0, 0, 0, 0.02), rgba(0, 0, 0, 0.02), transparent);
}
hr.hr-text {
position: relative;
border: none;
height: 1px;
background-color: #3070b3;
}
hr.hr-text::before {
content: attr(data-content);
display: inline-block;
background-color: #fff;
font-weight: bold;
font-size: 0.85rem;
color: #fff;
border-radius: 30rem;
padding: 0.2rem 2rem;
position: absolute;
top: 50%;
left: 50%;