Skip to content

Commit

Permalink
frontend and docker compose fixes,
Browse files Browse the repository at this point in the history
  • Loading branch information
max402 committed Apr 22, 2024
1 parent 550a01b commit 4c86c72
Show file tree
Hide file tree
Showing 15 changed files with 179 additions and 160 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,4 @@ dist/
cache/

/frontend/datasafe-ui/package-lock.json
/datasafe-rest-impl/ROOT_BUCKET/
2 changes: 1 addition & 1 deletion datasafe-rest-impl/1.createDockerimage.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,4 @@ npm install
ng build --deploy-url /static/ --base-href /static/
mv dist ../../datasafe-rest-impl/target/dist
cd ../../datasafe-rest-impl
docker build . -t datasafe-rest-test:latest --build-arg JAR_FILE=datasafe-rest-impl-*.jar
docker build . -t datasafe-rest-test:latest --build-arg JAR_FILE=datasafe-rest-impl.jar
26 changes: 24 additions & 2 deletions datasafe-rest-impl/DEMO.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,29 @@ To **run** demo:

## Building and running demo

### Building
### Run it with Docker Compose
The easiest way to run Datasafe Rest Application is using Docker Compose. By default, it works with filesystem with root
directory `datasafe-rest-impl/ROOT_BUCKET`.
Build it with:
``` bash
# build backend
mvn clean package

# build frontend
cd frontend/datasafe-ui
npm i
ng build --deploy-url /static/ --base-href /static/
mv dist ../../datasafe-rest-impl/target/dist

# build image and start datasafe in docker
docker compose up datasafe
```

Frontend is available at http://localhost:8080/static/index.html

### Alternatively you can use shell scripts to build and run datasafe with different types of storages

#### Building

- Build from sources

Expand All @@ -34,7 +56,7 @@ cd datasafe-rest-impl
docker pull adorsys/datasafe && docker tag adorsys/datasafe datasafe-rest-test:latest
```

### Running
#### Running

Run using local filesystem, all data will be stored in `target/ROOT_BUCKET` folder:
```bash
Expand Down
6 changes: 4 additions & 2 deletions datasafe-rest-impl/compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,17 @@ services:
datasafe:
build:
args:
JAR_FILE: "datasafe-rest-impl-2.0.2-SNAPSHOT.jar"
JAR_FILE: "datasafe-rest-impl.jar"
# image: adorsys/datasafe
environment:
EXPOSE_API_CREDS: true
DEFAULT_USER: username
DEFAULT_PASSWORD: password
USE_FILESYSTEM: file:///Users/max/Desktop/datasafe
USE_FILESYSTEM: file:///usr/app/ROOT_BUCKET
ports:
- 8080:8080
volumes:
- "./ROOT_BUCKET:/usr/app/ROOT_BUCKET"
db:
image: mysql:5.7
restart: always
Expand Down
1 change: 0 additions & 1 deletion datasafe-rest-impl/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,6 @@
<activeByDefault>true</activeByDefault>
</activation>
<build>
<finalName>${project.artifactId}-${project.version}</finalName>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
Expand Down
2 changes: 1 addition & 1 deletion datasafe-rest-impl/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ if [[ -z "$API_URL" ]]; then
fi

# Bind API url and credentials, sed -i won't work because of OC user permissions
sed 's!${API_URL}!'"$API_URL"'!g' "$APP_HOME/frontend/env.js" > /tmp/env.js && mv /tmp/env.js "$APP_HOME/frontend/env.js"
sed 's!${API_URL}!'"$API_URL"'!g' "$APP_HOME/frontend/env.prod.js" > /tmp/env.js && mv /tmp/env.js "$APP_HOME/frontend/env.js"

# do not expose sensitive data by default
LOGIN=""
Expand Down
29 changes: 13 additions & 16 deletions frontend/datasafe-ui/src/app/app.component.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
import {Component, OnInit} from '@angular/core';
import {ErrorStateMatcher} from "@angular/material/core";
import {FormControl, FormGroupDirective, NgForm} from "@angular/forms";
import {Component} from '@angular/core';
import {ErrorStateMatcher} from '@angular/material/core';
import {FormControl, FormGroupDirective, NgForm} from '@angular/forms';

