Forgot to commit as I developed, component search works, reading dynamic parameters from json blob works, calculation work is on-going

master
willd 1 year ago
parent 40f8263006
commit 54503e69f5

@ -65,21 +65,22 @@ def serveImage(img):
img_io.seek(0)
return send_file(img_io, mimetype='image/png')
@app.route('/parts', strict_slashes=True)
@app.route('/', strict_slashes=True)
def index():
return render_template('partsearch.html', containers=getContainers())
@app.route('/parts/getlocationsInContainer/<containerID>')
def get_locations_in_container(containerID):
s = 'select id, name from locations where container_id = :id order by name;'
r = db_engine.execute(text(s), id=containerID)
@app.route('/getTypes')
def get_locations_in_container():
s = 'select id, name from containers order by name;'
r = db_engine.execute(text(s))
l={}
for row in r:
l[row[0]]= row[1];
r.close()
print(json.dumps(l))
return json.dumps(l)
@app.route('/parts/getlocationURL/<locationID>')
@app.route('/getlocationURL/<locationID>')
def get_locationURL(locationID):
s = 'select map from locations where id = :id;'
r = db_engine.execute(text(s), id=locationID)
@ -89,7 +90,7 @@ def get_locationURL(locationID):
r.close()
return l[0][0]
@app.route('/parts/locationEditor')
@app.route('/locationEditor')
def locationEditor():
query = 'select c.name as container, l.name as name, l.id, c.id as container_id from locations as l inner join containers as c on l.container_id = c.id order by container, name;'
r = db_engine.execute(text(query))
@ -99,7 +100,7 @@ def locationEditor():
r.close()
return render_template('locationEditor.html', locations=locations, containers=getContainers())
@app.route('/parts/alterLocation/<locationID>', methods=['POST'])
@app.route('/alterLocation/<locationID>', methods=['POST'])
@requires_auth
def alterLocation(locationID):
locationID = int(locationID)
@ -122,9 +123,9 @@ def alterLocation(locationID):
r.close()
return '{"status":"ok"}'
@app.route('/parts/getpartinfo/<partID>')
@app.route('/getpartinfo/<partID>')
def get_part_info(partID):
s = 'select p.id,partno,description,notes, c.name || l.name as location_descriptor, location_id, container_id, datasheet from parts as p inner join locations as l on p.location_id = l.id inner join containers as c on l.container_id = c.id where p.id = :id;'
s = 'select p.id,partno,description,notes,parameters,c.name as type_descriptor, type_id, datasheet from parts as p inner join containers as c on p.type_id = c.type where p.id = :id;'
r = db_engine.execute(text(s), id=partID)
l = []
for row in r:
@ -132,7 +133,7 @@ def get_part_info(partID):
r.close()
return json.dumps(l[0])
@app.route('/parts/query/<filter_dummy>/<query>') # TODO: maybe change AND to OR or maybe not
@app.route('/query/<filter_dummy>/<query>') # TODO: maybe change AND to OR or maybe not
def query(filter_dummy, query):
filter = request.args.to_dict()
keywords = query.split() # Default splits with spaces
@ -142,12 +143,12 @@ def query(filter_dummy, query):
for i in range(len(keywords)):
kw_dict["kw" + str(i)] = keywords[i]
s = 'select p.id,partno,description, c.name || l.name as location_descriptor from parts as p inner join locations as l on p.location_id = l.id inner join containers as c on l.container_id = c.id where '
s = 'select p.id,partno,description,type_id,c.name as type_descriptor from parts as p inner join containers as c on p.type_id = c.type where '
if filter['l'] == 'true':
s += '('
for i in range(len(keywords)):
s += 'LOWER(c.name||l.name) like LOWER(:kw'+ str(i) +') AND '
s += 'LOWER(c.name) like LOWER(:kw'+ str(i) +') AND '
s = s[:-5]
s += ') OR '
if filter['p'] == 'true':
@ -171,7 +172,7 @@ def query(filter_dummy, query):
r.close()
return json.dumps(l)
@app.route('/parts/map/<containerID>')
@app.route('/map/<containerID>')
def getMap(containerID):
s = 'select map, overlay from containers where id = :id;'
r = db_engine.execute(text(s), id=containerID)
@ -196,14 +197,14 @@ def getMap(containerID):
return serveImage(mapimage)
@app.route('/parts/getfile/<filename>')
@app.route('/getfile/<filename>')
def getfile(filename):
if(re.match('^[\w\-_]+.[p|P][d|D][f|F]$', filename) == None):
return 'No injections pls.'
return send_from_directory('/srv/datasheets/', filename)
@app.route('/parts/alter/<partID>', methods=['POST'])
@app.route('/alter/<partID>', methods=['POST'])
@requires_auth
def alter(partID):
partID = int(partID)
@ -211,8 +212,8 @@ def alter(partID):
r = {}
if partID < 0:
# New entry
s = 'insert into parts (partno, description, datasheet, location_id, whoadded, notes) '
s += 'values (:partno, :description, :datasheet, :location_id, :user_id, :notes) returning id;'
s = 'insert into parts (partno, description, datasheet, type_id, whoadded, notes, parameters) '
s += 'values (:partno, :description, :datasheet, :type_id, :user_id, :notes, :parameters) returning id;'
s = text(s)
if len(request.files) != 0:
datasheet_file = request.files['datasheet-file']
@ -222,7 +223,7 @@ def alter(partID):
datasheet_filename = datasheet_filename[:-4] + str(i) + '.pdf'
i += 1
datasheet_file.save('/srv/datasheets/' + datasheet_filename)
datasheet_filename = 'http://elab.kth.se/parts/getfile/' + datasheet_filename
datasheet_filename = 'http://elab.kth.se/getfile/' + datasheet_filename
# elif request.form.has_key('datasheet-url'):
# datasheet_filename = request.form['datasheet-url']
else:
@ -233,8 +234,9 @@ def alter(partID):
r = db_engine.execute(s, partno=request.form['partno'],
description=request.form['description'],
datasheet=datasheet_filename,
location_id=request.form['location_id'],
type_id=request.form['type_id'],
notes=request.form['notes'],
parameters=request.form['parameters'],
user_id=session['uid'])
else:
# Modify entry
@ -244,7 +246,7 @@ def alter(partID):
l.append(dict(row))
r.close()
s = 'update parts '
s += 'set partno=:partno, description=:description, datasheet=:datasheet, location_id=:location_id, notes=:notes '
s += 'set partno=:partno, description=:description, datasheet=:datasheet, type_id=:type_id, notes=:notes, parameters=:parameters '
if len(request.files) != 0:
datasheet_file = request.files['datasheet-file']
datasheet_filename = secure_filename(datasheet_file.filename)
@ -253,7 +255,7 @@ def alter(partID):
datasheet_filename = datasheet_filename[:-4] + str(i) + '.pdf'
i += 1
datasheet_file.save('/srv/datasheets/' + datasheet_filename)
datasheet_filename = 'http://elab.kth.se/parts/getfile/' + datasheet_filename
datasheet_filename = 'http://elab.kth.se/getfile/' + datasheet_filename
if l[0]['datasheet'] != None:
whole_url = l[0]['datasheet']
actual_filename = whole_url[whole_url.rfind('/') + 1:]
@ -268,15 +270,16 @@ def alter(partID):
r = db_engine.execute(s, partno=request.form['partno'],
description=request.form['description'],
datasheet=datasheet_filename,
location_id=request.form['location_id'],
type_id=request.form['type_id'],
id=partID,
notes=request.form['notes'])
notes=request.form['notes'],
parameters=request.form['parameters'])
new_id = r.fetchone()[0]
r.close()
return '{"status":"ok", "part_id" : ' + str(new_id) + '}'
@app.route('/parts/delete/<partID>')
@app.route('/delete/<partID>')
@requires_auth
def delete(partID):
if int(partID) < 0:
@ -285,7 +288,7 @@ def delete(partID):
r = db_engine.execute(s, id=partID)
return '{"status":"ok"}'
@app.route('/parts/deleteLocation/<locationID>')
@app.route('/deleteLocation/<locationID>')
@requires_auth
def deleteLocation(locationID):
if int(locationID) < 0:
@ -294,7 +297,7 @@ def deleteLocation(locationID):
r = db_engine.execute(s, id=locationID)
return '{"status":"ok"}'
@app.route('/parts/fetchOctopartSnippet/<searchTerm>')
@app.route('/fetchOctopartSnippet/<searchTerm>')
def fetchOctopartSnippet(searchTerm):
if octopartURL == '':
return '{"result":"octopart integration not enabled"}'
@ -334,7 +337,7 @@ if __name__ == '__main__':
app.config['SESSION_TYPE'] = 'memcached'
with open('admin.json') as f:
postgres_credentials = json.load(f)
db_engine, db_metadata = connect(postgres_credentials['username'], postgres_credentials['password'], 'parts_v2')
db_engine, db_metadata = connect(postgres_credentials['username'], postgres_credentials['password'], 'estimator')
parts = sqlalchemy.Table('parts', db_metadata)
try:
with open('octopartAPIkey.json') as f:

