This commit is contained in:
Adrian Amaglio 2021-02-26 09:47:45 +01:00
parent 979b67338e
commit 2600035511
11 changed files with 333 additions and 67 deletions

View File

@ -5,13 +5,22 @@
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0"> <meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico"> <link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title><%= htmlWebpackPlugin.options.title %></title> <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/fork-awesome@1.1.7/css/fork-awesome.min.css" integrity="sha256-gsmEoJAws/Kd3CjuOQzLie5Q3yshhvmo7YNtBG7aaEY=" crossorigin="anonymous">
<title>SEC 2003</title>
</head> </head>
<body> <body>
<h1>Super Émail Calculator 2003</h1>
<noscript> <noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong> <strong>Le Super Émail Calculator 2000 nécessite javascript pour fonctionner. Aucun pistage nest fait, aucune information nest envoyé au serveur, qui par ailleurs sen moquerait bien.</strong>
</noscript> </noscript>
<div id="app"></div> <div id="app"></div>
<!-- built files will be auto injected -->
</body> </body>
<footer>
<ul>
<li>Conçu par Adrian et Elisa</li>
<li>Code source disponible <a href="https://git.jean-cloud.net/adrian/SEC2003">sur notre dépôt git</a></li>
<li>Logo <a href="https://fr.freepik.com/vecteurs/ligne">Ligne vecteur créé par studiogstock - fr.freepik.com</a></li>
<li>Hébergé par <a href="https://jean-cloud.net">Jean-Cloud</a></li>
</ul>
</footer>
</html> </html>

View File

@ -1,18 +1,122 @@
<template> <template>
<div id="app"> <div>
<img alt="Vue logo" src="./assets/logo.png"> <h2>Formule SEGER</h2>
<HelloWorld msg="Welcome to Your Vue.js App"/> <table>
<tr>
<th>Oxyde basique <button @click="formule_seger['oxyde_basique'].push({quantity:0})" class="fa fa-plus"></button></th>
<th>Amphotere <button @click="formule_seger['amphotere'].push({quantity:0})" class="fa fa-plus"></button></th>
<th>Oxyde acide <button @click="formule_seger['oxyde_acide'].push({quantity:0})" class="fa fa-plus"></button></th>
</tr>
<tr>
<td>
<seger-field :liste="liste_oxydes_basique" v-model="formule_seger['oxyde_basique']"></seger-field>
</td>
<td>
<seger-field :liste="liste_amphoteres" v-model="formule_seger['amphotere']"></seger-field>
</td>
<td>
<seger-field :liste="liste_oxydes_acide" v-model="formule_seger['oxyde_acide']"></seger-field>
</td>
</tr>
<tr>
<td>Total: <span :class="{invalid: sommeQtyOxydesBasiques != 1}">{{sommeQtyOxydesBasiques}}</span></td>
</tr>
</table>
<h2>Ingrédients</h2>
<table>
<tr>
<th>
Ingredients
<button @click="ingredients.push({ingredient:0, molecule:0, quantity:20})" class="fa fa-plus"></button>
</th>
<th>Total pour <input type="numer" name="" min="0" v-model="grammage">g</th>
</tr>
<ingredients v-model="ingredients" :liste="liste_ingredients"></ingredients>
<tr>
<td></td>
<td>Masse molaire totale de la recette : 40 mol/g</td>
</tr>
</table>
<h2>Résultats</h2>
<td v-for="(l, type) in results" :key="type">
<h3>{{type}}</h3>
<ul>
<li v-for="v in l" :key="v.label" :class="{invalid:Math.abs(v.quantity) > 0.01}">
{{v.label}}&nbsp;: {{v.quantity.toFixed(2)}}
</li>
</ul>
</td>
</div> </div>
</template> </template>
<script> <script>
import HelloWorld from './components/HelloWorld.vue' import SegerField from './components/SegerField.vue'
import Ingredients from './components/Ingredients.vue'
import liste_ingredients from './data/ingredients.js'
import liste_oxydes_acide from './data/oxydes_acide.js'
import liste_oxydes_basique from './data/oxydes_basique.js'
import liste_amphoteres from './data/amphoteres.js'
export default { export default {
name: 'App', name: 'App',
components: { components: {
HelloWorld SegerField,
Ingredients,
},
data() {
return {
liste_ingredients: liste_ingredients,
liste_oxydes_acide: liste_oxydes_acide,
liste_oxydes_basique: liste_oxydes_basique,
liste_amphoteres: liste_amphoteres,
ingredients: [{ingredient:0, molecule:'', quantity:20}],
formule_seger: {
oxyde_basique: [{label:'CaO',quantity:0,imutable:true}, {label:'KNaO',quantity:0,imutable:true}, {label:'MgO',quantity:0,imutable:true}],
oxyde_acide: [{label:'SiO2',quantity:0,imutable:true}],
amphotere: [{label:'Al2O3',quantity:0,imutable:true}],
},
grammage: 100,
} }
},
computed: {
sommeQtyOxydesBasiques: function () {
var result = 0
for (const index in this.formule_seger.oxyde_basique) {
const i = parseFloat(this.formule_seger.oxyde_basique[index].quantity)
result += isNaN(i) ? 0 : i
}
return result
},
results: function () {
/* Input elements but times -1 */
var res = {}
for (const type in this.formule_seger) {
res[type] = []
for (const index in this.formule_seger[type]) {
res[type].push(Object.assign({}, this.formule_seger[type][index]))
res[type][index].quantity *= -1
}
}
/* Add elements we got in ingredients */
for (const index_ingredient in this.ingredients) {
const ingredient = this.ingredients[index_ingredient]
for (const index_molecule in liste_ingredients[ingredient.ingredient].composition) {
const molecule = liste_ingredients[ingredient.ingredient].composition[index_molecule]
var objet = res[molecule.type].find(o => {return o.label==molecule.label}) /* get the molecule item */
if (objet === undefined) {
objet = {label:molecule.label, quantity:molecule.quantity}
res[molecule.type].push(objet)
}
objet.quantity += molecule.quantity * (ingredient.quantity / liste_ingredients[ingredient.ingredient].masse_molaire)
}
}
return res
},
},
} }
</script> </script>
@ -25,4 +129,7 @@ export default {
color: #2c3e50; color: #2c3e50;
margin-top: 60px; margin-top: 60px;
} }
button {
cursor:pointer;
}
</style> </style>

