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 @@
<attribute name="maven.pomderived" value="true"/>
</attributes>
</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">
<attributes>
<attribute name="maven.pomderived" value="true"/>
......@@ -19,20 +13,19 @@
</classpathentry>
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
<attributes>
<attribute name="test" value="true"/>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
<attribute name="test" value="true"/>
</attributes>
</classpathentry>
<classpathentry excluding="**" kind="src" output="target/test-classes" path="src/test/resources">
<attributes>
<attribute name="test" value="true"/>
<attribute name="maven.pomderived" value="true"/>
<attribute name="test" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-11">
<attributes>
<attribute name="module" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
......@@ -41,5 +34,22 @@
<attribute name="maven.pomderived" value="true"/>
</attributes>
</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"/>
</classpath>
......@@ -32,6 +32,7 @@ tmp/**/*
local.properties
.loadpath
.factorypath
.settings/org.eclipse.jdt.apt.core.prefs
# CDT-specific
......
......@@ -39,4 +39,15 @@
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.m2e.core.maven2Nature</nature>
</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>
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
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.problem.forbiddenReference=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.source=11
......@@ -20,6 +20,7 @@ import org.springframework.util.StreamUtils;
import org.springframework.util.StringUtils;
import at.ac.uibk.gitsearch.repository.gitlab.GitLabRepository;
import at.ac.uibk.gitsearch.security.jwt.TokenProvider;
/**
* Service for exercise/course search results
......@@ -30,14 +31,16 @@ public class GitlabService {
@Autowired
private GitLabRepository gitLabRepository;
@Autowired
protected TokenProvider tokenProvider;
private final Logger log = LoggerFactory.getLogger(ShoppingBasketService.class);
public Boolean repositoryExists(String projectID) {
final GitLabApi gitLabApi = gitLabRepository.getGitLabApi();
final ProjectApi gitLabProjectApi = gitLabApi.getProjectApi();
try{
final GitLabApi gitLabApi = gitLabRepository.getGitLabApi(tokenProvider.getGitLabAccessInfo());
final ProjectApi gitLabProjectApi = gitLabApi.getProjectApi();
return gitLabProjectApi.getProject(projectID) != null;}
catch(GitLabApiException e){
log.error(e.getMessage(), e);
......@@ -48,7 +51,7 @@ public class GitlabService {
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);
}
......
......@@ -244,8 +244,8 @@ public class SearchService {
return copyInputStreamToFile(inputFile, file);}
catch(GitLabApiException exception){
log.error(exception.getMessage());
return null;
}
return null;
}
private File copyInputStreamToFile(InputStream inputStream, File file) throws IOException {
......
......@@ -163,7 +163,7 @@ public class StatisticsResource {
return ResponseUtil.wrapOrNotFound(statisticsDTO);
}
else{
return null;
return ResponseUtil.wrapOrNotFound(statisticsDTO);
}
}
......
......@@ -74,7 +74,6 @@ spring:
client-id: ${SECURITY_OAUTH2_CLIENT_REGISTRATION_GITLABOIDC_CLIENTID}
client-secret: ${SECURITY_OAUTH2_CLIENT_REGISTRATION_GITLABOIDC_CLIENTSECRET}
# ===================================================================
# To enable TLS in production, generate a certificate using:
# keytool -genkey -alias gitsearch -storetype PKCS12 -keyalg RSA -keysize 2048 -keystore keystore.p12 -validity 3650
......@@ -154,7 +153,7 @@ jhipster:
application:
registeredPlugins:
- "https://artemis.codeability.uibk.ac.at/api/sharing/config"
- 'https://artemis.codeability.uibk.ac.at/api/sharing/config'
gitlab:
url: https://sharing-codeability.uibk.ac.at/
generalAccessToken: ${APPLICATION_GITLAB_GENERALACCESSTOKEN}
url: https://sharing-codeability.uibk.ac.at/
generalAccessToken: ${APPLICATION_GITLAB_GENERALACCESSTOKEN}
......@@ -42,9 +42,9 @@ export class HealthComponent implements OnInit {
const modalRef = this.modalService.open(HealthModalComponent);
modalRef.componentInstance.health = health;
}
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);
}
}
}
......@@ -16,7 +16,7 @@ import { PageRibbonComponent } from './layouts/profiles/page-ribbon.component';
import { ActiveMenuDirective } from './layouts/navbar/active-menu.directive';
import { ErrorComponent } from './layouts/error/error.component';
import { QueryParamModule } from '@ngqp/core';
import { CacheService } from 'app/shared/service/cache.service'
import { CacheService } from 'app/shared/service/cache.service';
@NgModule({
imports: [
......@@ -30,17 +30,8 @@ import { CacheService } from 'app/shared/service/cache.service'
GitSearchV2AppRoutingModule,
QueryParamModule,
],
declarations: [
MainComponent,
NavbarComponent,
ErrorComponent,
PageRibbonComponent,
ActiveMenuDirective,
FooterComponent],
declarations: [MainComponent, NavbarComponent, ErrorComponent, PageRibbonComponent, ActiveMenuDirective, FooterComponent],
bootstrap: [MainComponent],
providers: [
CacheService,
]
providers: [CacheService],
})
export class GitSearchV2AppModule {}
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable, } from 'rxjs';
import { Observable } from 'rxjs';
import { SERVER_API_URL } from 'app/app.constants';
export class DeploymentInfo {
branch = "";
commitId = "";
branch = '';
commitId = '';
}
@Injectable({ providedIn: 'root' })
export class ApplicationInfoService {
cachedDeploymentInfo: DeploymentInfo;
inLoading = false;
constructor(
private http: HttpClient,
) {
this.cachedDeploymentInfo = {} as DeploymentInfo;
}
constructor(private http: HttpClient) {
this.cachedDeploymentInfo = {} as DeploymentInfo;
}
private loadDeploymentInfo(): Observable<DeploymentInfo> {
return this.http.get<DeploymentInfo>(SERVER_API_URL + 'api/applicationInfo/deploymentInfo');
}
public getDeploymentInfo(): DeploymentInfo {
if(!this.cachedDeploymentInfo.branch && !this.inLoading) {
this.inLoading = true;
this.loadDeploymentInfo().subscribe((res) => {
this.cachedDeploymentInfo = res;
this.inLoading = false;
});
if (!this.cachedDeploymentInfo.branch && !this.inLoading) {
this.inLoading = true;
this.loadDeploymentInfo().subscribe(res => {
this.cachedDeploymentInfo = res;
this.inLoading = false;
});
}
return this.cachedDeploymentInfo;
}
}
}
......@@ -26,7 +26,7 @@ export class ExerciseCardComponent implements OnInit {
this.exercise!.views = data.views!;
this.exercise!.downloads = data.downloads!;
},
() => alert('Request failed')
() => alert('Could not load exercise statistics')
);
}
this.exerciseSelectionEvent.emit(this.exercise);
......
......@@ -5,8 +5,6 @@ import { Subscription } from 'rxjs';
import { PluginActionInfo } from 'app/shared/model/search/search-result-dto.model';
import { PluginService } from 'app/shared/service/plugin-service';
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 { Account } from 'app/core/user/account.model';
import { SearchService } from 'app/search/service/search-service.ts';
......@@ -51,7 +49,7 @@ export class ExerciseDetailsComponent implements OnInit, OnDestroy {
}
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 {
......@@ -71,22 +69,21 @@ export class ExerciseDetailsComponent implements OnInit, OnDestroy {
return result;
}
public startAction(action: PluginActionInfo, exercise: Exercise): void {
const basketInfo: ShoppingBasketInfo = {
plugin: action.plugin,
action: action.action,
itemInfos: [
exercise.originalResult
]
};
this.pluginService.getRedirectLink(basketInfo).subscribe(
(redirectInfo: ShoppingBasketRedirectInfoDTO) => {
// alert('redirecting to ' + redirectInfo.redirectURL);
// location.href = redirectInfo.redirectURL;
window.open(redirectInfo.redirectURL, action.action);
},
() => alert('Search failed'))
}
public startAction(action: PluginActionInfo, exercise: Exercise): void {
const basketInfo: ShoppingBasketInfo = {
plugin: action.plugin,
action: action.action,
itemInfos: [exercise.originalResult],
};
this.pluginService.getRedirectLink(basketInfo).subscribe(
(redirectInfo: ShoppingBasketRedirectInfoDTO) => {
// alert('redirecting to ' + redirectInfo.redirectURL);
// location.href = redirectInfo.redirectURL;
window.open(redirectInfo.redirectURL, action.action);
},
() => alert('Search failed')
);
}
public download(): void {
this.exportExercise(Number(this.exercise!.originalResult.project.project_id));
......@@ -107,7 +104,7 @@ export class ExerciseDetailsComponent implements OnInit, OnDestroy {
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';
import { AccountService } from 'app/core/auth/account.service';
import { AuthServerProvider } from 'app/core/auth/auth-jwt.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';
@Component({
......@@ -24,9 +24,8 @@ export class MainComponent implements OnInit {
rootRenderer: RendererFactory2,
private authServerProvider: AuthServerProvider,
private cookieService: CookieService,
private messageService: MessageService,
) // private alertErrorComponent: AlertErrorComponent
{
private messageService: MessageService // private alertErrorComponent: AlertErrorComponent
) {
this.renderer = rootRenderer.createRenderer(document.querySelector('html'), null);
}
......@@ -50,11 +49,10 @@ export class MainComponent implements OnInit {
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 {
const tokenCookie = this.cookieService.get('tempRequestToken');
......
......@@ -4,16 +4,16 @@ import { ActivatedRoute, Router } from '@angular/router';
import { QueryParam, QueryParamBuilder, QueryParamGroup } from '@ngqp/core';
import { takeUntil } from 'rxjs/operators';
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 {Observable} from 'rxjs';
import {debounceTime, distinctUntilChanged, map, switchMap} from 'rxjs/operators';
import { Observable } from 'rxjs';
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 {
[key: string]: any
[key: string]: any;
}
@Component({
......@@ -26,9 +26,9 @@ export class SearchInputComponent implements OnInit, OnDestroy {
@Output() searchInputEvent = new EventEmitter<SearchInput>();
public pageSize = 4;
typeValues = Object.keys(IExerciseType);
questionIcon = faQuestion;
public paramGroup: QueryParamGroup;
private componentDestroyed$ = new Subject<void>();
......@@ -37,15 +37,67 @@ export class SearchInputComponent implements OnInit, OnDestroy {
public showSearchUsage = false;
private states = ['Alabama', 'Alaska', 'American Samoa', 'Arizona', 'Arkansas', 'California', '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'];
private states = [
'Alabama',
'Alaska',
'American Samoa',
'Arizona',
'Arkansas',
'California',
'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(
protected activatedRoute: ActivatedRoute,
......@@ -80,17 +132,15 @@ export class SearchInputComponent implements OnInit, OnDestroy {
emptyOn: '',
}),
};
// add type checkbox support
this.typeValues.forEach(
function(type: string): void {
const typeName = type.toString();
groupDef[typeName] = qpb.stringParam(typeName, {
debounceTime: SearchInputComponent.DEBOUNCE_TIME,
emptyOn: '',
});
}
);
this.typeValues.forEach(function (type: string): void {
const typeName = type.toString();
groupDef[typeName] = qpb.stringParam(typeName, {
debounceTime: SearchInputComponent.DEBOUNCE_TIME,
emptyOn: '',
});
});
this.paramGroup = qpb.group(groupDef);
......@@ -98,19 +148,18 @@ export class SearchInputComponent implements OnInit, OnDestroy {
this.searchInput.setValues(value);
this.searchInputEvent.emit(this.searchInput);
});
}
getSelectedTypes(): string[] {
const result: string[] = [];
this.typeValues.forEach(
type => {if(this.paramGroup.queryParams[type].value) result.push(type)});
this.typeValues.forEach(type => {
if (this.paramGroup.queryParams[type].value) result.push(type);
});
return result;
}
}
ngOnInit(): void {}
ngOnDestroy(): void {
this.componentDestroyed$.next();
this.componentDestroyed$.complete();
......@@ -123,39 +172,33 @@ export class SearchInputComponent implements OnInit, OnDestroy {
public onPageChange(page: number): void {
this.pageParam.setValue(page);
}
/*
/*
public itemSelected(): void {
this.searchInputEvent.emit(this.searchInput);
}
*/
autoCompleteContributorCreator = (text$: Observable<string>) =>
autoCompleteContributorCreator = (text$: Observable<string>) =>
text$.pipe(
debounceTime(200),
distinctUntilChanged(),
switchMap((searchText) => {
if(searchText.length <= 2) return [];
return this.searchService.getContributorCreatorAutoComplete( searchText).pipe(map(
ace => (ace.map(ac => ac.target)) ) ); }
)
);
autoCompleteKeyWords = (text$: Observable<string>) =>
switchMap(searchText => {
if (searchText.length <= 2) return [];
return this.searchService.getContributorCreatorAutoComplete(searchText).pipe(map(ace => ace.map(ac => ac.target)));
})
);
autoCompleteKeyWords = (text$: Observable<string>) =>
text$.pipe(
debounceTime(200),
distinctUntilChanged(),
switchMap((searchText) =>
this.searchService.getKeywordsAutoComplete( searchText).pipe(map(
ace => (ace.map(ac => ac.target)) ) ))
);
switchMap(searchText => this.searchService.getKeywordsAutoComplete(searchText).pipe(map(ace => ace.map(ac => ac.target))))
);
autoCompleteProgrammingLanguage = (text$: Observable<string>) =>
autoCompleteProgrammingLanguage = (text$: Observable<string>) =>
text$.pipe(
debounceTime(200),
distinctUntilChanged(),
switchMap((searchText) =>
this.searchService.getProgrammingLanguageAutoComplete( searchText).pipe(map(
ace => (ace.map(ac => ac.target)) ) ))
);
switchMap(searchText => this.searchService.getProgrammingLanguageAutoComplete(searchText).pipe(map(ace => ace.map(ac => ac.target))))
);
}
......@@ -57,11 +57,11 @@ export class SearchComponent implements OnInit {
this.hitCount = searchResultsDTO.hitCount;
// fix string to date conversion: unfortunatelly dates are not converted correctly :-()
searchResultsDTO.searchResult.forEach(hit => {
// eslint-disable-next-line @typescript-eslint/camelcase
hit.project.last_activity_at = new Date(hit.project.last_activity_at);
// eslint-disable-next-line @typescript-eslint/camelcase
hit.file.indexing_date = new Date(hit.file.indexing_date);
});
// eslint-disable-next-line @typescript-eslint/camelcase
hit.project.last_activity_at = new Date(hit.project.last_activity_at);
// eslint-disable-next-line @typescript-eslint/camelcase
hit.file.indexing_date = new Date(hit.file.indexing_date);
});
return searchResultsDTO.searchResult.map(this.searchResultToExercise);
}
......
/* eslint-disable */
import { Injectable } from '@angular/core';
import { HttpClient, HttpParams, HttpResponse } from '@angular/common/http';
import { Observable } from 'rxjs';
......@@ -69,8 +70,8 @@ export class SearchService {
params: new HttpParams().set('contributorPrefix', prefix),
});
}
getContributorCreatorAutoComplete(prefix: string): Observable<Array<AutoCompletionEntry>> {
getContributorCreatorAutoComplete(prefix: string): Observable<Array<AutoCompletionEntry>> {
const options: HttpParams = new HttpParams();
options.append('keyWordPrefix', prefix);
return this.http.get<Array<AutoCompletionEntry>>(this.resourceContributorCreatorAutoCompleteDetails, {
......@@ -85,7 +86,6 @@ export class SearchService {
params: new HttpParams().set('contributorPrefix', prefix),
});
}
}
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 ()
Warning: Objects are stored as json-Strings. I.e. Dates objects (and others) may not be converted correctly */
@Injectable()
export class CacheService {
constructor() { }
save(options: LocalStorageSaveOptions) {
// Set default values for optionals
options.expirationMins = options.expirationMins || 0
// Set expiration date in miliseconds
const expirationMS = options.expirationMins !== 0 ? options.expirationMins * 60 * 1000 : 0
const record = {
value: typeof options.data === 'string' ? options.data : JSON.stringify(options.data),
expiration: expirationMS !== 0 ? new Date().getTime() + expirationMS : null,
hasExpiration: expirationMS !== 0 ? true : false
}
localStorage.setItem(options.key, JSON.stringify(record))
}
load(key: string) {
// Get cached data from localstorage
const item = localStorage.getItem(key)
if (item !== null) {
const record = JSON.parse(item)
const now = new Date().getTime()
// Expired data will return null
if (!record || (record.hasExpiration && record.expiration <= now)) {
return null
} else {
return JSON.parse(record.value)
}
}
return null
constructor() {}
save(options: LocalStorageSaveOptions) {
// Set default values for optionals
options.expirationMins = options.expirationMins || 0;
// Set expiration date in miliseconds
const expirationMS = options.expirationMins !== 0 ? options.expirationMins * 60 * 1000 : 0;
const record = {
value: typeof options.data === 'string' ? options.data : JSON.stringify(options.data),
expiration: expirationMS !== 0 ? new Date().getTime() + expirationMS : null,
hasExpiration: expirationMS !== 0 ? true : false,
};
localStorage.setItem(options.key, JSON.stringify(record));
}
load(key: string) {
// Get cached data from localstorage
const item = localStorage.getItem(key);
if (item !== null) {
const record = JSON.parse(item);
const now = new Date().getTime();
// Expired data will return null
if (!record || (record.hasExpiration && record.expiration <= now)) {
return null;
} else {
return JSON.parse(record.value);
}
}
return null;
}
remove(key: string) {
localStorage.removeItem(key)
}
remove(key: string) {
localStorage.removeItem(key);
}
cleanLocalStorage() {
localStorage.clear()
}
cleanLocalStorage() {
localStorage.clear();
}
}
export class LocalStorageSaveOptions {
key = '';
data: any
expirationMins?: number
}
\ No newline at end of file
key = '';
data: any;
expirationMins?: number;
}
......@@ -3,19 +3,18 @@ import { HttpClient } from '@angular/common/http';
import { SERVER_API_URL } from 'app/app.constants';
export interface BroadCastMessage {
message: string;
starts_at: Date;
ends_at: Date;
color: string;
font: string;
id: number;
active: boolean; // false,
target_path: string; // "*/welcome",
broadcast_type: string; // "banner",
dismissable: boolean; // false
message: string;
starts_at: Date;
ends_at: Date;
color: string;
font: string;
id: number;
active: boolean; // false,
target_path: string; // "*/welcome",
broadcast_type: string; // "banner",
dismissable: boolean; // false
}
/**
......@@ -23,53 +22,43 @@ export interface BroadCastMessage {
*/
@Injectable({ providedIn: 'root' })
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;
constructor(protected http: HttpClient,) {
}
private messages = new Array<BroadCastMessage>();
private nextUpdate = 0;
public getActiveMessages(): Array<BroadCastMessage> {
const now = new Date();
return this.getMessages().filter(m =>
((m.starts_at <= now) && (m.ends_at >= now) )
); //
}
constructor(protected http: HttpClient) {}
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();
if (this.nextUpdate > now) {
return this.messages;
}
public getMessages(): Array<BroadCastMessage> {
const now = new Date().getTime();
if (this.nextUpdate > now) {
return this.messages;
}
this.nextUpdate = now + 60*1000; // wait at least 1 Minute for next try
const resp = this.http.get<Array<BroadCastMessage>>(this.messageResourceURL);
this.nextUpdate = now + 60 * 1000; // wait at least 1 Minute for next try
const resp = this.http.get<Array<BroadCastMessage>>(this.messageResourceURL);
resp.subscribe(
response => {
// 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
resp.subscribe(response => {
// first convert dates correctly :-(
return (response);
}
);
return this.messages;
}
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;
});
return this.messages;
}
}