Skip to content
This repository has been archived by the owner on Apr 24, 2023. It is now read-only.

Commit

Permalink
Merge pull request #1 from KevFan/master
Browse files Browse the repository at this point in the history
INTLY-3042 UI changes to CRUD App
  • Loading branch information
KevFan authored Sep 4, 2019
2 parents 66c3f56 + bb13aed commit ca1c9f6
Show file tree
Hide file tree
Showing 11 changed files with 16,552 additions and 99 deletions.
16 changes: 14 additions & 2 deletions fruit-app/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,21 @@

Very basic CRUD application for fruit

## Running locally
## Local Development Setup

- Install dependencies, `npm install`
- Run the server, `npm run`
- Run the server, `npm start`

When `client.js` has been modified, run `npm run client:build`

Application is then accessible on http://localhost:8080/ if `process.env.PORT` is undefined.

## Building and Running Application in Docker locally

```
docker build -t quay.io/integreatly/fruit-crud-app .
docker run -d --name fruit-crud-app -p 8080:8080 quay.io/integreatly/fruit-crud-app
```

Application is then accessible on http://localhost:8080/

43 changes: 24 additions & 19 deletions fruit-app/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,10 @@ fetch('/api/fruits')
socket.on('fruit', (fruitList) => {
refreshList(fruitList);
});
});
});

const fruitForm = document.getElementById('fruitForm');
fruitForm.addEventListener('submit', handleCreateFruit);

function handleCreateFruit(e) {
e.preventDefault();
Expand All @@ -30,20 +33,32 @@ function handleCreateFruit(e) {
return false;
}

const fruitForm = document.getElementById('fruitForm');
fruitForm.addEventListener('submit', handleCreateFruit);
function refreshList(fruitList) {
const fruitListElem = document.getElementById('fruitList');
const fruitElems = fruitList.map(f => buildFruitElem(f));
// remove existing children
while (!!fruitListElem.firstChild) {
fruitListElem.removeChild(fruitListElem.firstChild);
}
fruitElems.forEach(e => fruitListElem.appendChild(e));
}

function buildFruitElem(fruit) {
const fruitElem = document.createElement('tr');
const fruitIDElem = document.createElement('td');
fruitIDElem.setAttribute('data-label', 'ID');
fruitIDElem.textContent = fruit.id;
const fruitNameElem = document.createElement('td');
fruitNameElem.setAttribute('data-label', 'Name');
fruitNameElem.textContent = fruit.name;
const fruitActionElem = document.createElement('button');
fruitActionElem.className = 'pure-button';
fruitActionElem.style = 'margin: 5px;'
fruitActionElem.textContent = 'Delete';
fruitActionElem.onclick = deleteFruit.bind(null, fruit.id);

const fruitActionElem = document.createElement('td');
fruitActionElem.setAttribute('data-label', 'Actions');
deleteElem = document.createElement('i');
deleteElem.className = 'fa fa-trash';
deleteElem.style = 'font-size:25px;color:#C9190B;'
deleteElem.onclick = deleteFruit.bind(null, fruit.id);
fruitActionElem.appendChild(deleteElem);

fruitElem.appendChild(fruitIDElem);
fruitElem.appendChild(fruitNameElem);
Expand All @@ -56,14 +71,4 @@ function deleteFruit(fruitID) {
fetch(`/api/fruits/${fruitID}`, {
method: 'DELETE'
});
}

function refreshList(fruitList) {
const fruitListElem = document.getElementById('fruitList');
const fruitElems = fruitList.map(f => buildFruitElem(f));
// remove existing children
while (!!fruitListElem.firstChild) {
fruitListElem.removeChild(fruitListElem.firstChild);
}
fruitElems.forEach(e => fruitListElem.appendChild(e));
}
}
7 changes: 6 additions & 1 deletion fruit-app/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion fruit-app/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "fruit-app",
"version": "1.0.1",
"version": "1.0.2",
"description": "Fruit CRUD Application",
"main": "server.js",
"repository": "https://github.com/integr8ly/walkthrough-applications",
Expand All @@ -13,6 +13,7 @@
"openshift:deploy": "oc process -f ./template.json | oc create -f -"
},
"dependencies": {
"@patternfly/patternfly": "^2.27.1",
"express": "^4.17.1",
"socket.io": "^2.2.0",
"swagger-jsdoc": "^3.4.0"
Expand Down
14 changes: 14 additions & 0 deletions fruit-app/public/app.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
footer {
position: fixed;
left: 0;
bottom: 0;
width: 100%;
background-color: #72767B;
color: white;
text-align: center;
}

.middleAlign {
margin: auto;
padding: 10px;
}
42 changes: 23 additions & 19 deletions fruit-app/public/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ fetch('/api/fruits')
socket.on('fruit', (fruitList) => {
refreshList(fruitList);
});
});
});

const fruitForm = document.getElementById('fruitForm');
fruitForm.addEventListener('submit', handleCreateFruit);