@ -1,4 +1,4 @@
var rootURL = '/parts/'
var rootURL = '/'
function overlay_in() {
$('.shadow').show();
@ -15,4 +15,21 @@ function overlay_out() {
$('.overlay').hide();
});
end_edit();
}
}
function calculateoverlay_in() {
$('.shadow').show();
$('.calculateoverlay').show();
$('.shadow').animate({'opacity' : 0.7});
$('.calculateoverlay').animate({'opacity' : 1.0, 'top' : '5%'});
}
function calculateoverlay_out() {
$('.shadow').animate({'opacity' : 0.0}, function () {
$('.shadow').hide();
});
$('.calculateoverlay').animate({'opacity' : 0.0, 'top' : '0'}, function () {
$('.calculateoverlay').hide();
});
}

@ -95,7 +95,7 @@ function show_location_info(locationID) {
$('table#details tr#description td input').val(text_filter(data.description));
container_onchange();
if (data.datasheet != null) {
$('tr#datasheet-head').html($('<td>DATASHEET: <a href="parts/getfile/' + data.datasheet + '"><i class="fa fa-file-text" aria-hidden="true"></i></a></td>'));
$('tr#datasheet-head').html($('<td>DATASHEET: <a href="/getfile/' + data.datasheet + '"><i class="fa fa-file-text" aria-hidden="true"></i></a></td>'));
$('#datasheet-input').val(data.datasheet);
}
else
@ -123,4 +123,4 @@ function placeMarker(locationID){
// $("#mapURL").html("elab.png?x=" + correctX + "&y=" + correctY);
$("#clickablemap").attr("src", "map/" + $("#mapfile-input").val() + "?x=" + correctX + "&y=" + correctY);
}
}

