Commit 057e3023 authored by femiadeyemi's avatar femiadeyemi
Browse files

bit and pieces

- upgrade npm dependencies
- add forms
- little minor fixes
parent bdd4c0e8
This diff is collapsed.
{
"scripts": {
"preinstall": "npx npm-force-resolutions",
"lint:eslint": "eslint --ext .js,.html . --ignore-path .gitignore",
"format:eslint": "eslint --ext .js,.html . --fix --ignore-path .gitignore",
"lint:prettier": "prettier \"**/*.js\" --check --ignore-path .gitignore",
......@@ -14,21 +15,21 @@
"start:build": "npm run build && es-dev-server --root-dir target --app-index index.html --open --compatibility none"
},
"devDependencies": {
"@open-wc/building-rollup": "^1.0.0",
"@open-wc/eslint-config": "^2.0.0",
"@open-wc/testing": "^2.0.0",
"@open-wc/testing-karma": "^4.0.5",
"deepmerge": "^3.2.0",
"es-dev-server": "^1.5.0",
"eslint": "^6.1.0",
"eslint-config-prettier": "^6.11.0",
"husky": "^4.3.0",
"lint-staged": "^10.4.0",
"prettier": "^2.0.4",
"rimraf": "^2.6.3",
"rollup": "^2.3.4",
"rollup-plugin-copy": "^3.3.0",
"sinon": "^9.0.3"
"@open-wc/building-rollup": "1.10.0",
"@open-wc/eslint-config": "^0.3.12",
"@open-wc/testing": "2.5.33",
"@open-wc/testing-karma": "^1.0.2",
"deepmerge": "4.2.2",
"es-dev-server": "2.1.0",
"eslint": "7.29.0",
"eslint-config-prettier": "8.3.0",
"husky": "6.0.0",
"lint-staged": "11.0.0",
"prettier": "2.3.2",
"rimraf": "3.0.2",
"rollup": "2.52.3",
"rollup-plugin-copy": "3.4.0",
"sinon": "9.2.4"
},
"eslintConfig": {
"extends": [
......@@ -57,16 +58,26 @@
"author": "HIFIS Technical Platform Core Team",
"license": "AGPL-3.0",
"dependencies": {
"@material/mwc-button": "0.20.0",
"@material/mwc-fab": "0.20.0",
"@material/mwc-icon-button": "0.20.0",
"@material/mwc-list": "^0.20.0",
"@material/mwc-select": "^0.20.0",
"@material/mwc-textarea": "^0.20.0",
"@material/mwc-textfield": "^0.20.0",
"@material/mwc-button": "0.21.0",
"@material/mwc-fab": "0.21.0",
"@material/mwc-icon-button": "0.21.0",
"@material/mwc-list": "0.21.0",
"@material/mwc-select": "0.21.0",
"@material/mwc-switch": "0.21.0",
"@material/mwc-textarea": "0.21.0",
"@material/mwc-textfield": "0.21.0",
"commonmark": "0.30.0",
"js-cookie": "2.2.1",
"lit-element": "2.3.1",
"lit-html": "1.2.1"
"lit-element": "2.5.1",
"lit-html": "1.4.1"
},
"resolutions": {
"karma-mocha": "2.0.1",
"ua-parser-js": "0.7.28",
"glob-parent": "6.0.0",
"minimist": "1.2.5",
"socket.io": "4.1.2",
"xmlhttprequest-ssl": "2.0.0"
},
"repository": {
"type": "git",
......
......@@ -65,8 +65,8 @@
<properties>
<java.version>11</java.version>
<version.frontend-maven>1.9.1</version.frontend-maven>
<version.node>v12.16.1</version.node>
<version.npm>6.14.2</version.npm>
<version.node>v14.17.1</version.node>
<version.npm>7.19.0</version.npm>
<version.maven-install-plugin>2.5.2</version.maven-install-plugin>
<version.maven-release-plugin>2.5.3</version.maven-release-plugin>
<version.jacoco-maven-plugin>0.8.5</version.jacoco-maven-plugin>
......
......@@ -108,7 +108,7 @@ class HelmholtzCloudFooter extends LitElement
<div class="helmholtz-logo-container">
<img src=${this.backgroundColor ?
`media/i/Helmholtz_white.svg` :
`media/i/helmholtz_blue.svg`}></img>
`media/i/helmholtz_blue.svg`}>
</div>
`
}
......
......@@ -95,7 +95,7 @@ class HelmholtzCloudHeader extends LitElement
<img @click="${this._goToHomepage}"
src=${this.backgroundColor ?
`media/i/helmholtz-cloud_white_font.svg` :
`media/i/helmholtz-cloud_blue_font.svg`}></img>
`media/i/helmholtz-cloud_blue_font.svg`}>
<div class="project-name">Helmholtz Cloud</div>
</div>
<nav class="top-nav">
......
This diff is collapsed.
import {css, html, LitElement} from 'lit-element';
import '@material/mwc-button';
class ImageForm extends LitElement
{
constructor()
{
super();
this.uploadUrl = `${window.CONFIG['cerebrum.endpoint']}images`
}
static get properties()
{
return {
uploadUrl: {
type: String
}
}
}
static get styles()
{
return css`
.hide {
display: none;
}
.result {
display: block;
}
.error {
display: block;
}
.form {
}
`;
}
render()
{
return html`
<span>Add new image</span>
<div class="hide" id="error">${this.errorMessage}</div>
<form class="form" action="${this.uploadUrl}"
enctype="multipart/form-data"
id="form" @submit="${this._upload}">
<div>
<input required id="name" name="name" @input="${this._checkValidity}">
</div>
<div>
<input class="" type="file" name="image" id="image" accept="image/*" @change="${this._checkValidity}">
</div>
<div><input type="submit" value="Upload" id="button" disabled></div>
</form>
<div class="hide" id="result">
<p>Cerebrum is happy with your upload. Here are the details</p>
<div>
<span>metadata</span>
<div>
<code id="metadata"></code>
</div>
<img id="img" width="100px" height="auto">
</div>
<div><button>do you want to add another one</button></div>
</div>
`;
}
_upload(e)
{
e.preventDefault()
console.log(e);
const form = this.shadowRoot.querySelector("#form");
const fileName = form.querySelector("#image").value;
const extention = fileName.split(".").pop()
if (extention !== "svg") {
this.errorMessage = "Only svg file can be uploaded"
this.shadowRoot.querySelector("#error").append("");
return ;
}
const options = {
method: 'POST',
body: new FormData(form),
headers: {
'Authorization': `Bearer ${sessionStorage.getItem("access_token")}`
}
}
fetch(form.action, options)
.then((response) => {
return response.json()
})
.then(json => {
this.shadowRoot.querySelector('#img').src = `data:image/svg+xml;base64,${json["image"]}`;
const newMet = JSON.parse(JSON.stringify(json));
delete newMet["image"];
delete newMet["createdDate"];
delete newMet["lastModifiedDate"];
delete newMet["foreignKeys"];
this.shadowRoot.querySelector('#metadata').append(JSON.stringify(newMet));
this.shadowRoot.querySelector('#error').classList.replace('form', 'hide');
this.shadowRoot.querySelector('#error').classList.replace('error', 'hide')
this.shadowRoot.querySelector('#result').classList.replace('hide', 'result')
}).catch( e=> {
this.errorMessage = e.message;
this.shadowRoot.querySelector('#result').classList.replace('result', 'hide');
this.shadowRoot.querySelector('#error').classList.replace('hide', 'error')
})
return false;
}
_checkValidity(e)
{
console.log(e);
const form = this.shadowRoot.querySelector("#form");
const fileName = form.querySelector("#image").value;
const extension = fileName.split(".").pop()
const name = form.querySelector("#name").value;
if (extension === "svg" && (name !== "" || name !== null)) {
this.shadowRoot.querySelector('#error').classList.replace('error', 'hide')
this.shadowRoot.querySelector('#button').removeAttribute("disabled");
}
if (extension !== "svg" && e.type === "change") {
console.log("extension problem")
this.shadowRoot.querySelector('#button').setAttribute("disabled", true);
}
if ((name === "" || name === null) && e.type === "input") {
console.log("name is empty");
this.shadowRoot.querySelector('#button').setAttribute("disabled", true);
}
}
}
customElements.define('image-form', ImageForm);
\ No newline at end of file
import {css, html, LitElement} from 'lit-element';
class ServiceForm extends LitElement
{
constructor()
{
super();
this.organizations = [];
this.uuids = [];
const headers = new Headers({
"Accept": "application/json"
});
if (sessionStorage.getItem('auth_status')) {
headers.append("Authorization", `Bearer ${sessionStorage.getItem("access_token")}`);
}
fetch(`${window.location.origin}/api/v0/services`, {headers: headers})
.then((response) => {
if (response.status !== 200) {
throw new Error(`Looks like there was a problem. Status Code: ${response.status}`);
}
return response.json();
})
.then(data => {
this.services = data.content;
this.services.forEach(service => {
this.uuids.push(service.uuid)
});
})
.catch(e => console.log(e));
fetch(`${window.location.origin}/api/v0/organizations`, {headers: headers})
.then((response) => {
if (response.status !== 200) {
throw new Error(`Looks like there was a problem. Status Code: ${response.status}`);
}
return response.json();
})
.then(data => {
this.organizations = data.content;
})
.catch(e => console.log(e));
}
static get properties()
{
return {
organizations: {
type: Array
},
services: {
type: Array
},
uuids: {
type: Array
},
currentService: {
type: Object
},
stillCurrentService: {
type: Object
}
}
}
static get styles()
{
return css`
:host {
width: 100%;
height: 100%;
overflow: hidden;
}
header,
main,
footer {
width: 100%;
}
header {
position: fixed;
top: 0;
z-index: 100;
box-sizing: border-box;
border-bottom: 1px solid #274C69;
box-shadow: 0 -2px 8px rgb(0 0 0 / 9%),
0 4px 8px rgb(0 0 0 / 6%),
0 1px 2px rgb(0 0 0 / 30%),
0 2px 6px rgb(0 0 0 / 15%)
}
* {
box-sizing: border-box;
}
main {
display: flex;
padding-top: 50px; /*must be equal to the height of the header*/
width: 100%;
height: 100%;
overflow: hidden;
}
.side-nav {
width: 80px;
height: 100%;
background-color: #fff;
/*background-color: #005aa0;*/
}
.container {
width: calc(100% - 80px);
background-color: #e8e8e8;
padding: 10px;
}
/* css for the form-card and content*/
.form-card {
width: 700px;
height: 100%;
margin: auto;
}
.card-top {
width: 100%;
height: 100px;
display: flex;
justify-content: center;
align-items: center;
}
.card-content {
width: 100%;
height: calc(100% - 100px);
padding: 30px;
overflow-y: scroll;
background-color: #fff;
border: 1px solid #cdcdce;
border-radius: 8px;
}
mwc-select#uuids {
width: 400px;
}
mwc-select, mwc-textfield, mwc-textarea, mwc-button {
width: 100%;
}
mwc-textarea {
height: 150px;
/*max-height: 100px;*/
}
mwc-icon-button {
display: none;
}
mwc-button {
margin-top: 20px;
--mdc-theme-primary: #8cb422;
--mdc-theme-on-primary: white;
}
.row {
border-bottom: 1px solid #cdcdcd;
padding: 40px 0;
}
.editable {
padding: 20px 0;
}
.show {
display: inline-block;
position: absolute;
right: calc(50% - 350px);
color: #005aa0;
--mdc-icon-size: 20px;
}
.no-selection {
text-align: center;
width: 100%;
height: 100%;
display: block;
padding-top: 40%;
}
.warning {
color: red;
font-size: 0.7em;
}
`;
}
render()
{
return html`
<div class="form-card">
<div class="card-top">
<mwc-select id="uuids" outlined label="service uuids" @action="${this._showService}">
<mwc-list-item></mwc-list-item>
${this.uuids.map(uuid =>
html`<mwc-list-item value="${uuid}">${uuid}</mwc-list-item>`)}
</mwc-select>
</div>
<div class="card-content">
${this.movingCurrentService ? html`
<div class="editable row"
@mouseenter="${this._mouseEnter}" @mouseleave="${this._mouseLeave}">
<mwc-textfield id="service-name" disabled required
label="service name" @change="${this._saveServiceName}"
value="${this.movingCurrentService.name}"></mwc-textfield>
<mwc-icon-button icon="edit" @click="${this._edit}"></mwc-icon-button>
</div>
<div class="editable row"
@mouseenter="${this._mouseEnter}" @mouseleave="${this._mouseLeave}">
<mwc-textarea id="summary"
disabled charCounter required maxlength="80" charCounter
label="summary" @change="${this._saveSummary}"
value="${this.movingCurrentService.summary ?
this.movingCurrentService.summary: ''}"></mwc-textarea>
<mwc-icon-button icon="edit" @click="${this._edit}"></mwc-icon-button>
</div>
<div class="editable row"
@mouseenter="${this._mouseEnter}" @mouseleave="${this._mouseLeave}">
<mwc-textarea id="description"
disabled charCounter required
label="service description" @change="${this._saveDescription}"
value="${this.movingCurrentService.description}"></mwc-textarea>
<mwc-icon-button icon="edit" @click="${this._edit}"></mwc-icon-button>
</div>
<div class="editable row"
@mouseenter="${this._mouseEnter}" @mouseleave="${this._mouseLeave}">
<mwc-textfield disabled required id="url"
label="entrypoint" @change="${this._saveUrl}"
value="${this.movingCurrentService.url}"></mwc-textfield>
<mwc-icon-button icon="edit" @click="${this._edit}"></mwc-icon-button>
</div>
<div class="row">
<span> service providers</span>
${this.movingCurrentService["serviceProviders"] ?
html`
${this.movingCurrentService["serviceProviders"].map(provider =>
html`
<div class="editable"
@mouseenter="${this._mouseEnter}" @mouseleave="${this._mouseLeave}">
<mwc-textfield id="software-name"
disabled required
label="software name" @change="${this._saveSoftwareName}"
value="${provider["serviceTechnicalName"]}"></mwc-textfield>
<mwc-icon-button icon="edit" @click="${this._edit}"></mwc-icon-button>
</div>
<mwc-select id="organization"
outlined label="organization" @change="${this._saveOrganisation}">
${this.organizations.map(org =>
html`
<mwc-list-item
value="${org["abbreviation"]}"
?selected="${org["uuid"] === provider["organization"]["uuid"]}">
${org["abbreviation"]}</mwc-list-item>
`
)}
</mwc-select>
`
)}`:
html`
<div><p class="warning">No provider is linked to this service yet</p></div>
<div class="editable"
@mouseenter="${this._mouseEnter}" @mouseleave="${this._mouseLeave}">
<mwc-textfield id="software-name"
disabled required
label="software name" @change="${this._saveSoftwareName}"
value=""></mwc-textfield>
<mwc-icon-button icon="edit" @click="${this._edit}"></mwc-icon-button>
</div>
<mwc-select id="organization" outlined
label="organization" @change="${this._saveOrganisation}">
<mwc-list-item></mwc-list-item>
${this.organizations.map(org =>
html`
<mwc-list-item
value="${org["abbreviation"]}">
${org["abbreviation"]}</mwc-list-item>
`)}
</mwc-select>
`}
</div>
<div>
<mwc-button raised label="update" @click="${this._update}"></mwc-button>
</div>
`: html`
<span class="no-selection">service metadata will be display here</span>
`}
</div>
</div>
`;
}
_update()
{
const headers = new Headers({
"Accept": "application/json",
"Content-Type": "application/json",
"Authorization": `Bearer ${sessionStorage.getItem("access_token")}`
});
const profile = this.stillCurrentService.url !== this.movingCurrentService.url ||
this.stillCurrentService.name !== this.movingCurrentService.name ||
this.stillCurrentService.description !== this.movingCurrentService.description;
const movingProvider = this.movingCurrentService.serviceProviders[0];
let provider;
if (this.stillCurrentService.serviceProviders === null) {
provider = movingProvider.organization["uuid"] && movingProvider.serviceTechnicalName;
} else {
const stillProvider = this.stillCurrentService.serviceProviders[0];
provider = stillProvider.serviceTechnicalName !== movingProvider.serviceTechnicalName ||
stillProvider.organization["uuid"] !== movingProvider.organization["uuid"];
}
console.log('profile', profile);
console.log('provider', provider);
if (sessionStorage.getItem('auth_status')) {
if (profile && provider){
this._updateServiceProfile(headers)
.then((r) => {
console.log('service profile is updated', r);
//change the value inside
this._updateServiceProvider(headers).then((r1)=>{
console.log('service provider is updated', r1);
})
}).catch(e => {console.log(e)});
} else {
if (profile)
this._updateServiceProfile(headers)
.then((r) => {
console.log('service profile is updated', r);
}).catch(e => {
console.log('error when updating a service profile', e)
});
if (provider)
this._updateServiceProvider(headers)
.then((r) => {
console.log('service provider is updated', r);
}).catch(e => {
console.log('error when updating a provider', e)
});
}
} else {
console.log('please login');
}
}
_updateServiceProfile(headers)
{
const cloneService = JSON.parse(JSON.stringify(this.movingCurrentService));
delete cloneService["serviceProviders"];
delete cloneService["managementTeam"];