function handleCreateFruit(e) {
e.preventDefault();
Expand All @@ -31,20 +34,32 @@ function handleCreateFruit(e) {
return false;
}

const fruitForm = document.getElementById('fruitForm');
fruitForm.addEventListener('submit', handleCreateFruit);
function refreshList(fruitList) {
const fruitListElem = document.getElementById('fruitList');
const fruitElems = fruitList.map(f => buildFruitElem(f));
// remove existing children
while (!!fruitListElem.firstChild) {
fruitListElem.removeChild(fruitListElem.firstChild);
}
fruitElems.forEach(e => fruitListElem.appendChild(e));
}

function buildFruitElem(fruit) {
const fruitElem = document.createElement('tr');
const fruitIDElem = document.createElement('td');
fruitIDElem.setAttribute('data-label', 'ID');
fruitIDElem.textContent = fruit.id;
const fruitNameElem = document.createElement('td');
fruitNameElem.setAttribute('data-label', 'Name');
fruitNameElem.textContent = fruit.name;
const fruitActionElem = document.createElement('button');
fruitActionElem.className = 'pure-button';
fruitActionElem.style = 'margin: 5px;'
fruitActionElem.textContent = 'Delete';
fruitActionElem.onclick = deleteFruit.bind(null, fruit.id);

const fruitActionElem = document.createElement('td');
fruitActionElem.setAttribute('data-label', 'Actions');
deleteElem = document.createElement('i');
deleteElem.className = 'fa fa-trash';
deleteElem.style = 'font-size:25px;color:#C9190B;'
deleteElem.onclick = deleteFruit.bind(null, fruit.id);
fruitActionElem.appendChild(deleteElem);

fruitElem.appendChild(fruitIDElem);
fruitElem.appendChild(fruitNameElem);
Expand All @@ -58,17 +73,6 @@ function deleteFruit(fruitID) {
method: 'DELETE'
});
}

function refreshList(fruitList) {
const fruitListElem = document.getElementById('fruitList');
const fruitElems = fruitList.map(f => buildFruitElem(f));
// remove existing children
while (!!fruitListElem.firstChild) {
fruitListElem.removeChild(fruitListElem.firstChild);
}
fruitElems.forEach(e => fruitListElem.appendChild(e));
}

},{"socket.io-client":36}],2:[function(require,module,exports){
module.exports = after

Expand Down
90 changes: 55 additions & 35 deletions fruit-app/public/index.html
Original file line number Diff line number Diff line change
@@ -1,38 +1,58 @@
<!DOCTYPE html>
<html>
<head>
<title>Fruit List Application</title>
<link rel="stylesheet" href="/pure-min-1.0.1.css" crossorigin="anonymous">
<link rel="stylesheet" href="/style.css" crossorigin="anonymous">
</head>
<body>
<div class="pure-g">
<div class="pure-u-1-3"></div>
<div class="pure-u-1-3">
<h1 style="text-align: center;">Fruit List Application</h1>

<form id="fruitForm" class="pure-form pure-g">
<div class="pure-u-3-4">
<input id="fruitInput" class="pure-input-1" placeholder="Pineapple...">
</div>
<div class="pure-u-1-4">
<button type="submit" class="pure-button pure-button-primary pure-input-1">Create</button>
</div>
</form>

<table style="margin: auto; width: 100%;" class="pure-table">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Actions</th>
</tr>
</thead>
<tbody id="fruitList"></tbody>
</table>
</div>
<div class="pure-u-1-3"></div>
</div>
<script async src="/client.js"></script>
</body>

<head>
<title>Fruit List Application</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">

<link rel="stylesheet" href="/app.css" crossorigin="anonymous">
<link rel="stylesheet" href="/patternfly.css" crossorigin="anonymous">
<link rel="stylesheet" href="/patternfly-addons.css" crossorigin="anonymous">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
</head>

<body class="pf-u-display-flex pf-u-justify-content-center">
<div class="pf-l-stack pf-m-gutter" style="margin: auto; padding: 1em; min-width: 75%;">
<section class="pf-l-stack__item">
<h1 class="pf-c-title pf-m-4xl" style="text-align: center;">
<i class="fa fa-shopping-basket"></i>
Fruit List Application
</h1>
</section>

<section class="pf-l-stack__item">
<form id="fruitForm" novalidate class="pf-c-form">
<div class="pf-c-input-group">
<input class="pf-c-form-control" required id="fruitInput" class="pf-c-form"
placeholder="Pineapple..."></input>
<button class="pf-c-button pf-m-primary" type="submit">
Create
</button>
</div>
</form>
</section>

<section class="pf-l-stack__item pf-m-fill">
<table class="pf-c-table pf-m-grid-md" role="grid" id="frutiTable">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Actions</th>
</tr>
</thead>
<tbody id="fruitList"></tbody>
</table>
</section>
</div>

<script async src="/client.js"></script>
</body>

<footer>
<p class="middleAlign">
<i class="fa fa-info-circle"></i> Basic CRUD application that represents a legacy system.
</p>
</footer>

</html>
Loading

0 comments on commit ca1c9f6

Please sign in to comment.