export class Env {

// Read environment variables from browser window
private static browserWindow = window || {};
private static browserWindowEnv = Env.browserWindow['__env'] || {};

static apiUrl = Env.get('apiUrl');
static apiUsername = Env.get('apiUsername');
static apiPassword = Env.get('apiPassword');

static get(key): string {
if (this.browserWindowEnv.hasOwnProperty(key)) {
return window['__env'][key];
}

return null;
}

static apiUrl = Env.get('apiUrl');
static apiUsername = Env.get('apiUsername');
static apiPassword = Env.get('apiPassword');
}

export class FieldErrorStateMatcher implements ErrorStateMatcher {
Expand All @@ -30,8 +30,8 @@ export class FieldErrorStateMatcher implements ErrorStateMatcher {

export class ParentOrFieldErrorStateMatcher implements ErrorStateMatcher {
isErrorState(control: FormControl | null, form: FormGroupDirective | NgForm | null): boolean {
const invalidCtrl = !!(control && control.invalid && control.parent.dirty);
const invalidParent = !!(control && control.parent && control.parent.invalid && control.parent.dirty);
const invalidCtrl = !!(control?.invalid && control?.parent?.dirty);
const invalidParent = !!(control?.parent?.invalid && control?.parent?.dirty);

return (invalidCtrl || invalidParent);
}
Expand All @@ -40,12 +40,12 @@ export class ParentOrFieldErrorStateMatcher implements ErrorStateMatcher {
export class ErrorMessageUtil {

static extract(error): string {
let errMsg = "Failed " + error.message;
if (error && error.error && error.error.message) {
let errMsg = 'Failed ' + error.message;
if (error?.error?.message) {
errMsg = error.error.message;
}

return errMsg.substring(0, 32) + (errMsg.length >= 32 ? "..." : "");
return errMsg.substring(0, 32) + (errMsg.length >= 32 ? '...' : '');
}
}

Expand All @@ -54,10 +54,7 @@ export class ErrorMessageUtil {
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
export class AppComponent {

constructor() { }

ngOnInit() {
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@ import {FlatTreeControl} from '@angular/cdk/tree';
import {Component, Inject, Injectable} from '@angular/core';
import {BehaviorSubject, merge, Observable} from 'rxjs';
import {map} from 'rxjs/operators';
import {ApiService} from "../../service/api/api.service";
import {CredentialsService} from "../../service/credentials/credentials.service";
import {Router} from "@angular/router";
import {ErrorMessageUtil} from "../../app.component";
import {MAT_DIALOG_DATA, MatDialog, MatDialogRef} from "@angular/material/dialog";
import {ApiService} from '../../service/api/api.service';
import {CredentialsService} from '../../service/credentials/credentials.service';
import {Router} from '@angular/router';
import {ErrorMessageUtil} from '../../app.component';
import {MAT_DIALOG_DATA, MatDialog, MatDialogRef} from '@angular/material/dialog';

class UserFileSystem {

Expand All @@ -19,43 +19,43 @@ class UserFileSystem {
this.fs.clear();

// maintain consistent order
files.concat(Array.from(this.uiCreatedFolders).map(it => it + "/"))
files.concat(Array.from(this.uiCreatedFolders).map(it => it + '/'))
.sort()
.forEach(it => this.addEntry(it));
}

rootLevelNodes() : string[] {
let res = new Set<string>();
rootLevelNodes(): string[] {
const res = new Set<string>();

this.fs.forEach((value, key) => {
let split = key.split("/", 2);
res.add(split[0] + (split.length > 1 ? "/" : ""));
const split = key.split('/', 2);
res.add(split[0] + (split.length > 1 ? '/' : ''));
});

return Array.from(res)
return Array.from(res);
}

private addEntry(path: string) {

var fullPath = "";
var folder = "";
let fullPath = '';
let folder = '';
path = (path.startsWith('/')) ? path.substring(1) : path;
path.split("/").forEach(segment => {
path.split('/').forEach(segment => {
fullPath += segment;
fullPath += (fullPath === path ? "" : "/");
fullPath += (fullPath === path ? '' : '/');

let name = (((fullPath === path) && (!path.endsWith("/"))) ? segment : segment + "/");
const name = (((fullPath === path) && (!path.endsWith('/'))) ? segment : segment + '/');
this.putToFolder(folder, name);
folder = fullPath
})
folder = fullPath;
});
}

private putToFolder(folder: string, name: string) {
if ("" === name || "/" === name) {
if ('' === name || '/' === name) {
name = null;
}

if (folder === "") {
if (folder === '') {
folder = name;
name = null;
}
Expand All @@ -76,15 +76,15 @@ export class DynamicFlatNode {
isLoading: boolean;

constructor(path: string) {
let level = path.split("/").length - 1;
if (path.endsWith("/")) {
let level = path.split('/').length - 1;
if (path.endsWith('/')) {
level = level - 1;
}

this.name = path.replace(/\/$/, "").match(/(.+\/)*([^\/]+)$/)[2];
this.name = path.replace(/\/$/, '').match(/(.+\/)*([^\/]+)$/)[2];
this.path = path;
this.level = level;
this.expandable = path.endsWith("/");
this.expandable = path.endsWith('/');
}
}

Expand All @@ -93,7 +93,7 @@ export class DynamicDatabase {
storageTree = new UserFileSystem();

loadData(api: ApiService, creds: CredentialsService, filetreeComponent: FiletreeComponent, router: Router) {
api.listDocuments("", creds.getCredentialsForApi())
api.listDocuments('', creds.getCredentialsForApi())
.then(res => {
this.storageTree.buildFs(<Array<string>> res);

Expand All @@ -111,22 +111,22 @@ export class DynamicDatabase {
}

rebuildView(filetreeComponent: FiletreeComponent) {
let paths = this.memoizedFs();
const paths = this.memoizedFs();

this.storageTree.buildFs(Array.from(paths));
filetreeComponent.dataSource.data = this.storageTree.rootLevelNodes()
.map(path => new DynamicFlatNode(path));
}

private memoizedFs() {
let paths = new Set<string>();
const paths = new Set<string>();
this.storageTree.fs.forEach((values, key) => {
paths.add(key);
values.forEach(file => {
if (null != file) {
paths.add(key + file);
}
})
});
});
return paths;
}
Expand Down Expand Up @@ -158,7 +158,7 @@ export class DynamicDataSource {
}

private keepExpandedNodesState() {
let toExpand = new Set<string>(this.expandedMemoize);
const toExpand = new Set<string>(this.expandedMemoize);
let expanded = false;
do {
expanded = false;
Expand All @@ -169,7 +169,7 @@ export class DynamicDataSource {
expanded = true;
toExpand.delete(node.path);
});
} while (toExpand.size != 0 && expanded);
} while (toExpand.size !== 0 && expanded);
}

constructor(private treeControl: FlatTreeControl<DynamicFlatNode>,
Expand Down Expand Up @@ -254,10 +254,10 @@ export class FiletreeComponent {

treeControl: FlatTreeControl<DynamicFlatNode>;
dataSource: DynamicDataSource;
error: any;
getLevel = (node: DynamicFlatNode) => node.level;
isExpandable = (node: DynamicFlatNode) => node.expandable;
hasChild = (_: number, _nodeData: DynamicFlatNode) => _nodeData.expandable;
error: any;

constructor(private database: DynamicDatabase, private api: ApiService, private creds: CredentialsService,
private router: Router, public dialog: MatDialog) {
Expand All @@ -270,19 +270,19 @@ export class FiletreeComponent {
addUiFolderWithPath(path: string) {
const dialogRef = this.dialog.open(AddFolderDialog, {
width: '250px',
data: {folderPath: ""}
data: {folderPath: ''}
});

dialogRef.afterClosed().subscribe(result => {
if (result !== undefined) {
this.database.storageTree.uiCreatedFolders.add("" !== path ? path + result : result);
this.database.storageTree.uiCreatedFolders.add('' !== path ? path + result : result);
this.database.rebuildView(this);
}
});
}

addUiFolder() {
this.addUiFolderWithPath("");
this.addUiFolderWithPath('');
}

addUiFolderWithpathFromName(event) {
Expand All @@ -308,8 +308,8 @@ export class FiletreeComponent {
}

private removePathFromUiCreatedFolders(path: string) {
let pathPrefix = path.replace(/\/$/, "");
let toRemove = Array.from(this.database.storageTree.uiCreatedFolders)
const pathPrefix = path.replace(/\/$/, '');
const toRemove = Array.from(this.database.storageTree.uiCreatedFolders)
.filter(it => it.startsWith(pathPrefix));
toRemove.forEach(remove => this.database.storageTree.uiCreatedFolders.delete(remove));
}
Expand Down
Loading

0 comments on commit 4c86c72

Please sign in to comment.