View File

@ -1,58 +0,0 @@
<template>
<div class="hello">
<h1>{{ msg }}</h1>
<p>
For a guide and recipes on how to configure / customize this project,<br>
check out the
<a href="https://cli.vuejs.org" target="_blank" rel="noopener">vue-cli documentation</a>.
</p>
<h3>Installed CLI Plugins</h3>
<ul>
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel" target="_blank" rel="noopener">babel</a></li>
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-eslint" target="_blank" rel="noopener">eslint</a></li>
</ul>
<h3>Essential Links</h3>
<ul>
<li><a href="https://vuejs.org" target="_blank" rel="noopener">Core Docs</a></li>
<li><a href="https://forum.vuejs.org" target="_blank" rel="noopener">Forum</a></li>
<li><a href="https://chat.vuejs.org" target="_blank" rel="noopener">Community Chat</a></li>
<li><a href="https://twitter.com/vuejs" target="_blank" rel="noopener">Twitter</a></li>
<li><a href="https://news.vuejs.org" target="_blank" rel="noopener">News</a></li>
</ul>
<h3>Ecosystem</h3>
<ul>
<li><a href="https://router.vuejs.org" target="_blank" rel="noopener">vue-router</a></li>
<li><a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a></li>
<li><a href="https://github.com/vuejs/vue-devtools#vue-devtools" target="_blank" rel="noopener">vue-devtools</a></li>
<li><a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener">vue-loader</a></li>
<li><a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener">awesome-vue</a></li>
</ul>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
props: {
msg: String
}
}
</script>
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
h3 {
margin: 40px 0 0;
}
ul {
list-style-type: none;
padding: 0;
}
li {
display: inline-block;
margin: 0 10px;
}
a {
color: #42b983;
}
</style>

View File

