v20201023
authorKilian Saffran <ksaffran@dks.lu>
Fri, 23 Oct 2020 08:20:59 +0000 (10:20 +0200)
committerKilian Saffran <ksaffran@dks.lu>
Fri, 23 Oct 2020 08:20:59 +0000 (10:20 +0200)
.vscode/settings.json
app/lib/POT/Workplan.pm
app/lib/dksdb.pm
app/static/js/timecalc.js
app/tmpl/block/dlgstaffperioddays.tt
app/tmpl/index.tt
app/tmpl/module/periods/staffperiodweeks.js
app/tmpl/module/workplans/workplans.js
desktopapp/main.js

index d4477bc..079f549 100644 (file)
@@ -1,6 +1,6 @@
 {
   "perlSyntax.includePaths": [
-    "C:/Users/kilian/Workspace/pot_lu/app/lib/perl5","C:/Users/kilian/Workspace/pot_lu/app/lib","C:/Users/kilian/Workspace/pot_lu/website/api/lib"
+    "C:/Users/kilian/Workspace/pot_lu/app/lib/perl5","C:/Users/kilian/Workspace/pot_lu/app/lib","C:/Users/kilian/Workspace/pot_lu/website/api/lib","D:/Workspace/pot_lu/app/lib/perl5","D:/Workspace/pot_lu/app/lib","D:/Workspace/pot_lu/website/api/lib"
 ],
 "es6-css-minify.minifyOnSave": "no",
 "git.ignoreLimitWarning": true,
index dea845b..f70b00b 100644 (file)
@@ -101,7 +101,7 @@ sub getWorkplanDays(){
     to_char(wpd.pausestart2::interval, 'HH24:MI') AS pausestart2,
     to_char(wpd.pauseend2::interval, 'HH24:MI') AS pauseend2,";
 
-    if ($payedpause->{payedpauses} eq "1"){
+    if ($payedpause->{payedpauses} ne "1"){
       $sql .= "to_char( dt1+dt2-pdt1-pdt2, 'HH24:MI') AS dayhours,";
     } else {
       $sql .= "to_char(dt1+dt2, 'HH24:MI') AS dayhours,";
index 60cf28b..9e9317d 100644 (file)
@@ -20,7 +20,7 @@ sub new {
     my $class = shift;
     my $p = shift;
     my $self = bless {}, $class;
-    $self->{debug} = 0;
+    $self->{debug} = 1;
     $self->{dbh} = DBI->connect($p->{dsn},$p->{dbuser},$p->{dbpassword},{PrintError=>1,RaiseError=>1,AutoCommit=>1})  or return "query Connection Error!".$!;
     return $self;
 }
index 8632672..72425a2 100644 (file)
@@ -3,7 +3,9 @@ let timecalc = {
     minutes = parseInt(minutes);
     if ((minutes == null) || (minutes == 0)){ return "00:00";};
     let hours = parseInt(minutes/60);
+    
     let restminutes = minutes-(hours*60);
+    // console.log(hours + " : " + restminutes);
     return timecalc.lpad(hours,2,'0') + ":"+ timecalc.lpad(restminutes,2,'0');
   },
   TimeToMinutes:function (strtime){
index 0254614..ae06d8f 100644 (file)
@@ -3,7 +3,7 @@
     <header>
       <span class="button toolbarbtn display-topright" onclick="document.getElementById('dlg_staffreportperioddays').style.display='none'; return false;"><span class="icon icon-remove" style="font-size: 18px;"></span></span>
       <h2 id="dlg_staffreportperioddays_title">
-        Editer Jour
+        Editer Jour:&nbsp;<span id="display_date" class="xlarge">dd, DD.MM.YYYY<span>
       </h2>
     </header>
     <div class="container">
       <form id="frm_staffreportperioddays" name="frm_staffreportperioddays">
         <input class="data_staffreportperioddays" id="id" name="ident_staffreportperioddays_id" type="hidden" value="">
         <div class="container padding">
-          <div class="row">
-          <div class="container third center">
-            <div class="cell center">
-              <input class="white text-black readonly" id="infofreetimebefore" name="infofreetimebefore" style="width: 60px;font-weight: bold;" type="text" value=""> <label class="label" style="font-weight:bold;" for="infofreetimebefore">heures libres avant</label>
-            </div>
-          </div>
-          <div class="container third center">
-          <h4 id="display_date">
-            dd, DD.MM.YYYY
-          </h4>
-          </div>
-          <div class="container third center">
-            <div class="cell center">
-              <input class="white text-black readonly" id="infofreetimeafter" name="infofreetimeafter" style="width: 60px;font-weight: bold;" type="text" value=""> <label class="label" style="font-weight:bold;" for=
-                  "infofreetimeafter">heures libres après</label>
-            </div>
-          </div>
-          </div>
           <div class="row">
             <div class="container half">
               <fieldset>
-                <legend>heures de travail</legend>
+                <legend style="font-weight: bold;">heures de travail</legend>
                 <div class="container">
                   <div class="container cell">
                       <div class="cell" style="width: 86px;">
                       </div>
                       <label class="label" for="staffreportperioddays_timeend1">fin 1</label>
                   </div>
+                  <div class="container cell">
+                    <div class="cell" style="width: 86px;">
+                      <input class="white text-black readonly" id="total1" name="total1" style="width: 60px;" type="text" value=""> <label class="label" for="total1">Total 12</label>
+                    </div>
+                  </div>
                 </div>
                 <div class="container">
                   <div class="container cell">
                       </div>
                       <label class="label" for="staffreportperioddays_timeend2">fin 2</label>
                   </div>
+                  <div class="container cell">
+                    <div class="cell" style="width: 86px;">
+                      <input class="white text-black readonly" id="total2" name="total2" style="width: 60px;" type="text" value=""> <label class="label" for="total2">Total 2</label>
+                    </div>
+                  </div>
                 </div>
               </fieldset>
               <fieldset>
                       </div>
                       <label class="label" for="staffreportperioddays_timeend1">fin 1</label>
                   </div>
+                  <div class="container cell">
+                    <div class="cell" style="width: 86px;">
+                      <input class="white text-black readonly" id="pausetotal1" name="pausetotal1" style="width: 60px;" type="text" value=""> <label class="label" for="pausetotal1">Total pause 1</label>
+                    </div>
+                  </div>
                 </div>
                 <div class="container">
                   <div class="container cell">
                       </div>
                       <label class="label" for="staffreportperioddays_pauseend2">fin 2</label>
                   </div>
+                  <div class="container cell">
+                    <div class="cell" style="width: 86px;">
+                      <input class="white text-black readonly" id="pausetotal2" name="pausetotal2" style="width: 60px;" type="text" value=""> <label class="label" for="pausetotal2">Total pause 2</label>
+                    </div>
+                  </div>
                 </div>
                 <div class="container cell">
                   <div class="cell">
                 </div>
               </fieldset>
               <fieldset>
-              <legend>Info heures</legend>
-              <div class="cell" style="width: 86px;">
-                  <input class="white text-black readonly" id="infomaxdayhours" name="infomaxdayhours" style="width: 60px;" type="text" value=""> <label class="label" for=
-                  "infomaxdayhours">max total</label>
-                </div>
-              <div class="cell" style="width: 86px;">
-                  <input class="white text-black readonly" id="infomaxinterruptionhours" name="infomaxinterruptionhours" style="width: 60px;" type="text" value=""> <label class="label" for=
-                  "infomaxinterruptionhours">max coupure</label>
-                </div>
-                <div class="cell" style="width: 120px;">
-                  <input class="white text-black readonly" id="infomindailyrecuperation" name="infomindailyrecuperation" style="width: 60px;" type="text" value=""> <label class="label" for=
-                  "infomindailyrecuperation">min heures libre quotidienne</label>
+              <legend>Info heures libres avant/après</legend>
+              <div class="cell" style="width: 150px;">
+                  <input class="white text-black readonly" id="infofreetimebefore" name="infofreetimebefore" style="width: 60px;font-weight: bold;" type="text" value=""> <label class="label" for="infofreetimebefore">heures libres avant</label>
                 </div>
-                <div class="cell" style="width: 100px;">
-                  <input class="white text-black readonly" id="infomaxweekhours" name="infomaxweekhours" style="width: 60px;" type="text" value=""> <label class="label" for=
-                  "infomaxweekhours">max heures par semaine</label>
+              <div class="cell" style="width: 150px;">
+                  <input class="white text-black readonly" id="infofreetimeafter" name="infofreetimeafter" style="width: 60px;font-weight: bold;" type="text" value=""> <label class="label" for=
+                  "infofreetimeafter">heures libres après</label>
                 </div>
+                
               </fieldset>
             </div>
             <div class="container half card_vacancy">
               <fieldset>
-                <legend>congé</legend>
-                <div class="container">
-                  <select class="select data_staffreportperioddays" data-column="id_vacancytype" data-id="" style="float: left;" placeholder="00:00"  data-table="staffreportperioddays" id="id_vacancytype" name="staffreportperioddays_id_vacancytype" value="">
-                  </select> <label class="label dayvacancy" for="staffreportperioddays_id_vacancytype">Type de congé</label>
-                </div>
+                <legend style="font-weight: bold;">congé</legend>
                 <div class="container cell">
                     <div class="cell" style="width: 86px;">
                       <input class="timefield data_staffreportperioddays vacdaytotal" data-column="vacancyhours" data-id="" style="float: left;" placeholder="00:00"  data-table="staffreportperioddays" id="vacancyhours" name="staffreportperioddays_vacancyhours" onblur=
-                      "timecalc.validateTime(this);staffperiodweeks.checkdaytime();return false;" type="text" value="">
+                      "staffperiodweeks.checkdaytime();return false;" type="text" value="">
                       <a class="toolbarbtn text-red inlinebtn" href="javascript:dataform.cleanfield('vacancyhours');staffperiodweeks.checkdaytime();" ><span class="icon icon-remove" style=
                       "font-size: 10px;"></span></a>
                     </div>
                     <label class="label" for="staffreportperioddays_vacancyhours">Heures</label>
                 </div>
+                <div class="container cell">
+                <div class="cell" style="width: 250px">
+
+                  <select class="select data_staffreportperioddays" data-column="id_vacancytype" data-id="" placeholder="00:00"  data-table="staffreportperioddays" id="id_vacancytype" name="staffreportperioddays_id_vacancytype" value="">
+                  </select> <label class="label dayvacancy" for="staffreportperioddays_id_vacancytype">Type de congé</label>
+                </div>
+                </div>
+                
               </fieldset>
               <fieldset>
-                <legend>récupération</legend>
-                <div class="container">
-                  <select class="select data_staffreportperioddays" data-column="id_recuperationtype" data-id="" style="float: left;" placeholder="00:00"  data-table="staffreportperioddays" id="id_recuperationtype" name="staffreportperioddays_id_recuperationtype" value="">
-                  </select> <label class="label dayrepos" for="staffreportperioddays_id_recuperationtype">type de repos</label>
-                </div>
+                <legend style="font-weight: bold;">récupération</legend>
+                
                 <div class="container cell">
                     <div class="cell" style="width: 86px;">
                       <input class="timefield data_staffreportperioddays repdaytotal" data-column="recuperationhours" data-id="" style="float: left;" placeholder="00:00"  data-table="staffreportperioddays" id="recuperationhours" name="staffreportperioddays_recuperationhours"
-                      onblur="timecalc.validateTime(this);staffperiodweeks.checkdaytime();;return false;" type="text" value="">
+                      onblur="staffperiodweeks.checkdaytime();return false;" type="text" value="">
                       <a class="toolbarbtn text-red inlinebtn" href="javascript:dataform.cleanfield('recuperationhours');staffperiodweeks.checkdaytime();" ><span class="icon icon-remove" style=
                       "font-size: 10px;"></span></a>
                     </div>
                     <label class="label" for="staffreportperioddays_recuperationhours">Heures</label>
                 </div>
+                <div class="container cell">
+                <div class="cell" style="width: 250px">
+                  <select class="select data_staffreportperioddays" data-column="id_recuperationtype" data-id="" style="float: left;" placeholder="00:00"  data-table="staffreportperioddays" id="id_recuperationtype" name="staffreportperioddays_id_recuperationtype" value="">
+                  </select> <label class="label dayrepos" for="staffreportperioddays_id_recuperationtype">type de repos</label>
+                </div>
+                </div>
               </fieldset>
               <fieldset>
-                <legend>jour</legend>
+              <legend>Info heures</legend>
+              <div class="cell" style="width: 86px;">
+                  <input class="white text-black readonly" id="infomaxdayhours" name="infomaxdayhours" style="width: 60px;" type="text" value=""> <label class="label" for=
+                  "infomaxdayhours">max total</label>
+                </div>
+              <div class="cell" style="width: 86px;">
+                  <input class="white text-black readonly" id="infomaxinterruptionhours" name="infomaxinterruptionhours" style="width: 60px;" type="text" value=""> <label class="label" for=
+                  "infomaxinterruptionhours">max coupure</label>
+                </div>
+                <div class="cell" style="width: 120px;">
+                  <input class="white text-black readonly" id="infomindailyrecuperation" name="infomindailyrecuperation" style="width: 60px;" type="text" value=""> <label class="label" for=
+                  "infomindailyrecuperation">min heures libre quotidienne</label>
+                </div>
+                <div class="cell" style="width: 100px;">
+                  <input class="white text-black readonly" id="infomaxweekhours" name="infomaxweekhours" style="width: 60px;" type="text" value=""> <label class="label" for=
+                  "infomaxweekhours">max heures par semaine</label>
+                </div>
+              </fieldset>
+              <fieldset>
+                <legend style="font-weight: bold;">Totaux Jour</legend>
                 <div class="cell" style="width: 86px;">
-                  <input class="data_staffreportperioddays white text-black readonly" id="workhours" name="staffreportperioddays_workhours" style="width: 60px;" type="text" value=""> <label class="label" for=
-                  "staffreportperioddays_workhours">travail</label>
+                  <input class="data_staffreportperioddays white text-black readonly" id="workhours" name="staffreportperioddays_workhours" style="width: 60px;font-weight: bold;" type="text" value=""> <label class="label" for=
+                  "staffreportperioddays_workhours" style="font-weight: bold;">Total travail</label>
                 </div>
                 <div class="cell" style="width: 86px;">
                   <input class="data_staffreportperioddays white text-black readonly" id="timepause" name="staffreportperioddays_timepause" style="width: 60px;" type="text" value=""> <label class="label" for=
-                  "staffreportperioddays_timepause">pause</label>
+                  "staffreportperioddays_timepause">Total pause</label>
                 </div>
+                
                 <div class="cell" style="width: 86px;">
-                  <input class="data_staffreportperioddays white text-black readonly" id="interruptionhours" name="staffreportperioddays_interruptionhours" style="width: 60px;" type="text" value=""> <label class="label" for=
-                  "staffreportperioddays_interruptionhours">coupure</label>
+                  <input class="data_staffreportperioddays white text-black readonly wdaytotal" id="dayhours" name="staffreportperioddays_dayhours" style="width: 60px;font-weight: bold;" type="text" value=""> <label class="label" for="staffreportperioddays_dayhours" style="font-weight: bold;">Total jour</label>
                 </div>
                 <div class="cell" style="width: 86px;">
-                  <input class="data_staffreportperioddays white text-black readonly wdaytotal" id="dayhours" name="staffreportperioddays_dayhours" style="width: 60px;" type="text" value=""> <label class="label" for=
-                  "staffreportperioddays_dayhours">total jour</label>
+                  <input class="data_staffreportperioddays white text-black readonly" id="interruptionhours" name="staffreportperioddays_interruptionhours" style="width: 60px;" type="text" value=""> <label class="label" for=
+                  "staffreportperioddays_interruptionhours">coupure</label>
                 </div>
               </fieldset>
+              
             </div>
           </div>
         </div>
index b4daa1c..50f1a95 100644 (file)
@@ -1,4 +1,4 @@
-[% appversion = '0.9.14' %]
+[% appversion = '0.9.14.2' %]
 [% minify = '' %]
 <!DOCTYPE html>
 <html lang="fr">
index e996eb6..2b646ad 100644 (file)
@@ -214,6 +214,7 @@ let staffperiodweeks = {
           document.getElementById("infofreetimebefore").value=data.result.tiembefore;
           document.getElementById("infofreetimeafter").value=data.result.timeafter;
           staffperiodweeks.calcfreetime();
+          staffperiodweeks.checkworktime();
         } 
         app.viewdialog('staffreportperioddays');
       }).catch(e => {console.log(e)});
@@ -276,7 +277,7 @@ let staffperiodweeks = {
         document.getElementById("vacancyhours").value=staffperiodweeks.currentday.contracthours;
       }
     }
-    staffperiodweeks.checkdaytime();
+    staffperiodweeks.checkdaytime(document.getElementById("vacancyhours"));
   },
   setrecuperationhours: function(){
     if (!staffperiodweeks.choices["id_recuperationtype"].selected()){
@@ -286,9 +287,13 @@ let staffperiodweeks = {
         document.getElementById("recuperationhours").value=staffperiodweeks.currentday.contracthours;
       }
     }
-    staffperiodweeks.checkdaytime();
+    staffperiodweeks.checkdaytime("id_recuperationtype");
   },
   checkworktime: function(id){
+    if (id){
+      timecalc.validateTime(document.getElementById(id));
+    }
+    
     staffperiodweeks.disablesave=false;
     let mt1 = 0;let mt2 = 0;let mtp1 = 0;let mtp2 = 0;let mtp = 0;
     let s1 = 0;let e1=0;let s2 = 0;let e2=0;
@@ -306,6 +311,10 @@ let staffperiodweeks = {
     let oirupt = document.getElementById("interruptionhours");
     let owkh = document.getElementById("workhours");
     let ppy = document.getElementById("payedpause");
+    let odt1 = document.getElementById("total1");
+    let odt2 =document.getElementById("total2");
+    let opt1 =document.getElementById("pausetotal1");
+    let opt2 =document.getElementById("pausetotal2");
     let msg = "";
     
     if (ode1.value && ods1.value){
@@ -314,6 +323,7 @@ let staffperiodweeks = {
       if (e1 < s1) {e1 = e1 + 1440;}
       
       mt1 = e1-s1;
+      odt1.value=timecalc.MinutesToTime(mt1);
     }
     if (ode2.value && ods2.value){
       s2 = timecalc.TimeToMinutes(ods2.value);
@@ -321,6 +331,7 @@ let staffperiodweeks = {
       if (e2 < s2) {e2 = e2 + 1440;}
       //("H2 " + e2 + " - " + s2);
       mt2 = e2-s2;
+      odt2.value=timecalc.MinutesToTime(mt2);
     }
     if (ope1.value && ops1.value){
       ps1 = timecalc.TimeToMinutes(ops1.value);
@@ -329,6 +340,7 @@ let staffperiodweeks = {
         pe1 = pe1 + 1440;
       }
       mtp1 = pe1-ps1;
+      opt1.value=timecalc.MinutesToTime(mtp1);
       if (ps1 < s1){
         staffperiodweeks.disablesave = true;
         msg = "les pauses doivent être dans les heures de travail!";
@@ -343,6 +355,7 @@ let staffperiodweeks = {
       pe2 = timecalc.TimeToMinutes(ope2.value);
       if (pe2 < ps2) {pe2 = pe2 + 1440;}
       mtp2 = pe2-ps2;
+      opt2.value=timecalc.MinutesToTime(mtp2);
       if (ps2 < s2){
         staffperiodweeks.disablesave = true;
         msg = "les pauses doivent être dans les heures de travail!";
@@ -375,18 +388,28 @@ let staffperiodweeks = {
       oirupt.classList.add("text-black");
       oirupt.value="00:00";
     }
-    //console.log(mt1 + " + " + mt2);
+    console.log(mt1 + " + " + mt2);
     if ((ppy.checked) && (ppy.checked === true)){
-      owkh.value= timecalc.MinutesToTime(mt1+mt2);
-      console.log(mt1 + " + " + mt2);
+      let mtall = mt1+mt2;
+      // console.log("pause payed!");
+      // console.log("minutes: " + mtall);
+      // console.log(mt1 + " + " + mt2);
+      owkh.value= timecalc.MinutesToTime(mtall);
     } else {
-      owkh.value= timecalc.MinutesToTime(mt1+mt2-mtp);
-      console.log(mt1 + " + " + mt2 - " - " + mtp);
+      let mtall = mt1+mt2-mtp;
+      // console.log("pause not payed!");
+      // console.log("minutes: " + mtall);
+      // console.log(mt1 + " + " + mt2 + " - " + mtp);
+      owkh.value= timecalc.MinutesToTime(mtall);
+      
     }
     
     staffperiodweeks.checkdaytime();
   },
-  checkdaytime: function(){
+  checkdaytime: function(obj){
+    if (obj){
+      timecalc.validateTime(obj.value);
+    }
     let wktime = 0;
     let vactime = 0;
     let reptime = 0;
index 12f02ab..4d75be7 100644 (file)
@@ -56,23 +56,7 @@ let workplans ={
       columns: [
       { title: "jour",field: "weekday",formatter:wdayFormatter,headerSort: false  },
       { title: "heures de<br/>travail",field: "dspworkdata",headerSort: false,hozAlign:"center",formatter:sizeFormatter},
-      // { title: "heures de travail",
-      //   columns: [
-      //     { title: "début 1",field: "start1",width: 80,headerSort: false },
-      //     { title: "fin 1",field: "end1",width: 80,headerSort: false },
-      //     { title: "début 2",field: "start2",width: 80,headerSort: false },
-      //     { title: "fin 2",field: "end2",width: 80,headerSort: false }
-      //   ]
-      // },
       { title: "heures de<br/>pause",field: "dsppausedata",headerSort: false,hozAlign:"center",formatter:sizeFormatter},
-      // { title : "pauses",
-      //   columns:[
-      //     { title: "début 1",field: "pausestart1",width: 80,headerSort: false },
-      //     { title: "fin 1",field: "pauseend1",width: 80,headerSort: false },
-      //     { title: "début 2",field: "pausestart2",width: 80,headerSort: false },
-      //     { title: "fin 2",field: "pauseend2",width: 80,headerSort: false },
-      //   ]
-      // },
       { title: "total<br/>pause",field: "pause",width: 80,headerSort: false }, 
       { title: "coupure",field: "interruption",width: 90,headerSort: false}, 
       { title: "total<br/>travail",field: "dayhours",width: 80,formatter:boldFormatter,headerSort: false,bottomCalc:workplans.weekhourssum },  
@@ -236,7 +220,7 @@ let workplans ={
     return false;
   },
   checktime: function(id){
-    console.log("checktime ID",id);
+    //console.log("checktime ID",id);
     timecalc.validateTime(document.getElementById(id));
     workplans.disablesave =false;
     let mt1 = 0;let mt2 = 0;let mtp1 = 0;let mtp2 = 0;let mtp = 0;
@@ -254,8 +238,8 @@ let workplans ={
     let odp = document.getElementById("pause");
     let odt1 = document.getElementById("total1");
     let odt2 =document.getElementById("total2");
-    let opt1 =document.getElementById("totalpause1");
-    let opt2 =document.getElementById("totalpause2");
+    let opt1 =document.getElementById("pausetotal1");
+    let opt2 =document.getElementById("pausetotal2");
     let oirupt = document.getElementById("interruptionhours");
     let owkh = document.getElementById("dayhours");
     let msg = "";
@@ -284,6 +268,7 @@ let workplans ={
         pe1 = pe1 + 1440;
       }
       mtp1 = pe1-ps1;
+      //console.log(mtp1);
       opt1.value=timecalc.MinutesToTime(mtp1);
       if (ps1 < s1){
         workplans.disablesave = true;
@@ -345,6 +330,7 @@ let wdayFormatter = function(cell, formatterParams){
 };
 
 let boldFormatter = function(cell, formatterParams){
+  if (cell.getValue() == "00:00"){ return "";}
   cell.getElement().style.fontWeight="bold";return cell.getValue();
 };
 
index 1674b68..71c9fab 100644 (file)
@@ -39,24 +39,27 @@ function createWindow () {
   console.log("loding URL:" + appcfg.host)
   mainWindow.loadURL(appcfg.host,{userAgent: ua});
   if (os.platform() == "darwin"){
-    console.log("Set Menu")
-    const template = []
-      template.unshift({
-        label: app.getName(),
-        submenu: [
-          {role: 'about'},
-          {type: 'separator'},
-          {role: 'services', submenu: []},
-          {type: 'separator'},
-          {role: 'hide'},
-          {role: 'hideothers'},
-          {role: 'unhide'},
-          {type: 'separator'},
-          {role: 'quit'}
-        ]
-      })
-    const menu = Menu.buildFromTemplate(template)
-    Menu.setApplicationMenu(menu)
+    // console.log("Set Menu")
+    let template = [{
+      label: "Application",
+      submenu: [
+          { label: "About Application", selector: "orderFrontStandardAboutPanel:" },
+          { type: "separator" },
+          { label: "Quit", accelerator: "Command+Q", click: function() { app.quit(); }}
+      ]}, {
+      label: "Edit",
+      submenu: [
+          { label: "Undo", accelerator: "CmdOrCtrl+Z", selector: "undo:" },
+          { label: "Redo", accelerator: "Shift+CmdOrCtrl+Z", selector: "redo:" },
+          { type: "separator" },
+          { label: "Cut", accelerator: "CmdOrCtrl+X", selector: "cut:" },
+          { label: "Copy", accelerator: "CmdOrCtrl+C", selector: "copy:" },
+          { label: "Paste", accelerator: "CmdOrCtrl+V", selector: "paste:" },
+          { label: "Select All", accelerator: "CmdOrCtrl+A", selector: "selectAll:" }
+      ]}
+  ];
+    
+    Menu.setApplicationMenu(Menu.buildFromTemplate(template))
   } else {
     mainWindow.setMenu(null)
   }