v20210118 pwa added
authorKilian Saffran <ksaffran@dks.lu>
Mon, 18 Jan 2021 15:16:19 +0000 (16:16 +0100)
committerKilian Saffran <ksaffran@dks.lu>
Mon, 18 Jan 2021 15:16:19 +0000 (16:16 +0100)
16 files changed:
app/db.cgi
app/index.cgi
app/lib/POT/Period.pm
app/lib/session.pm
app/manifest.json [new file with mode: 0644]
app/static/img/favicon/manifest.json
app/static/js/app.js
app/static/js/app.min.js
app/static/js/request.js
app/static/js/sw.js [new file with mode: 0644]
app/tmpl/index.tt
app/tmpl/lang/de.tt
app/tmpl/lang/fr.tt
app/tmpl/module/periods.tt
app/tmpl/module/periods/reportperiod.js
app/tmpl/module/workplans/workplans.js

index f277700..e24935f 100644 (file)
@@ -64,7 +64,7 @@ if (($cgi->request_method() eq "GET") || ($cgi->request_method() eq "POST")){
     if (exists($p->{schemata})){
       $schema = $db->securetext($p->{schemata});
     }
-    if ($p->{get} =~ /periods$|periodweeksums$|perioddays$|perioddata$|staffperiods$|staffperiodsgrouped$|staffperiodsplitted$|defaultdaylimits$/){
+    if ($p->{get} =~ /periods$|periodweeksums$|perioddays$|perioddata$|staffperiods$|staffperiodsgrouped$|staffperiodsplitted$|defaultdaylimits$|lastperioddates$/){
       my $period = POT::Period->new({db => $db});
       if ($p->{get} eq 'periods'){
         $hres = $period->getPeriods($schema);
@@ -94,6 +94,9 @@ if (($cgi->request_method() eq "GET") || ($cgi->request_method() eq "POST")){
       elsif ($p->{get} eq "defaultdaylimits"){
         $hres = $period->getDefaultDayLimits($schema);
       }
+      elsif ($p->{get} eq "lastperioddates"){
+        $hres = $period->getLastPeriodDates($schema);
+      }
     } elsif ($p->{get} =~ /company$|companiesdata$|staffgroups$|staffgroup$|sectors$|allschemalist$|companysize$|vacancydays$|gvacancytypes$|sectordata$/){
       my $cp = POT::Company->new({db => $db});
       if ($p->{get} eq 'companiesdata'){
@@ -188,7 +191,7 @@ if (($cgi->request_method() eq "GET") || ($cgi->request_method() eq "POST")){
       }
     }
     
-    if ($p->{get} !~ /periodweeksums$|staffperiodsgrouped$|company$|workplan$|workplanday$|worktime$|staffcontract$|staff$|staffgroup$|defaultdaylimits$|termsstatus$|user$/ ){
+    if ($p->{get} !~ /periodweeksums$|staffperiodsgrouped$|company$|workplan$|workplanday$|worktime$|staffcontract$|staff$|staffgroup$|defaultdaylimits$|termsstatus$|user$|lastperioddates$/ ){
       foreach my $r (sort {$a <=> $b} keys(%{$hres})){
         push(@retdata,$hres->{$r});
       }
index adc7b83..1d6283a 100644 (file)
@@ -25,10 +25,10 @@ my $sess = ();
 my $se = session->new({db => $db});
 
 $vars->{ua} = $ENV{HTTP_USER_AGENT};
-if (($vars->{ua} !~ /^POT/) && ($vars->{ua} !~ /iPad/)){
-     print "Location: https://www.plandutravail.lu\n\n";
-     exit(0);
-}
+if (($vars->{ua} !~ /^POT/) && ($vars->{ua} !~ /iPad/)){
+     print "Location: https://www.plandutravail.lu\n\n";
+     exit(0);
+}
 $vars->{realpath} = $cgi->url({-absolute=>1});
 $vars->{filepath} = substr($cgi->url({-absolute=>1}),length($vars->{basepath})+1); 
 $vars->{baseurl} = $cgi->url({-base=>1}).'/'.$vars->{basepath};
@@ -48,7 +48,7 @@ $vars->{abspath} = "";
 
 
 $p->{sid} = $cgi->cookie($vars->{cookiename});
-print STDERR "cookie: ".$vars->{cookiename}." : ".$p->{sid}."\n--\n";
+#print STDERR "cookie: ".$vars->{cookiename}." : ".$p->{sid}."\n--\n";
 if ($cgi->request_method() eq "GET"){
   my @params = $cgi->param();
   foreach my $pp (@params){
@@ -95,7 +95,7 @@ if (($cgi->request_method() eq "POST") || ($cgi->request_method() eq "GET")){
 }
 if ($p->{sid} ne ""){
   $sess = $se->getsession($p->{sid});
-  print STDERR "after sessioncheck:".Dumper($sess);
+  #print STDERR "after sessioncheck:".Dumper($sess);
   if ($sess == undef){
     $p->{sid} = "";
     $skl = "login.tt";
index cb8e8b2..dbb0c8f 100644 (file)
@@ -754,4 +754,11 @@ sub invalidatePeriod(){
   return 1;
 }
 
+sub getLastPeriodDates(){
+  my $self = shift;
+  my $schema = shift;
+  my $sql = "select max(startdate) as startdate,max(enddate) as enddate,case when date(max(startdate) - interval '1 year') < current_date then null else date(max(startdate) - interval '1 year') end as alloweddate from ".$schema.".reportperiod;";
+  return $self->{db}->query($sql);
+}
+
 1;
\ No newline at end of file
index 0cca33e..5823ade 100644 (file)
@@ -98,7 +98,7 @@ sub getsession($){
   my $sql = "select se.id as idsession,us.lang,us.id,us.username,ugrp.id as usergroup,us.id_staffgroups as staffgroups,se.sessiondata from sessions se 
 join users us on (us.id=se.id_user)
 left join usergroups ugrp on (ugrp.id=us.id_usergroup)
-where se.id= '".$self->{db}->securetext($sid)."' and se.remote_addr= '".$ENV{REMOTE_ADDR}."' and (se.user_agent LIKE '".'%POT%'."' OR se.user_agent LIKE ''".'%iPad%'."'') and 
+where se.id= '".$self->{db}->securetext($sid)."' and se.remote_addr= '".$ENV{REMOTE_ADDR}."' and (se.user_agent LIKE '".'%POT%'."' OR se.user_agent LIKE '".'%iPad%'."') and 
 us.isblocked is null group by se.id,us.id,ugrp.id;";
  #and se.user_agent LIKE 'POT/%/%/%'
   my $res= $self->{db}->querysorted($sql);
diff --git a/app/manifest.json b/app/manifest.json
new file mode 100644 (file)
index 0000000..8e1a4ea
--- /dev/null
@@ -0,0 +1,47 @@
+{
+ "name": "POT",
+ "short_name": "POT",
+ "icons": [
+  {
+   "src": "/img/favicon/android-icon-36x36.png",
+   "sizes": "36x36",
+   "type": "image/png",
+   "density": "0.75"
+  },
+  {
+   "src": "/img/favicon/android-icon-48x48.png",
+   "sizes": "48x48",
+   "type": "image/png",
+   "density": "1.0"
+  },
+  {
+   "src": "/img/favicon/android-icon-72x72.png",
+   "sizes": "72x72",
+   "type": "image/png",
+   "density": "1.5"
+  },
+  {
+   "src": "/img/favicon/android-icon-96x96.png",
+   "sizes": "96x96",
+   "type": "image/png",
+   "density": "2.0"
+  },
+  {
+   "src": "/img/favicon/android-icon-144x144.png",
+   "sizes": "144x144",
+   "type": "image/png",
+   "density": "3.0"
+  },
+  {
+   "src": "/img/favicon/android-icon-192x192.png",
+   "sizes": "192x192",
+   "type": "image/png",
+   "density": "4.0"
+  }
+ ],
+ "start_url":"/index.html",
+ "background_color":"#52638e",
+ "theme_color":"#52638e",
+ "display":"standalone",
+ "orientation":"portrait"
+}
\ No newline at end of file
index 013d4a6..bf7254f 100644 (file)
@@ -1,41 +1,47 @@
 {
- "name": "App",
+ "name": "POT",
+ "short_name": "POT",
  "icons": [
   {
-   "src": "\/android-icon-36x36.png",
+   "src": "/img/favicon/android-icon-36x36.png",
    "sizes": "36x36",
-   "type": "image\/png",
+   "type": "image/png",
    "density": "0.75"
   },
   {
-   "src": "\/android-icon-48x48.png",
+   "src": "/img/favicon/android-icon-48x48.png",
    "sizes": "48x48",
    "type": "image\/png",
    "density": "1.0"
   },
   {
-   "src": "\/android-icon-72x72.png",
+   "src": "/img/favicon/android-icon-72x72.png",
    "sizes": "72x72",
    "type": "image\/png",
    "density": "1.5"
   },
   {
-   "src": "\/android-icon-96x96.png",
+   "src": "/img/favicon/android-icon-96x96.png",
    "sizes": "96x96",
    "type": "image\/png",
    "density": "2.0"
   },
   {
-   "src": "\/android-icon-144x144.png",
+   "src": "/img/favicon/android-icon-144x144.png",
    "sizes": "144x144",
    "type": "image\/png",
    "density": "3.0"
   },
   {
-   "src": "\/android-icon-192x192.png",
+   "src": "/img/favicon/android-icon-192x192.png",
    "sizes": "192x192",
    "type": "image\/png",
    "density": "4.0"
   }
- ]
+ ],
+ "start_url":"/index.html",
+ "background_color":"#52638e",
+ "theme_color":"#52638e",
+ "display":"standalone",
+ "orientation":"portrait"
 }
\ No newline at end of file
index 04b663d..d789c71 100644 (file)
@@ -68,3 +68,12 @@ document.addEventListener("DOMContentLoaded", function() {
   moment.locale('fr');\r
   initpage();\r
 });\r
+\r
+if ("serviceWorker" in navigator) {\r
+  window.addEventListener("load", function() {\r
+    navigator.serviceWorker\r
+      .register("/static/js/sw.js")\r
+      .then(res => console.log("service worker registered"))\r
+      .catch(err => console.log("service worker not registered", err))\r
+  })\r
+}\r
index 08ec326..b21a478 100644 (file)
@@ -1 +1,8 @@
-let app={loadpage:function(modulepage,modulename){location.href=modulepage},logout:function(){postData(location.href,{logout:"1"}).then(data=>{location.href="login.html"})},reloadpage(){},changedataset:function(){},getCurrentSchemata:function(){return schemata},changedataset:function(){let csel=document.getElementById("current_schemata").value;schemata=csel,postData("db.cgi",{fn:"setsessiondata",params:{schemata:csel}}).then(data=>{document.getElementById("current_schemata").dataset.selected=csel})},setschemata(data){},reload_page:function(){location.href=location.href},viewpanel:function(pnlname){let panels=document.getElementsByClassName("panel"),toolbars=document.getElementsByClassName("paneltoolbar");currentview=pnlname;for(let p=0;p<panels.length;p++)panels[p].style.display="none";for(let p=0;p<toolbars.length;p++)toolbars[p].style.display="none";return document.getElementById("pnl_"+pnlname)&&(document.getElementById("pnl_"+pnlname).style.display="block"),document.getElementById("tlb_"+pnlname)&&(document.getElementById("tlb_"+pnlname).style.display="block"),!1},viewdialog:function(dlgname){document.getElementById("dlg_"+dlgname)&&(document.getElementById("dlg_"+dlgname).style.display="block")},opendlg:function(dlgname,msgdata,callback){for(var x in msgdata)document.getElementById(dlgname+x)&&(document.getElementById(dlgname+x).innerHTML=msgdata[x]);callback&&(document.getElementById(dlgname+"_button")&&document.getElementById(dlgname+"_button").addEventListener("click",callback,!0),document.getElementById(dlgname+"_button")&&document.getElementById(dlgname+"_button").addEventListener("click",callback,!0))},closedlg:function(dlgid){document.getElementById(dlgid).style.display="none"}};document.addEventListener("DOMContentLoaded",(function(){moment.locale("fr"),initpage()}));
\ No newline at end of file
+let app={loadpage:function(e,t){location.href=e},logout:function(){postData(location.href,{logout:"1"}).then(e=>{location.href="login.html"})},reloadpage(){},changedataset:function(){},getCurrentSchemata:function(){return schemata},changedataset:function(){let e=document.getElementById("current_schemata").value
+schemata=e,postData("db.cgi",{fn:"setsessiondata",params:{schemata:e}}).then(t=>{document.getElementById("current_schemata").dataset.selected=e})},setschemata(e){},reload_page:function(){location.href=location.href},viewpanel:function(e){let t=document.getElementsByClassName("panel"),n=document.getElementsByClassName("paneltoolbar")
+currentview=e
+for(let e=0;e<t.length;e++)t[e].style.display="none"
+for(let e=0;e<n.length;e++)n[e].style.display="none"
+return document.getElementById("pnl_"+e)&&(document.getElementById("pnl_"+e).style.display="block"),document.getElementById("tlb_"+e)&&(document.getElementById("tlb_"+e).style.display="block"),!1},viewdialog:function(e){document.getElementById("dlg_"+e)&&(document.getElementById("dlg_"+e).style.display="block")},opendlg:function(e,t,n){for(var o in t)document.getElementById(e+o)&&(document.getElementById(e+o).innerHTML=t[o])
+n&&(document.getElementById(e+"_button")&&document.getElementById(e+"_button").addEventListener("click",n,!0),document.getElementById(e+"_button")&&document.getElementById(e+"_button").addEventListener("click",n,!0))},closedlg:function(e){document.getElementById(e).style.display="none"}}
+document.addEventListener("DOMContentLoaded",function(){moment.locale("fr"),initpage()}),"serviceWorker"in navigator&&window.addEventListener("load",function(){navigator.serviceWorker.register("/static/js/sw.js").then(e=>void 0).catch(e=>void 0)})
index 2eba8bb..0724d1c 100644 (file)
@@ -17,7 +17,10 @@ async function postData(url = '', data = {}) {
     body: JSON.stringify(data) 
   });
   
-  return response.json();
+  //console.log(response.text());
+  var x = response.json();
+  if (x) { return x;}
+  return {};
 }
 
 var report ={
diff --git a/app/static/js/sw.js b/app/static/js/sw.js
new file mode 100644 (file)
index 0000000..e3e5d96
--- /dev/null
@@ -0,0 +1,21 @@
+const staticpot = "pot"
+const assets = [
+  "/",
+  "/index.html"
+]
+
+self.addEventListener("install", installEvent => {
+  installEvent.waitUntil(
+    caches.open(staticpot).then(cache => {
+      cache.addAll(assets)
+    })
+  )
+})
+
+self.addEventListener("fetch", fetchEvent => {
+  fetchEvent.respondWith(
+    caches.match(fetchEvent.request).then(res => {
+      return res || fetch(fetchEvent.request)
+    })
+  )
+})
\ No newline at end of file
index cd18c85..cea6cf4 100644 (file)
@@ -1,4 +1,4 @@
-[% appversion='1.0.28' %]
+[% appversion='1.0.28dev2' %]
 [% minify = '' %]
 [% PROCESS "lang/${lang}.tt" %]
 <!DOCTYPE html>
index aa78a89..b75f96b 100644 (file)
   "pwdcondition" => "Passwörter müssen mindstens 10 Zeichen lang seien und mindestens 1 Grossbuchstabe, 1 Klein-Buchstabe und 1 Zahl enthalten",\r
   "genpwd" => "Passwort vorschlagen",\r
   "usergroup" => "Berechtigungen",\r
-  "language" => "Sprache"\r
+  "language" => "Sprache",\r
+  "msgdeldefworkplan" => "Der Standard Wochenplan kann nicht gelöscht werden!",\r
+  "msgdelusedworkplan" => "Solange ein Plan für einen Mitarbeiter eingetragen ist, kann er nicht gelöscht werden!",\r
+  "msgaddperiod" => "Sie können keine Periode mehr vor folgendem Datum hinzufügen: "\r
  } %]
\ No newline at end of file
index 0942977..1c6f9e3 100644 (file)
   "pwdcondition" => "les mots de passes doivent contenir au moins 10 lettres , au moins une lettre majuscule, une lettre minuscule et un nombre",
   "genpwd" => "Passwort vorschlagen",
   "usergroup" => "Droits d'accès",
-  "language" => "Langue"
+  "language" => "Langue",
+  "msgdeldefworkplan" => "Le plan Standard ne peut pas être supprimé!",
+  "msgdelusedworkplan" => "Le plan ne peut pas être supprimé dès qu'il est utilisé par un salarié",
+  "msgaddperiod" => "vous ne pouvez plus ajouter des périodes avant le: "
  } %]
\ No newline at end of file
index 13bff82..d00c254 100644 (file)
@@ -5,14 +5,14 @@
      <a class="bar-item toolbarbtn" href="[% abspath %]index.html"><span class="icon icon-back" style="font-size: 16px;"></span>[% lbl.back %]</a>
       <div class="bar-item PageHeadTitle">[% lbl.refperiods %]</div>
       <div class="toolbar paneltoolbar" id="tlb_periods">
-      <button class="bar-item toolbarbtn  right" onclick="reportperiod.add();"><span class="icon icon-plus" style="font-size: 16px;"></span>[% lbl.add %]</button> 
-      <button class="bar-item toolbarbtn right" onclick="reportperiod.editplan();"><span class="icon icon-edit" style="font-size: 16px;"></span>[% lbl.edit %]</button>
-       <button class="bar-item toolbarbtn right" onclick="reportperiod.generatereport();"><span class="icon icon-pdf" style="font-size: 16px;"></span>[% lbl.pdf %]</button>
+      <button class="bar-item toolbarbtn  right" onclick="reportperiod.add();return false;"><span class="icon icon-plus" style="font-size: 16px;"></span>[% lbl.add %]</button> 
+      <button class="bar-item toolbarbtn right" onclick="reportperiod.editplan();return false;"><span class="icon icon-edit" style="font-size: 16px;"></span>[% lbl.edit %]</button>
+       <button class="bar-item toolbarbtn right" onclick="reportperiod.generatereport();return false;"><span class="icon icon-pdf" style="font-size: 16px;"></span>[% lbl.pdf %]</button>
       [% IF session.usergroup == 'admin' %]
-      <button class="bar-item toolbarbtn right red" onclick="reportperiod.datarefresh();"><span class="icon icon-datarefresh" style="font-size: 16px;"></span>actualiser</button>
+      <button class="bar-item toolbarbtn right red" onclick="reportperiod.datarefresh();return false;"><span class="icon icon-datarefresh" style="font-size: 16px;"></span>actualiser</button>
       [% END %]
       [% IF session.usergroup != 'teamleader' %]
-      <button class="bar-item toolbarbtn right" onclick="periodvalidation.showdlg();"><span class="icon icon-pay" style="font-size: 16px;"></span>[% lbl.finalstatement %]</button>
+      <button class="bar-item toolbarbtn right" onclick="periodvalidation.showdlg();return false;"><span class="icon icon-pay" style="font-size: 16px;"></span>[% lbl.finalstatement %]</button>
       [% END %]
   <!--<button class="bar-item toolbarbtn  right" onclick="staff.remove();"><span class="icon icon-remove text-red" style="font-size: 16px;"></span>[% lbl.delete %]</button>
   <button class="bar-item toolbarbtn  right" onclick="staff.edit();"><span class="icon icon-edit" style="font-size: 16px;">[% lbl.edit %]</button>-->
index fc0ea13..38fe2dd 100644 (file)
@@ -128,7 +128,7 @@ let reportperiod ={
           reportperiod.tbl.setData(data.result.sqldata);
         }
       });
-      
+      //return false;
     } else {
       reportperiod.tbl.setData([]);
       reportperiod.tblsplitted.setData([]);
@@ -147,16 +147,22 @@ let reportperiod ={
     app.viewpanel('tbl_reportperiod');
   },
   add: function(){
-    let act = {};
-    act["fn"] = "add_reportperiod";
-    act["schemata"] = schemata;
-    showinfodlg("Ajouter Période de référence","Ajouter prochaine periode?",reportperiod.afteraddconfirm,act,"<span class=\"icon-Save\"></span>[% lbl.add %]","<span class=\"icon-remove\"></span>[% lbl.cancel %]");
-    return false;
+    postData("db.cgi",{"get":"lastperioddates","schemata":schemata}).then(data => {
+      console.log("data",data);
+      if (data.result.data.alloweddate != null){
+        showmessagedlg("Info","[% lbl.msgaddperiod %] "+ moment(data.result.data.alloweddate).format('DD.MM.YYYY'));
+      } else {
+        postData("db.cgi",{"fn":"add_reportperiod","schemata":schemata}).then(nrepid => {
+          console.log(nrepid);
+          reportperiod.gettbldata();
+        }).catch(err => { console.log(err)});
+        
+      }
+
+    }).catch(err => { console.log(err)});
   },
-  afteraddconfirm(data){
-    postData("db.cgi",data).then(data => {
-      reportperiod.gettbldata();
-    });
+  afteraddconfirm(){
+    
   },
   generatereport: function(){
 
index eb0a7a7..f765367 100644 (file)
@@ -143,11 +143,13 @@ let workplans ={
   remove: function(){
     let udata = workplans.tblfilter.getSelectedData();
     if (udata[0].isdefault){
-      showmessagedlg("Info","Le plan Standard ne peut pas être supprimé!");
+
+  
+      showmessagedlg("Info","[% lbl.msgdeldefworkplan %]");
       return false;
     }
     if (parseInt(udata[0].staffcount) > 0){
-      showmessagedlg("Info","Le plan ne peut pas être supprimé dès qu'il est utilisé par un salarié");
+      showmessagedlg("Info","[% lbl.msgdelusedworkplan %]");
       return false;
     }
     if (udata[0]) {