@ -0,0 +1,48 @@
<template>
<div>
<tr v-for="(v,i) in value" :key="v.label">
<td>
<select @input="setMolecule(i) ; update()" v-model="v.ingredient">
<option value="">-</option>
<option v-for="(item, index) in liste" :value="index" :key="index">{{item.label}}</option>
</select>
<select @input="update" v-model="v.molecule">
<option v-for="(molecule,index) in liste[v.ingredient].composition" :value="index" :key="molecule.label">
{{ molecule.label }}
</option>
</select>
</td>
<td>20g</td>
<td><button v-show="value.length > 1" @click="suppr(i) ; update()">Supprimer</button></td>
</tr>
</div>
</template>
<script>
export default {
name: 'Ingredients',
props: {
value: {type: Array, required: true},
liste: {type: Array, required: true},
},
created: function () {
this.setMolecule(0)
},
methods: {
update: function () {
this.$emit('input', this.value)
},
setMolecule: function (index) {
this.value[index].molecule = 0
},
suppr: function (index) {
this.value.splice(index, 1)
},
},
}
</script>
<style scoped>
</style>

View File

@ -0,0 +1,33 @@
<template>
<div>
<div v-for="molecule in filtered" :key="molecule">
</div>
</div>
</template>
<script>
export default {
name: 'MoleculeList',
props: {
type: {type: String, required: true},
liste: {type: Array, required: true},
},
methods: {
},
computed: {
surplus: function () {
return this.list
},
normal: function () {
return this.list
},
filtered: function () {
return this.list.filter(x => {return x.type == this.type})
},
},
}
</script>
<style scoped>
</style>

View File

@ -0,0 +1,43 @@
<template>
<div>
<div v-for="(v,index) in value" :key="v.label">
<input @input="update" type="number" v-model="v.quantity" min="0" step="0.1">
<span v-if="v.imutable">
{{v.label}}
</span>
<span v-else>
<select @input="update" v-model="v.label">
<option value="">-</option>
<option v-for="item in liste" :value="item" :key="item">
{{ item }}
</option>
</select>
<button v-show="value.length > 1" @click="suppr(index) ; update()" class="fa fa-remove"></button>
</span>
</div>
</div>
</template>
<script>
export default {
name: 'SegerField',
props: {
value: {type: Array, required: true},
liste: {type: Array, required: true},
},
methods: {
update: function () {
this.$emit('input', this.value)
},
suppr: function (index) {
this.value.splice(index, 1)
},
},
}
</script>
<style scoped>
</style>

2
src/data/amphoteres.js Normal file
View File

@ -0,0 +1,2 @@
const amphoteres = ["a"];
export default amphoteres;

76
src/data/ingredients.js Normal file
View File

@ -0,0 +1,76 @@
const ingredients = [
{
"label": "Kaolin",
"id": "kaolin",
"origine": "Ceradel 2019",
"composition": [
{
"label":"Al2O3",
"quantity": 1,
"type": "amphotere"
},{
"label":"SiO2",
"quantity": 1,
"type": "oxyde_acide"
}
],
"commentaire": "c'est cool",
"masse_molaire": 258
},
{
"label": "Syenite",
"id": "syenite",
"origine": "",
"composition": [
{
"label":"KNaO",
"quantity": 0.4,
"type": "oxyde_basique"
},{
"label":"Al2O3",
"quantity": 0.2,
"type": "amphotere"
},{
"label":"SiO2",
"quantity": 3,
"type": "oxyde_acide"
}
],
"commentaire": "c'est cool",
"masse_molaire": 120
},
{
"label": "Talc",
"id": "talc",
"origine": "",
"composition": [
{
"label":"BULLSHIT 500",
"quantity": 1,
"type": "oxyde_basique"
},{
"label":"SiO2",
"quantity": 3,
"type": "oxyde_acide"
}
],
"commentaire": "c'est cool",
"masse_molaire": 120
},
{
"label": "Craie",
"id": "craie",
"origine": "",
"composition": [
{
"label":"CAO",
"quantity": 1,
"type": "oxyde_basique"
}
],
"commentaire": "c'est cool",
"masse_molaire": 120
}
];
export default ingredients;

2
src/data/oxydes_acide.js Normal file
View File

@ -0,0 +1,2 @@
const oxydes_acide = ["a"];
export default oxydes_acide;

View File

@ -0,0 +1,2 @@
const liste_oxydes_basique = ["a"];
export default liste_oxydes_basique;

View File

@ -6,3 +6,5 @@ Vue.config.productionTip = false
new Vue({ new Vue({
render: h => h(App), render: h => h(App),
}).$mount('#app') }).$mount('#app')