apdate
This commit is contained in:
parent
979b67338e
commit
2600035511
@ -5,13 +5,22 @@
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||
<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>
|
||||
<body>
|
||||
<h1>Super Émail Calculator 2003</h1>
|
||||
<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 n’est fait, aucune information n’est envoyé au serveur, qui par ailleurs s’en moquerait bien.</strong>
|
||||
</noscript>
|
||||
<div id="app"></div>
|
||||
<!-- built files will be auto injected -->
|
||||
</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>
|
||||
|
119
src/App.vue
119
src/App.vue
@ -1,18 +1,122 @@
|
||||
<template>
|
||||
<div id="app">
|
||||
<img alt="Vue logo" src="./assets/logo.png">
|
||||
<HelloWorld msg="Welcome to Your Vue.js App"/>
|
||||
<div>
|
||||
<h2>Formule SEGER</h2>
|
||||
<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}} : {{v.quantity.toFixed(2)}}
|
||||
</li>
|
||||
</ul>
|
||||
</td>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<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 {
|
||||
name: 'App',
|
||||
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>
|
||||
|
||||
@ -25,4 +129,7 @@ export default {
|
||||
color: #2c3e50;
|
||||
margin-top: 60px;
|
||||
}
|
||||
button {
|
||||
cursor:pointer;
|
||||
}
|
||||
</style>
|
||||
|
@ -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>
|
48
src/components/Ingredients.vue
Normal file
48
src/components/Ingredients.vue
Normal 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>
|
33
src/components/MoleculeList.vue
Normal file
33
src/components/MoleculeList.vue
Normal 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>
|
43
src/components/SegerField.vue
Normal file
43
src/components/SegerField.vue
Normal 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
2
src/data/amphoteres.js
Normal file
@ -0,0 +1,2 @@
|
||||
const amphoteres = ["a"];
|
||||
export default amphoteres;
|
76
src/data/ingredients.js
Normal file
76
src/data/ingredients.js
Normal 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
2
src/data/oxydes_acide.js
Normal file
@ -0,0 +1,2 @@
|
||||
const oxydes_acide = ["a"];
|
||||
export default oxydes_acide;
|
2
src/data/oxydes_basique.js
Normal file
2
src/data/oxydes_basique.js
Normal file
@ -0,0 +1,2 @@
|
||||
const liste_oxydes_basique = ["a"];
|
||||
export default liste_oxydes_basique;
|
@ -6,3 +6,5 @@ Vue.config.productionTip = false
|
||||
new Vue({
|
||||
render: h => h(App),
|
||||
}).$mount('#app')
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user