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

Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • development/sharing/codeability-sharing-platform
1 result
Show changes
Commits on Source (4)
Showing
with 278 additions and 236 deletions
...@@ -6,12 +6,6 @@ ...@@ -6,12 +6,6 @@
<attribute name="maven.pomderived" value="true"/> <attribute name="maven.pomderived" value="true"/>
</attributes> </attributes>
</classpathentry> </classpathentry>
<classpathentry kind="src" output="target/test-classes" path="target/generated-test-sources/test-annotations">
<attributes>
<attribute name="test" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" path="target/generated-sources/annotations"/>
<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources"> <classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
<attributes> <attributes>
<attribute name="maven.pomderived" value="true"/> <attribute name="maven.pomderived" value="true"/>
...@@ -19,20 +13,19 @@ ...@@ -19,20 +13,19 @@
</classpathentry> </classpathentry>
<classpathentry kind="src" output="target/test-classes" path="src/test/java"> <classpathentry kind="src" output="target/test-classes" path="src/test/java">
<attributes> <attributes>
<attribute name="test" value="true"/>
<attribute name="optional" value="true"/> <attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/> <attribute name="maven.pomderived" value="true"/>
<attribute name="test" value="true"/>
</attributes> </attributes>
</classpathentry> </classpathentry>
<classpathentry excluding="**" kind="src" output="target/test-classes" path="src/test/resources"> <classpathentry excluding="**" kind="src" output="target/test-classes" path="src/test/resources">
<attributes> <attributes>
<attribute name="test" value="true"/>
<attribute name="maven.pomderived" value="true"/> <attribute name="maven.pomderived" value="true"/>
<attribute name="test" value="true"/>
</attributes> </attributes>
</classpathentry> </classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11"> <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11">
<attributes> <attributes>
<attribute name="module" value="true"/>
<attribute name="maven.pomderived" value="true"/> <attribute name="maven.pomderived" value="true"/>
</attributes> </attributes>
</classpathentry> </classpathentry>
...@@ -41,5 +34,22 @@ ...@@ -41,5 +34,22 @@
<attribute name="maven.pomderived" value="true"/> <attribute name="maven.pomderived" value="true"/>
</attributes> </attributes>
</classpathentry> </classpathentry>
<classpathentry kind="src" path="target/generated-sources/annotations">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
<attribute name="ignore_optional_problems" value="true"/>
<attribute name="m2e-apt" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="target/test-classes" path="target/generated-test-sources/test-annotations">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
<attribute name="ignore_optional_problems" value="true"/>
<attribute name="m2e-apt" value="true"/>
<attribute name="test" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="target/classes"/> <classpathentry kind="output" path="target/classes"/>
</classpath> </classpath>
...@@ -32,6 +32,7 @@ tmp/**/* ...@@ -32,6 +32,7 @@ tmp/**/*
local.properties local.properties
.loadpath .loadpath
.factorypath .factorypath
.settings/org.eclipse.jdt.apt.core.prefs
# CDT-specific # CDT-specific
......
...@@ -39,4 +39,15 @@ ...@@ -39,4 +39,15 @@
<nature>org.eclipse.jdt.core.javanature</nature> <nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.m2e.core.maven2Nature</nature> <nature>org.eclipse.m2e.core.maven2Nature</nature>
</natures> </natures>
<filteredResources>
<filter>
<id>1617023900149</id>
<name></name>
<type>30</type>
<matcher>
<id>org.eclipse.core.resources.regexFilterMatcher</id>
<arguments>node_modules|.git|__CREATED_BY_JAVA_LANGUAGE_SERVER__</arguments>
</matcher>
</filter>
</filteredResources>
</projectDescription> </projectDescription>
eclipse.preferences.version=1
org.eclipse.jdt.apt.aptEnabled=true
org.eclipse.jdt.apt.genSrcDir=target/generated-sources/annotations
org.eclipse.jdt.apt.genTestSrcDir=target/generated-test-sources/test-annotations
...@@ -12,5 +12,6 @@ org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled ...@@ -12,5 +12,6 @@ org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=warning
org.eclipse.jdt.core.compiler.processAnnotations=enabled
org.eclipse.jdt.core.compiler.release=disabled org.eclipse.jdt.core.compiler.release=disabled
org.eclipse.jdt.core.compiler.source=11 org.eclipse.jdt.core.compiler.source=11
...@@ -20,6 +20,7 @@ import org.springframework.util.StreamUtils; ...@@ -20,6 +20,7 @@ import org.springframework.util.StreamUtils;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import at.ac.uibk.gitsearch.repository.gitlab.GitLabRepository; import at.ac.uibk.gitsearch.repository.gitlab.GitLabRepository;
import at.ac.uibk.gitsearch.security.jwt.TokenProvider;
/** /**
* Service for exercise/course search results * Service for exercise/course search results
...@@ -30,14 +31,16 @@ public class GitlabService { ...@@ -30,14 +31,16 @@ public class GitlabService {
@Autowired @Autowired
private GitLabRepository gitLabRepository; private GitLabRepository gitLabRepository;
@Autowired
protected TokenProvider tokenProvider;
private final Logger log = LoggerFactory.getLogger(ShoppingBasketService.class); private final Logger log = LoggerFactory.getLogger(ShoppingBasketService.class);
public Boolean repositoryExists(String projectID) { public Boolean repositoryExists(String projectID) {
final GitLabApi gitLabApi = gitLabRepository.getGitLabApi();
final ProjectApi gitLabProjectApi = gitLabApi.getProjectApi();
try{ try{
final GitLabApi gitLabApi = gitLabRepository.getGitLabApi(tokenProvider.getGitLabAccessInfo());
final ProjectApi gitLabProjectApi = gitLabApi.getProjectApi();
return gitLabProjectApi.getProject(projectID) != null;} return gitLabProjectApi.getProject(projectID) != null;}
catch(GitLabApiException e){ catch(GitLabApiException e){
log.error(e.getMessage(), e); log.error(e.getMessage(), e);
...@@ -48,7 +51,7 @@ public class GitlabService { ...@@ -48,7 +51,7 @@ public class GitlabService {
public InputStream getRepositoryZip(String exerciseID) throws GitLabApiException, IOException { public InputStream getRepositoryZip(String exerciseID) throws GitLabApiException, IOException {
final GitLabApi gitLabApi = gitLabRepository.getGitLabApi(Optional.empty()); final GitLabApi gitLabApi = gitLabRepository.getGitLabApi(tokenProvider.getGitLabAccessInfo());
return rePackageGitLabProjectZip(new ZipInputStream(gitLabApi.getRepositoryApi().getRepositoryArchive(exerciseID, "HEAD", "zip")), "from project " + exerciseID); return rePackageGitLabProjectZip(new ZipInputStream(gitLabApi.getRepositoryApi().getRepositoryArchive(exerciseID, "HEAD", "zip")), "from project " + exerciseID);
} }
......
...@@ -244,8 +244,8 @@ public class SearchService { ...@@ -244,8 +244,8 @@ public class SearchService {
return copyInputStreamToFile(inputFile, file);} return copyInputStreamToFile(inputFile, file);}
catch(GitLabApiException exception){ catch(GitLabApiException exception){
log.error(exception.getMessage()); log.error(exception.getMessage());
return null;
} }
return null;
} }
private File copyInputStreamToFile(InputStream inputStream, File file) throws IOException { private File copyInputStreamToFile(InputStream inputStream, File file) throws IOException {
......
...@@ -163,7 +163,7 @@ public class StatisticsResource { ...@@ -163,7 +163,7 @@ public class StatisticsResource {
return ResponseUtil.wrapOrNotFound(statisticsDTO); return ResponseUtil.wrapOrNotFound(statisticsDTO);
} }
else{ else{
return null; return ResponseUtil.wrapOrNotFound(statisticsDTO);
} }
} }
......
...@@ -74,7 +74,6 @@ spring: ...@@ -74,7 +74,6 @@ spring:
client-id: ${SECURITY_OAUTH2_CLIENT_REGISTRATION_GITLABOIDC_CLIENTID} client-id: ${SECURITY_OAUTH2_CLIENT_REGISTRATION_GITLABOIDC_CLIENTID}
client-secret: ${SECURITY_OAUTH2_CLIENT_REGISTRATION_GITLABOIDC_CLIENTSECRET} client-secret: ${SECURITY_OAUTH2_CLIENT_REGISTRATION_GITLABOIDC_CLIENTSECRET}
# =================================================================== # ===================================================================
# To enable TLS in production, generate a certificate using: # To enable TLS in production, generate a certificate using:
# keytool -genkey -alias gitsearch -storetype PKCS12 -keyalg RSA -keysize 2048 -keystore keystore.p12 -validity 3650 # keytool -genkey -alias gitsearch -storetype PKCS12 -keyalg RSA -keysize 2048 -keystore keystore.p12 -validity 3650
...@@ -154,7 +153,7 @@ jhipster: ...@@ -154,7 +153,7 @@ jhipster:
application: application:
registeredPlugins: registeredPlugins:
- "https://artemis.codeability.uibk.ac.at/api/sharing/config" - 'https://artemis.codeability.uibk.ac.at/api/sharing/config'
gitlab: gitlab:
url: https://sharing-codeability.uibk.ac.at/ url: https://sharing-codeability.uibk.ac.at/
generalAccessToken: ${APPLICATION_GITLAB_GENERALACCESSTOKEN} generalAccessToken: ${APPLICATION_GITLAB_GENERALACCESSTOKEN}
...@@ -42,9 +42,9 @@ export class HealthComponent implements OnInit { ...@@ -42,9 +42,9 @@ export class HealthComponent implements OnInit {
const modalRef = this.modalService.open(HealthModalComponent); const modalRef = this.modalService.open(HealthModalComponent);
modalRef.componentInstance.health = health; modalRef.componentInstance.health = health;
} }
translateKeys(key: string) { translateKeys(key: string) {
if ( key.startsWith('health.indicator.http')) return key.substr(17); if (key.startsWith('health.indicator.http')) return key.substr(17);
return this.translateService.instant(key); return this.translateService.instant(key);
} }
} }
...@@ -16,7 +16,7 @@ import { PageRibbonComponent } from './layouts/profiles/page-ribbon.component'; ...@@ -16,7 +16,7 @@ import { PageRibbonComponent } from './layouts/profiles/page-ribbon.component';
import { ActiveMenuDirective } from './layouts/navbar/active-menu.directive'; import { ActiveMenuDirective } from './layouts/navbar/active-menu.directive';
import { ErrorComponent } from './layouts/error/error.component'; import { ErrorComponent } from './layouts/error/error.component';
import { QueryParamModule } from '@ngqp/core'; import { QueryParamModule } from '@ngqp/core';
import { CacheService } from 'app/shared/service/cache.service' import { CacheService } from 'app/shared/service/cache.service';
@NgModule({ @NgModule({
imports: [ imports: [
...@@ -30,17 +30,8 @@ import { CacheService } from 'app/shared/service/cache.service' ...@@ -30,17 +30,8 @@ import { CacheService } from 'app/shared/service/cache.service'
GitSearchV2AppRoutingModule, GitSearchV2AppRoutingModule,
QueryParamModule, QueryParamModule,
], ],
declarations: [ declarations: [MainComponent, NavbarComponent, ErrorComponent, PageRibbonComponent, ActiveMenuDirective, FooterComponent],
MainComponent,
NavbarComponent,
ErrorComponent,
PageRibbonComponent,
ActiveMenuDirective,
FooterComponent],
bootstrap: [MainComponent], bootstrap: [MainComponent],
providers: [ providers: [CacheService],
CacheService,
]
}) })
export class GitSearchV2AppModule {} export class GitSearchV2AppModule {}
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http'; import { HttpClient } from '@angular/common/http';
import { Observable, } from 'rxjs'; import { Observable } from 'rxjs';
import { SERVER_API_URL } from 'app/app.constants'; import { SERVER_API_URL } from 'app/app.constants';
export class DeploymentInfo { export class DeploymentInfo {
branch = ""; branch = '';
commitId = ""; commitId = '';
} }
@Injectable({ providedIn: 'root' }) @Injectable({ providedIn: 'root' })
export class ApplicationInfoService { export class ApplicationInfoService {
cachedDeploymentInfo: DeploymentInfo; cachedDeploymentInfo: DeploymentInfo;
inLoading = false; inLoading = false;
constructor( constructor(private http: HttpClient) {
private http: HttpClient, this.cachedDeploymentInfo = {} as DeploymentInfo;
) { }
this.cachedDeploymentInfo = {} as DeploymentInfo;
}
private loadDeploymentInfo(): Observable<DeploymentInfo> { private loadDeploymentInfo(): Observable<DeploymentInfo> {
return this.http.get<DeploymentInfo>(SERVER_API_URL + 'api/applicationInfo/deploymentInfo'); return this.http.get<DeploymentInfo>(SERVER_API_URL + 'api/applicationInfo/deploymentInfo');
} }
public getDeploymentInfo(): DeploymentInfo { public getDeploymentInfo(): DeploymentInfo {
if(!this.cachedDeploymentInfo.branch && !this.inLoading) { if (!this.cachedDeploymentInfo.branch && !this.inLoading) {
this.inLoading = true; this.inLoading = true;
this.loadDeploymentInfo().subscribe((res) => { this.loadDeploymentInfo().subscribe(res => {
this.cachedDeploymentInfo = res; this.cachedDeploymentInfo = res;
this.inLoading = false; this.inLoading = false;
}); });
} }
return this.cachedDeploymentInfo; return this.cachedDeploymentInfo;
} }
} }
...@@ -26,7 +26,7 @@ export class ExerciseCardComponent implements OnInit { ...@@ -26,7 +26,7 @@ export class ExerciseCardComponent implements OnInit {
this.exercise!.views = data.views!; this.exercise!.views = data.views!;
this.exercise!.downloads = data.downloads!; this.exercise!.downloads = data.downloads!;
}, },
() => alert('Request failed') () => alert('Could not load exercise statistics')
); );
} }
this.exerciseSelectionEvent.emit(this.exercise); this.exerciseSelectionEvent.emit(this.exercise);
......
...@@ -5,8 +5,6 @@ import { Subscription } from 'rxjs'; ...@@ -5,8 +5,6 @@ import { Subscription } from 'rxjs';
import { PluginActionInfo } from 'app/shared/model/search/search-result-dto.model'; import { PluginActionInfo } from 'app/shared/model/search/search-result-dto.model';
import { PluginService } from 'app/shared/service/plugin-service'; import { PluginService } from 'app/shared/service/plugin-service';
import { ShoppingBasketInfo, ShoppingBasketRedirectInfoDTO } from 'app/shared/model/basket/shopping-basket-info.model'; import { ShoppingBasketInfo, ShoppingBasketRedirectInfoDTO } from 'app/shared/model/basket/shopping-basket-info.model';
import { HttpErrorResponse } from '@angular/common/http';
import { AccountService } from 'app/core/auth/account.service'; import { AccountService } from 'app/core/auth/account.service';
import { Account } from 'app/core/user/account.model'; import { Account } from 'app/core/user/account.model';
import { SearchService } from 'app/search/service/search-service.ts'; import { SearchService } from 'app/search/service/search-service.ts';
...@@ -51,7 +49,7 @@ export class ExerciseDetailsComponent implements OnInit, OnDestroy { ...@@ -51,7 +49,7 @@ export class ExerciseDetailsComponent implements OnInit, OnDestroy {
} }
public getPersonDetailsWithEmail(person: Person): string { public getPersonDetailsWithEmail(person: Person): string {
return "<a class='text-dark' href= 'mailto:'" + person.email + '>' + person.name + ', ' + person.affiliation + '</a>'; return "<a class='text-dark' href='mailto:" + person.email + "'>" + person.name + ', ' + person.affiliation + '</a>';
} }
public arrayToString(array: string[]): string { public arrayToString(array: string[]): string {
...@@ -71,22 +69,21 @@ export class ExerciseDetailsComponent implements OnInit, OnDestroy { ...@@ -71,22 +69,21 @@ export class ExerciseDetailsComponent implements OnInit, OnDestroy {
return result; return result;
} }
public startAction(action: PluginActionInfo, exercise: Exercise): void { public startAction(action: PluginActionInfo, exercise: Exercise): void {
const basketInfo: ShoppingBasketInfo = { const basketInfo: ShoppingBasketInfo = {
plugin: action.plugin, plugin: action.plugin,
action: action.action, action: action.action,
itemInfos: [ itemInfos: [exercise.originalResult],
exercise.originalResult };
] this.pluginService.getRedirectLink(basketInfo).subscribe(
}; (redirectInfo: ShoppingBasketRedirectInfoDTO) => {
this.pluginService.getRedirectLink(basketInfo).subscribe( // alert('redirecting to ' + redirectInfo.redirectURL);
(redirectInfo: ShoppingBasketRedirectInfoDTO) => { // location.href = redirectInfo.redirectURL;
// alert('redirecting to ' + redirectInfo.redirectURL); window.open(redirectInfo.redirectURL, action.action);
// location.href = redirectInfo.redirectURL; },
window.open(redirectInfo.redirectURL, action.action); () => alert('Search failed')
}, );
() => alert('Search failed')) }
}
public download(): void { public download(): void {
this.exportExercise(Number(this.exercise!.originalResult.project.project_id)); this.exportExercise(Number(this.exercise!.originalResult.project.project_id));
...@@ -107,7 +104,7 @@ export class ExerciseDetailsComponent implements OnInit, OnDestroy { ...@@ -107,7 +104,7 @@ export class ExerciseDetailsComponent implements OnInit, OnDestroy {
window.URL.revokeObjectURL(url); window.URL.revokeObjectURL(url);
} }
}, },
(error: HttpErrorResponse) => this.jhiAlertService.error('Unable to export exercise. Error: ' + error.message) () => alert('Unable to export exercise. Please log in to export.')
); );
} }
......
...@@ -6,7 +6,7 @@ import { TranslateService, LangChangeEvent } from '@ngx-translate/core'; ...@@ -6,7 +6,7 @@ import { TranslateService, LangChangeEvent } from '@ngx-translate/core';
import { AccountService } from 'app/core/auth/account.service'; import { AccountService } from 'app/core/auth/account.service';
import { AuthServerProvider } from 'app/core/auth/auth-jwt.service'; import { AuthServerProvider } from 'app/core/auth/auth-jwt.service';
import { CookieService } from 'ngx-cookie-service'; import { CookieService } from 'ngx-cookie-service';
import { MessageService, BroadCastMessage} from 'app/shared/service/message-service' import { MessageService, BroadCastMessage } from 'app/shared/service/message-service';
// import { AlertErrorComponent } from 'app/shared/alert/alert-error.component'; // import { AlertErrorComponent } from 'app/shared/alert/alert-error.component';
@Component({ @Component({
...@@ -24,9 +24,8 @@ export class MainComponent implements OnInit { ...@@ -24,9 +24,8 @@ export class MainComponent implements OnInit {
rootRenderer: RendererFactory2, rootRenderer: RendererFactory2,
private authServerProvider: AuthServerProvider, private authServerProvider: AuthServerProvider,
private cookieService: CookieService, private cookieService: CookieService,
private messageService: MessageService, private messageService: MessageService // private alertErrorComponent: AlertErrorComponent
) // private alertErrorComponent: AlertErrorComponent ) {
{
this.renderer = rootRenderer.createRenderer(document.querySelector('html'), null); this.renderer = rootRenderer.createRenderer(document.querySelector('html'), null);
} }
...@@ -50,11 +49,10 @@ export class MainComponent implements OnInit { ...@@ -50,11 +49,10 @@ export class MainComponent implements OnInit {
this.renderer.setAttribute(document.querySelector('html'), 'lang', langChangeEvent.lang); this.renderer.setAttribute(document.querySelector('html'), 'lang', langChangeEvent.lang);
}); });
} }
public getActiveMessages(): Array<BroadCastMessage> {
return this.messageService.getActiveMessages(); //
}
public getActiveMessages(): Array<BroadCastMessage> {
return this.messageService.getActiveMessages(); //
}
private checkRequestToken(): void { private checkRequestToken(): void {
const tokenCookie = this.cookieService.get('tempRequestToken'); const tokenCookie = this.cookieService.get('tempRequestToken');
......
...@@ -4,16 +4,16 @@ import { ActivatedRoute, Router } from '@angular/router'; ...@@ -4,16 +4,16 @@ import { ActivatedRoute, Router } from '@angular/router';
import { QueryParam, QueryParamBuilder, QueryParamGroup } from '@ngqp/core'; import { QueryParam, QueryParamBuilder, QueryParamGroup } from '@ngqp/core';
import { takeUntil } from 'rxjs/operators'; import { takeUntil } from 'rxjs/operators';
import { SearchInput } from 'app/shared/model/search/search-input.model'; import { SearchInput } from 'app/shared/model/search/search-input.model';
import { SearchService } from '../service/search-service' import { SearchService } from '../service/search-service';
import { faQuestion } from '@fortawesome/free-solid-svg-icons'; import { faQuestion } from '@fortawesome/free-solid-svg-icons';
import {Observable} from 'rxjs'; import { Observable } from 'rxjs';
import {debounceTime, distinctUntilChanged, map, switchMap} from 'rxjs/operators'; import { debounceTime, distinctUntilChanged, map, switchMap } from 'rxjs/operators';
import {IExerciseType } from 'app/shared/model/exercise.model'; import { IExerciseType } from 'app/shared/model/exercise.model';
interface LooseObject { interface LooseObject {
[key: string]: any [key: string]: any;
} }
@Component({ @Component({
...@@ -26,9 +26,9 @@ export class SearchInputComponent implements OnInit, OnDestroy { ...@@ -26,9 +26,9 @@ export class SearchInputComponent implements OnInit, OnDestroy {
@Output() searchInputEvent = new EventEmitter<SearchInput>(); @Output() searchInputEvent = new EventEmitter<SearchInput>();
public pageSize = 4; public pageSize = 4;
typeValues = Object.keys(IExerciseType); typeValues = Object.keys(IExerciseType);
questionIcon = faQuestion; questionIcon = faQuestion;
public paramGroup: QueryParamGroup; public paramGroup: QueryParamGroup;
private componentDestroyed$ = new Subject<void>(); private componentDestroyed$ = new Subject<void>();
...@@ -37,15 +37,67 @@ export class SearchInputComponent implements OnInit, OnDestroy { ...@@ -37,15 +37,67 @@ export class SearchInputComponent implements OnInit, OnDestroy {
public showSearchUsage = false; public showSearchUsage = false;
private states = ['Alabama', 'Alaska', 'American Samoa', 'Arizona', 'Arkansas', 'California', 'Colorado', private states = [
'Connecticut', 'Delaware', 'District Of Columbia', 'Federated States Of Micronesia', 'Florida', 'Georgia', 'Alabama',
'Guam', 'Hawaii', 'Idaho', 'Illinois', 'Indiana', 'Iowa', 'Kansas', 'Kentucky', 'Louisiana', 'Maine', 'Alaska',
'Marshall Islands', 'Maryland', 'Massachusetts', 'Michigan', 'Minnesota', 'Mississippi', 'Missouri', 'Montana', 'American Samoa',
'Nebraska', 'Nevada', 'New Hampshire', 'New Jersey', 'New Mexico', 'New York', 'North Carolina', 'North Dakota', 'Arizona',
'Northern Mariana Islands', 'Ohio', 'Oklahoma', 'Oregon', 'Palau', 'Pennsylvania', 'Puerto Rico', 'Rhode Island', 'Arkansas',
'South Carolina', 'South Dakota', 'Tennessee', 'Texas', 'Utah', 'Vermont', 'Virgin Islands', 'Virginia', 'California',
'Washington', 'West Virginia', 'Wisconsin', 'Wyoming']; 'Colorado',
'Connecticut',
'Delaware',
'District Of Columbia',
'Federated States Of Micronesia',
'Florida',
'Georgia',
'Guam',
'Hawaii',
'Idaho',
'Illinois',
'Indiana',
'Iowa',
'Kansas',
'Kentucky',
'Louisiana',
'Maine',
'Marshall Islands',
'Maryland',
'Massachusetts',
'Michigan',
'Minnesota',
'Mississippi',
'Missouri',
'Montana',
'Nebraska',
'Nevada',
'New Hampshire',
'New Jersey',
'New Mexico',
'New York',
'North Carolina',
'North Dakota',
'Northern Mariana Islands',
'Ohio',
'Oklahoma',
'Oregon',
'Palau',
'Pennsylvania',
'Puerto Rico',
'Rhode Island',
'South Carolina',
'South Dakota',
'Tennessee',
'Texas',
'Utah',
'Vermont',
'Virgin Islands',
'Virginia',
'Washington',
'West Virginia',
'Wisconsin',
'Wyoming',
];
constructor( constructor(
protected activatedRoute: ActivatedRoute, protected activatedRoute: ActivatedRoute,
...@@ -80,17 +132,15 @@ export class SearchInputComponent implements OnInit, OnDestroy { ...@@ -80,17 +132,15 @@ export class SearchInputComponent implements OnInit, OnDestroy {
emptyOn: '', emptyOn: '',
}), }),
}; };
// add type checkbox support // add type checkbox support
this.typeValues.forEach( this.typeValues.forEach(function (type: string): void {
function(type: string): void { const typeName = type.toString();
const typeName = type.toString(); groupDef[typeName] = qpb.stringParam(typeName, {
groupDef[typeName] = qpb.stringParam(typeName, { debounceTime: SearchInputComponent.DEBOUNCE_TIME,
debounceTime: SearchInputComponent.DEBOUNCE_TIME, emptyOn: '',
emptyOn: '', });
}); });
}
);
this.paramGroup = qpb.group(groupDef); this.paramGroup = qpb.group(groupDef);
...@@ -98,19 +148,18 @@ export class SearchInputComponent implements OnInit, OnDestroy { ...@@ -98,19 +148,18 @@ export class SearchInputComponent implements OnInit, OnDestroy {
this.searchInput.setValues(value); this.searchInput.setValues(value);
this.searchInputEvent.emit(this.searchInput); this.searchInputEvent.emit(this.searchInput);
}); });
} }
getSelectedTypes(): string[] { getSelectedTypes(): string[] {
const result: string[] = []; const result: string[] = [];
this.typeValues.forEach( this.typeValues.forEach(type => {
type => {if(this.paramGroup.queryParams[type].value) result.push(type)}); if (this.paramGroup.queryParams[type].value) result.push(type);
});
return result; return result;
} }
ngOnInit(): void {} ngOnInit(): void {}
ngOnDestroy(): void { ngOnDestroy(): void {
this.componentDestroyed$.next(); this.componentDestroyed$.next();
this.componentDestroyed$.complete(); this.componentDestroyed$.complete();
...@@ -123,39 +172,33 @@ export class SearchInputComponent implements OnInit, OnDestroy { ...@@ -123,39 +172,33 @@ export class SearchInputComponent implements OnInit, OnDestroy {
public onPageChange(page: number): void { public onPageChange(page: number): void {
this.pageParam.setValue(page); this.pageParam.setValue(page);
} }
/* /*
public itemSelected(): void { public itemSelected(): void {
this.searchInputEvent.emit(this.searchInput); this.searchInputEvent.emit(this.searchInput);
} }
*/ */
autoCompleteContributorCreator = (text$: Observable<string>) => autoCompleteContributorCreator = (text$: Observable<string>) =>
text$.pipe( text$.pipe(
debounceTime(200), debounceTime(200),
distinctUntilChanged(), distinctUntilChanged(),
switchMap((searchText) => { switchMap(searchText => {
if(searchText.length <= 2) return []; if (searchText.length <= 2) return [];
return this.searchService.getContributorCreatorAutoComplete( searchText).pipe(map( return this.searchService.getContributorCreatorAutoComplete(searchText).pipe(map(ace => ace.map(ac => ac.target)));
ace => (ace.map(ac => ac.target)) ) ); } })
) );
);
autoCompleteKeyWords = (text$: Observable<string>) =>
autoCompleteKeyWords = (text$: Observable<string>) =>
text$.pipe( text$.pipe(
debounceTime(200), debounceTime(200),
distinctUntilChanged(), distinctUntilChanged(),
switchMap((searchText) => switchMap(searchText => this.searchService.getKeywordsAutoComplete(searchText).pipe(map(ace => ace.map(ac => ac.target))))
this.searchService.getKeywordsAutoComplete( searchText).pipe(map( );
ace => (ace.map(ac => ac.target)) ) ))
);
autoCompleteProgrammingLanguage = (text$: Observable<string>) => autoCompleteProgrammingLanguage = (text$: Observable<string>) =>
text$.pipe( text$.pipe(
debounceTime(200), debounceTime(200),
distinctUntilChanged(), distinctUntilChanged(),
switchMap((searchText) => switchMap(searchText => this.searchService.getProgrammingLanguageAutoComplete(searchText).pipe(map(ace => ace.map(ac => ac.target))))
this.searchService.getProgrammingLanguageAutoComplete( searchText).pipe(map( );
ace => (ace.map(ac => ac.target)) ) ))
);
} }
...@@ -57,11 +57,11 @@ export class SearchComponent implements OnInit { ...@@ -57,11 +57,11 @@ export class SearchComponent implements OnInit {
this.hitCount = searchResultsDTO.hitCount; this.hitCount = searchResultsDTO.hitCount;
// fix string to date conversion: unfortunatelly dates are not converted correctly :-() // fix string to date conversion: unfortunatelly dates are not converted correctly :-()
searchResultsDTO.searchResult.forEach(hit => { searchResultsDTO.searchResult.forEach(hit => {
// eslint-disable-next-line @typescript-eslint/camelcase // eslint-disable-next-line @typescript-eslint/camelcase
hit.project.last_activity_at = new Date(hit.project.last_activity_at); hit.project.last_activity_at = new Date(hit.project.last_activity_at);
// eslint-disable-next-line @typescript-eslint/camelcase // eslint-disable-next-line @typescript-eslint/camelcase
hit.file.indexing_date = new Date(hit.file.indexing_date); hit.file.indexing_date = new Date(hit.file.indexing_date);
}); });
return searchResultsDTO.searchResult.map(this.searchResultToExercise); return searchResultsDTO.searchResult.map(this.searchResultToExercise);
} }
......
/* eslint-disable */
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { HttpClient, HttpParams, HttpResponse } from '@angular/common/http'; import { HttpClient, HttpParams, HttpResponse } from '@angular/common/http';
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
...@@ -69,8 +70,8 @@ export class SearchService { ...@@ -69,8 +70,8 @@ export class SearchService {
params: new HttpParams().set('contributorPrefix', prefix), params: new HttpParams().set('contributorPrefix', prefix),
}); });
} }
getContributorCreatorAutoComplete(prefix: string): Observable<Array<AutoCompletionEntry>> { getContributorCreatorAutoComplete(prefix: string): Observable<Array<AutoCompletionEntry>> {
const options: HttpParams = new HttpParams(); const options: HttpParams = new HttpParams();
options.append('keyWordPrefix', prefix); options.append('keyWordPrefix', prefix);
return this.http.get<Array<AutoCompletionEntry>>(this.resourceContributorCreatorAutoCompleteDetails, { return this.http.get<Array<AutoCompletionEntry>>(this.resourceContributorCreatorAutoCompleteDetails, {
...@@ -85,7 +86,6 @@ export class SearchService { ...@@ -85,7 +86,6 @@ export class SearchService {
params: new HttpParams().set('contributorPrefix', prefix), params: new HttpParams().set('contributorPrefix', prefix),
}); });
} }
} }
export class AutoCompletionEntry { export class AutoCompletionEntry {
......
import { Injectable } from '@angular/core' import { Injectable } from '@angular/core';
/** provides a caching service, with a key, the data and a timeout () /** provides a caching service, with a key, the data and a timeout ()
Warning: Objects are stored as json-Strings. I.e. Dates objects (and others) may not be converted correctly */ Warning: Objects are stored as json-Strings. I.e. Dates objects (and others) may not be converted correctly */
@Injectable() @Injectable()
export class CacheService { export class CacheService {
constructor() { } constructor() {}
save(options: LocalStorageSaveOptions) { save(options: LocalStorageSaveOptions) {
// Set default values for optionals // Set default values for optionals
options.expirationMins = options.expirationMins || 0 options.expirationMins = options.expirationMins || 0;
// Set expiration date in miliseconds // Set expiration date in miliseconds
const expirationMS = options.expirationMins !== 0 ? options.expirationMins * 60 * 1000 : 0 const expirationMS = options.expirationMins !== 0 ? options.expirationMins * 60 * 1000 : 0;
const record = { const record = {
value: typeof options.data === 'string' ? options.data : JSON.stringify(options.data), value: typeof options.data === 'string' ? options.data : JSON.stringify(options.data),
expiration: expirationMS !== 0 ? new Date().getTime() + expirationMS : null, expiration: expirationMS !== 0 ? new Date().getTime() + expirationMS : null,
hasExpiration: expirationMS !== 0 ? true : false hasExpiration: expirationMS !== 0 ? true : false,
} };
localStorage.setItem(options.key, JSON.stringify(record)) localStorage.setItem(options.key, JSON.stringify(record));
} }
load(key: string) { load(key: string) {
// Get cached data from localstorage // Get cached data from localstorage
const item = localStorage.getItem(key) const item = localStorage.getItem(key);
if (item !== null) { if (item !== null) {
const record = JSON.parse(item) const record = JSON.parse(item);
const now = new Date().getTime() const now = new Date().getTime();
// Expired data will return null // Expired data will return null
if (!record || (record.hasExpiration && record.expiration <= now)) { if (!record || (record.hasExpiration && record.expiration <= now)) {
return null return null;
} else { } else {
return JSON.parse(record.value) return JSON.parse(record.value);
} }
}
return null
} }
return null;
}
remove(key: string) { remove(key: string) {
localStorage.removeItem(key) localStorage.removeItem(key);
} }
cleanLocalStorage() { cleanLocalStorage() {
localStorage.clear() localStorage.clear();
} }
} }
export class LocalStorageSaveOptions { export class LocalStorageSaveOptions {
key = ''; key = '';
data: any data: any;
expirationMins?: number expirationMins?: number;
} }
\ No newline at end of file
...@@ -3,19 +3,18 @@ import { HttpClient } from '@angular/common/http'; ...@@ -3,19 +3,18 @@ import { HttpClient } from '@angular/common/http';
import { SERVER_API_URL } from 'app/app.constants'; import { SERVER_API_URL } from 'app/app.constants';
export interface BroadCastMessage { export interface BroadCastMessage {
message: string; message: string;
starts_at: Date; starts_at: Date;
ends_at: Date; ends_at: Date;
color: string; color: string;
font: string; font: string;
id: number; id: number;
active: boolean; // false, active: boolean; // false,
target_path: string; // "*/welcome", target_path: string; // "*/welcome",
broadcast_type: string; // "banner", broadcast_type: string; // "banner",
dismissable: boolean; // false dismissable: boolean; // false
} }
/** /**
...@@ -23,53 +22,43 @@ export interface BroadCastMessage { ...@@ -23,53 +22,43 @@ export interface BroadCastMessage {
*/ */
@Injectable({ providedIn: 'root' }) @Injectable({ providedIn: 'root' })
export class MessageService { export class MessageService {
public messageResourceURL = SERVER_API_URL + 'api/applicationInfo/broadcastMessages';
public messageResourceURL = SERVER_API_URL + 'api/applicationInfo/broadcastMessages'; private messages = new Array<BroadCastMessage>();
private nextUpdate = 0;
private messages = new Array<BroadCastMessage>();;
private nextUpdate = 0;
constructor(protected http: HttpClient,) {
}
public getActiveMessages(): Array<BroadCastMessage> { constructor(protected http: HttpClient) {}
const now = new Date();
return this.getMessages().filter(m =>
((m.starts_at <= now) && (m.ends_at >= now) )
); //
}
public getMessages(): Array<BroadCastMessage> { public getActiveMessages(): Array<BroadCastMessage> {
const now = new Date();
return this.getMessages().filter(m => m.starts_at <= now && m.ends_at >= now); //
}
const now = new Date().getTime(); public getMessages(): Array<BroadCastMessage> {
if (this.nextUpdate > now) { const now = new Date().getTime();
return this.messages; if (this.nextUpdate > now) {
} return this.messages;
}
this.nextUpdate = now + 60*1000; // wait at least 1 Minute for next try this.nextUpdate = now + 60 * 1000; // wait at least 1 Minute for next try
const resp = this.http.get<Array<BroadCastMessage>>(this.messageResourceURL);
const resp = this.http.get<Array<BroadCastMessage>>(this.messageResourceURL);
resp.subscribe( resp.subscribe(response => {
response => { // first convert dates correctly :-(
// first convert dates correctly :-(
response.forEach( m => {
// eslint-disable-next-line @typescript-eslint/camelcase
m.starts_at = new Date(m.starts_at);
// eslint-disable-next-line @typescript-eslint/camelcase
m.ends_at = new Date(m.ends_at);})
// Data will be cached
this.messages = response;
this.nextUpdate = new Date().getTime() + 10*60*1000; // wait 10 Minute for next try
return (response); response.forEach(m => {
} // eslint-disable-next-line @typescript-eslint/camelcase
); m.starts_at = new Date(m.starts_at);
return this.messages; // eslint-disable-next-line @typescript-eslint/camelcase
} m.ends_at = new Date(m.ends_at);
});
// Data will be cached
this.messages = response;
this.nextUpdate = new Date().getTime() + 10 * 60 * 1000; // wait 10 Minute for next try
return response;
});
return this.messages;
}
} }