@ -1,13 +1,16 @@
var active_timer = 100;
var calculation = 0;
function capitalizeFirstLetter(string) {
return string.charAt(0).toUpperCase() + string.slice(1);
}
function init_edit(partID) {
$('table#details tr#location td p').hide();
$('#location-dropdown').show();
$('#container-dropdown').show();
$('table#details tr#type td p').hide();
$('#type-dropdown').show();
$('table#details tr#partno td p').hide();
$('input[name=partno-input]').show();
$('#magical_autofill').show();
// $('#magical_autofill').show();
$('table#details tr#description td p').hide();
$('input[name=description-input]').show();
@ -23,6 +26,16 @@ function init_edit(partID) {
$('input[name=notes-input]').show();
$('table#details tr#notes td p').hide();
$('input[name=voltage-input]').show();
$('table#details tr#voltage td p').hide();
$('input[name=current-input]').show();
$('table#details tr#current td p').hide();
$('input[name=sleepcurrent-input]').show();
$('table#details tr#sleepcurrent td p').hide();
$('input[name=txrx-input]').show();
$('input[name=txrx-head]').show();
$('table#details tr#txrx td p').hide();
// var newButton = '<div class="round-button-left"><a href="#" onclick="save(' + partID + ')"><i class="fa fa-check" aria-hidden="true"></i></a></div>';
// $('.round-button-left').replaceWith(newButton);
$('#edit-button').html('<i class="fa fa-check" aria-hidden="true"></i>');
@ -32,29 +45,32 @@ function init_edit(partID) {
}
function new_entry() {
$('table#details tr#location td p').text('');
$('table#details tr#type td p').text('');
$('table#details tr#partno td p').text('');
$('table#details tr#description td p').text('');
$('table#details tr#partno td input').val('');
$('table#details tr#description td input').val('');
$('input[name=datasheet-url-input]').val('');
// container_onchange();
container_onchange();
init_edit(-1);
overlay_in();
}
function calculate() {
calculateoverlay_in();
}
function end_edit() {
$('table#details tr#location td p').text($('table#details tr#location td select option:checked').text());
$('table#details tr#location td p').show();
$('#location-dropdown').hide();
$('#container-dropdown').hide();
$('table#details tr#type td p').text($('table#details tr#type td select option:checked').text());
$('table#details tr#type td p').show();
$('#type-dropdown').hide();
$('table#details tr#partno td p').text($('table#details tr#partno td input').val());
$('table#details tr#partno td p').show();
$('table#details tr#partno td input').hide();
$('#magical_autofill').hide();
// $('#magical_autofill').hide();
$('table#details tr#description td p').text($('table#details tr#description td input').val());
$('table#details tr#description td p').show();
@ -73,17 +89,26 @@ function end_edit() {
// $('.round-button-left').replaceWith(newButton);
}
function save(partID) {
if (!$('#location-dropdown').val()) {
alert('Please select a location.');
if (!$('#type-dropdown').val()) {
alert('Please select a component type.');
return;
}
var location_id_v = $('#location-dropdown').val();
var type_id_v = $('type-dropdown').val();
var partno_v = $('input[name=partno-input]').val();
var description_v = $('input[name=description-input]').val();
var datasheet = $('table#details tr#datasheet td input')[0].files;
var datasheet_url_v = $('input[name=datasheet-url-input]').val();
var notes_v = $('input[name=notes-input]').val();
var total = [];
var mapped = {};
$('.parameter-content').find('input').each(function(index,elem){
//8 console.log(elem.value);
total.push(elem.value);
mapped[elem.name] = elem.value;
});
console.log(mapped);
if(partno_v.length == 0){
alert('Please enter a part number.');
return;
@ -112,9 +137,11 @@ function save(partID) {
data.append('datasheet-url', datasheet_url_v);
}
data.append('partno', partno_v);
data.append('location_id', location_id_v);
data.append('type_id', type_id_v);
data.append('description', description_v);
data.append('notes', notes_v);
data.append('parameters', mapped);
$.ajax({
// Your server script to process the upload
@ -172,18 +199,48 @@ function delete_entry(partID) {
},
});
}
function calculate_entry(partID,parameters) {
if (partID < 0)
return;
if (!confirm('Add selected entry to calculation?'))
return;
console.log(parameters);
if(parameters != null) {
var jsonParameters = JSON.parse(data.parameters);
console.log(jsonParameters);
var count = Object.keys(jsonParameters).length;
console.log(count);
// for(var k = 0; k < count; k++) {
var obj = Object.keys(jsonParameters);
var values = Object.values(jsonParameters);
var voltage = 0;
var currents = [];
console.log(obj);
for (var key in obj) {
var value = obj[key];
console.log(key+":"+value);
if(value.includes('voltage')) {
voltage = values[key];
}
else if(value.includes('current')) {
}
}
}
}
function show_part_info(partID) {
$.getJSON(rootURL + 'getpartinfo/' + partID, function(data) {
$('table#details tr#location td p').text(text_filter(data.location_descriptor)); // name is the location friendly name
$('#container-dropdown').val(data.container_id);
$('img#map').attr('src', 'parts/map/' + data.container_id);
$('#location-dropdown').empty();
$.getJSON('parts/getlocationsInContainer/' + data.container_id, function(json) {
$.each(json, function(loc_id, loc_name) {
$('#location-dropdown').append('<option value="' + loc_id + '">' + loc_name + '</option>');
});
$('#location-dropdown').val(data.location_id);
$('img#map').attr('src', 'parts/map/' + data.type_id);
$('#type-dropdown').empty();
$.getJSON('/getTypes', function(json) {
$.each(json, function(type_id, type_name) {
$('#type-dropdown').append('<option value="' + type_id + '">' + type_name + '</option>');
if (data.type_id == type_id) {
$('table#details tr#type td p').text(text_filter(type_name)); // name is the type friendly name
}
});
$('#type-dropdown').val(data.type_id);
});
$('table#details tr#partno td p').text(text_filter(data.partno));
$('table#details tr#partno td input').val(text_filter(data.partno));
@ -191,6 +248,38 @@ function show_part_info(partID) {
$('table#details tr#description td input').val(text_filter(data.description));
$('table#details tr#notes td p').text(text_filter(data.notes));
$('input[name=notes-input]').val(text_filter(data.notes));
console.log(data.parameters);
if(data.parameters != null) {
var jsonParameters = JSON.parse(data.parameters);
console.log(jsonParameters);
var count = Object.keys(jsonParameters).length;
console.log(count);
// for(var k = 0; k < count; k++) {
var obj = Object.keys(jsonParameters);
var values = Object.values(jsonParameters);
console.log(obj);
for (var key in obj) {
var value = obj[key];
console.log(key+":"+value);
console.log($('table#details tr#'+value.substring(0,value.indexOf("-"))).children().length );
if(value.includes("input") && $('table#details tr#'+value.substring(0,value.indexOf("-"))).children().length == 0 ) {
$('table#details').append('<tr id='+value.substring(0,value.indexOf("-"))+'><td><p></p><input type="text" name='+value+' class="pinfo-input"></td></tr>')
$('table#details tr#'+value.substring(0,value.indexOf("-"))+' td p').text(capitalizeFirstLetter(value.substring(0,value.indexOf("-"))));
$('table#details tr#'+value.substring(0,value.indexOf("-"))+' td p').show();
$('table#details tr#'+value.substring(0,value.indexOf("-"))+' td input').val(values[key]);
$('table#details tr#'+value.substring(0,value.indexOf("-"))+' td input').show();
}
else {
$('table#details tr#'+value.substring(0,value.indexOf("-"))+' td p').text(capitalizeFirstLetter(value.substring(0,value.indexOf("-"))));
$('table#details tr#'+value.substring(0,value.indexOf("-"))+' td p').show();
$('table#details tr#'+value.substring(0,value.indexOf("-"))+' td input').val(values[key]);
$('table#details tr#'+value.substring(0,value.indexOf("-"))+' td input').show();
}
}
}
// }
// Resetting file input. Super dirty hack. Disgusting
var $el = $('#datasheet-finput');
$el.wrap('<form>').closest('form').get(0).reset();
@ -209,6 +298,15 @@ function show_part_info(partID) {
$('#delete-button').off('click').on('click', function() {
delete_entry(partID);
});
$('#calculate-add-button').off('click').on('click', function() {
for (var key in obj) {
var value = obj[key];
console.log(key+":"+value);
jsonParameters[obj[key]]=$('table#details tr#'+value.substring(0,value.indexOf("-"))+' td input').val();
}
calculate_entry(partID,jsonParameters);
});
overlay_in();
}).fail(function() {
console.log( "Fetching part info failed" );
@ -221,21 +319,24 @@ function perform_query() {
$('#no-results').hide();
var query = $('.search-bar').val();
var data = {
l:$('#location').is(':checked'),
l:$('#type').is(':checked'),
p:$('#partno').is(':checked'),
d:$('#description').is(':checked')
};
filter = '0';
$("#results").find("tr:not(:first)").remove(); // Delete all table rows
$.getJSON(rootURL + 'query/' + filter + '/' + query, data, function(data) {
var queryPromise = $.getJSON(rootURL + 'query/' + filter + '/' + query, data, function(data) {
for(var i = 0; i < data.length; i++) {
var newRow = $('<tr onclick="show_part_info(' + data[i].id + ')"></tr>');
newRow.append($('<td id="location"></td>').text(text_filter(data[i].location_descriptor)));
console.log(data[i]);
var newRow = $('<tr onclick="show_part_info(' + data[i].id + ')"></tr>');
newRow.append($('<td id="type"></td>').text(text_filter(data[i].type_descriptor)));
newRow.append($('<td id="partno"></td>').text(text_filter(data[i].partno)));
newRow.append($('<td id="description"></td>').text(text_filter(data[i].description)));
$('#results').append(newRow);
}
if(data.length == 0) {
$('#no-results').show();
$('#no-results').animate({opacity:1},2000);
@ -245,19 +346,23 @@ function perform_query() {
$('#no-results').animate({opacity:1},2000);
console.log( "Query failed" );
});
//});
}
function container_onchange() {
var selected_container_id = $('#container-dropdown').val();
if (selected_container_id > 0) {
$('img#map').attr('src', 'parts/map/' + selected_container_id);
$('#location-dropdown').empty();
$.getJSON('parts/getlocationsInContainer/' + selected_container_id, function(data) {
$.each(data, function(location_id, location_name) {
$('#location-dropdown').append('<option value="' + location_id + '">' + location_name + '</option>');
var selected_container_id = $('#type-dropdown').val();
// if (selected_container_id > 0) {
//$('#type-dropdown').empty();
$.getJSON('/getTypes', function(data) {
$.each(data, function(type_id, type_name) {
$('#type-dropdown').append('<option value="' + type_id + '">' + type_name + '</option>');
if (data.type_id == type_id) {
$('table#details tr#type td p').text(text_filter(type_name)); // name is the type friendly name
}
});
});
}
// }
}
function octopartFetch(){
@ -282,7 +387,7 @@ $(document).ready(function() {
active_timer = setTimeout(perform_query, 100);
});
$('.checkbox').change( function() {
if ( !$('#location').is(':checked')
if ( !$('#type').is(':checked')
&& !$('#partno').is(':checked')
&& !$('#description').is(':checked')
&& !$('#has-docs').is(':checked'))
@ -296,4 +401,4 @@ $(document).ready(function() {
// octopartFetch();
// }
// });
});
});

@ -81,6 +81,9 @@ input[type=text].search-bar {
input[type=checkbox]{
display: none;
}
input[type=range] {
}
input[type=checkbox] + label.toggle-btn {
padding:10px 0 10px 0;
@ -126,6 +129,24 @@ input[type=checkbox]:checked + label.toggle-btn {
opacity: 0.0;
}
.calculateoverlay {
background-color: #226666;
color: #D7E2E2;
display: none;
height: 90%;
padding: 0;
position: fixed;
margin:auto;
left:0;
right:0;
top:0;
min-width: 60%;
width:900px;
z-index: 201;
text-align: center;
opacity: 0.0;
}
.round-button {
display: flex;
align-items: center;
@ -171,7 +192,10 @@ input[type=checkbox]:checked + label.toggle-btn {
.round-floating-button a{
color: #D7E2E2;
}
#calculate-button {
right: 76px;
margin-right: 8px
}
#datasheet-info p {
font-size: 12pt;
}
@ -203,7 +227,7 @@ input[type=checkbox]:checked + label.toggle-btn {
text-align: left;
}
#results #location {
#results #type {
width: 18%;
}
@ -230,6 +254,9 @@ input[type=checkbox]:checked + label.toggle-btn {
#details {
width: 100%;
}
#results {
width: 100%;
}
#magical_autofill{
font-size: small;
@ -249,6 +276,14 @@ a.small_link{
padding-top:6pt;
padding-bottom:16pt;
}
.results-header {
color: #013A3A;
}
.results-content td{
padding-top:6pt;
padding-bottom:16pt;
}
td p {
margin: 0;
@ -275,4 +310,4 @@ td p {
.nothidden{
display: initial !important;
}
}

@ -8,10 +8,10 @@
integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4="
crossorigin="anonymous"></script>
<link href="https://fonts.googleapis.com/css?family=Roboto:300,400" rel="stylesheet">
<link rel="stylesheet" type="text/css" href="/parts/static/style.css">
<link rel="stylesheet" type="text/css" href="/static/style.css">
<script src="https://use.fontawesome.com/2fef7be393.js"></script>
<script type="text/javascript" src="/parts/static/common.js"></script>
<script type="text/javascript" src="/parts/static/locationEditorScript.js"></script>
<script type="text/javascript" src="/static/common.js"></script>
<script type="text/javascript" src="/static/locationEditorScript.js"></script>
</head>
<body>
<h1>LOCATION EDITOR</h1>

@ -3,56 +3,53 @@
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>ELAB Part Search Engine</title>
<title>IL2232 Estimator</title>
<script
src="https://code.jquery.com/jquery-3.2.1.min.js"
integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4="
crossorigin="anonymous"></script>
<link href="https://fonts.googleapis.com/css?family=Roboto:300,400" rel="stylesheet">
<link rel="stylesheet" type="text/css" href="parts/static/style.css" media="screen and (min-width:500px)">
<link rel="stylesheet" type="text/css" href="parts/static/style-m.css" media="screen and (max-width:500px)">
<link rel="apple-touch-icon-precomposed" href="parts/static/apple-touch-icon.png">
<link rel="stylesheet" type="text/css" href="static/style.css" media="screen and (min-width:500px)">
<link rel="stylesheet" type="text/css" href="static/style-m.css" media="screen and (max-width:500px)">
<link rel="apple-touch-icon-precomposed" href="static/apple-touch-icon.png">
<script src="https://use.fontawesome.com/2fef7be393.js"></script>
<script type="text/javascript" src="parts/static/common.js"></script>
<script type="text/javascript" src="parts/static/script.js"></script>
<script type="text/javascript" src="static/common.js"></script>
<script type="text/javascript" src="static/script.js"></script>
</head>
<body>
<h1>ELAB Part Search Engine</h1>
<p>Looking for obsolete ICs that were discontinued years ago? Just start typing!</p>
<h1>IL2232 Smart cities power budget estimator </h1>
<p>Designing an energy harvesting solution? Search for your components, add them and get a power requirement estimate</p>
<input type="text" name="search-bar" class="search-bar" placeholder="Search parts">
<div class="filter-container">
<p>SEARCH IN</p>
<ul>
<li><input type="checkbox" class="checkbox" id="location"><label class="toggle-btn" for="location">Locations<br><i class="fa fa-map" style="font-size:20pt"></i></label></li>
<li><input type="checkbox" class="checkbox" id="type"><label class="toggle-btn" for="type">Component type<br><i class="fa fa-map" style="font-size:20pt"></i></label></li>
<li><input type="checkbox" class="checkbox" id="partno" checked=""><label class="toggle-btn" for="partno">Part Number<br><i class="fa fa-hashtag" style="font-size:20pt"></i></label></li>
<li><input type="checkbox" class="checkbox" id="description" checked=""><label class="toggle-btn" for="description">Description<br><i class="fa fa-edit" style="font-size:20pt"></i></label></li>
</ul>
</div>
<table id="results">
<tr>
<th id="location">Location</th>
<th id="type">Component type</th>
<th id="partno">Part Number</th>
<th id="description">Description</th>
</tr>
</table>
<h3 id="no-results">No results.</h3>
<div class="shadow" onclick="overlay_out()"></div>
<div class="shadow" onclick="overlay_out();calculateoverlay_out()"></div>
<div class="overlay">
<h2>Part Details</h2>
<div id="info-container">
<img src="" id="map" class="map"/>
<table id="details">
<tr id="location-head" class="details-header"><td>LOCATION</td></tr>
<tr id="location" class="details-content"><td><p></p>
<select class="pinfo-input" id="container-dropdown" onchange="container_onchange()">
{% for container in containers %}
<option value="{{container['id']}}">{{container['name']}}</option>
<tr id="type-head" class="details-header"><td>TYPE</td></tr>
<tr id="type" class="details-content"><td><p></p>
<select class="pinfo-input" id="type-dropdown" onchange="container_onchange()">
{% for type in types %}
<option value="{{type['id']}}">{{type['name']}}</option>
{% endfor %}
</select>
<select class="pinfo-input" id="location-dropdown">
<option value="-1" selected="true">-- Select a container --</option>
</select>
</td></tr>
<tr id="partno-head" class="details-header"><td>PART NUMBER</td></tr>
<tr id="partno" class="details-content"><td><p></p><input type="text" name="partno-input" placeholder="Part Number" class="pinfo-input" id="partno-input"/></td></tr>
@ -64,17 +61,42 @@
<tr id="datasheet" style="display: none"><td>OR: <input type="text" class="pinfo-input" name="datasheet-url-input" style="width:80%; margin-bottom: 6pt;" placeholder="Datasheet URL"></td></tr>
<tr id="notes-head" class="details-header"><td>NOTES</td></tr>
<tr id="notes" class="details-content"><td><p></p><input type="text" name="notes-input" class="pinfo-input" placeholder="Notes"></td></tr>
<tr id="parameters-head" class="details-header"><td>PARAMETERS</td></tr>
</table>
<div class="button-container">
<div class="round-button"><a href="#" id="delete-button"><i class="fa fa-trash" aria-hidden="true"></i></a></div>
<div class="round-button"><a href="#" id="edit-button"><i class="fa fa-pencil" aria-hidden="true"></i></a></div>
<div class="round-button"><a href="#" id="duplicate-button" onclick="init_edit(-1)"><i class="fa fa-copy" aria-hidden="true"></i></a></div>
<div class="round-button text-center"><a href="#" id="calculate-add-button"><i class="fa fa-calculator" aria-hidden="true"></i></a></div>
</div>
</div>
<div>
<div class="small-square-button"><a href="#" onclick="overlay_out()"><i class="fa fa-times" aria-hidden="true"></i></a></div>
</div>
</div>
<div class="calculateoverlay">
<h2>Calculation results</h2>
<div id="calculation-container">
<table id="calculations">
<tr id="type-head" class="calculations-header"><td>TYPE</td></tr>
<tr id="type" class="calculations-content"><td><p></p>
</td></tr>
</table>
<div class="button-container">
<div class="round-button"><a href="#" id="delete-button"><i class="fa fa-trash" aria-hidden="true"></i></a></div>
<div class="round-button"><a href="#" id="edit-button"><i class="fa fa-pencil" aria-hidden="true"></i></a></div>
<div class="round-button"><a href="#" id="duplicate-button" onclick="init_edit(-1)"><i class="fa fa-copy" aria-hidden="true"></i></a></div>
<div class="round-button text-center"><a href="#" id="calculate-add-button"><i class="fa fa-calculator" aria-hidden="true"></i></a></div>
</div>
</div>
<div>
<div class="small-square-button"><a href="#" onclick="calculateoverlay_out()"><i class="fa fa-times" aria-hidden="true"></i></a></div>
</div>
</div>
<div class="round-floating-button"><a href="#" onclick="new_entry()"><i class="fa fa-plus" aria-hidden="true"></i></a></div>
<div id="calculate-button" class="round-floating-button"><a href="#" onclick="calculate()"><i class="fa fa-calculator" aria-hidden="true"></i></a></div>
</body>
</html>

Loading…
Cancel
Save