Jak řešit správné vykreslování deshboardu

jAkErCZ
Člen | 322
+
0
-

Zdravím,
Aktuálně mám deshboard ve kterém si přes metodu renderDefault() vykrasluji nějaké data. A rád bych si dodělal možnost že si uživatel vybere měsíc a rok a po odeslání mu to vykreslí data z měsíce a roku který si vybral.

Došel jsem až do fáze kdy mám pomocí js odelání data do metody

což mi vrátí data které potřebuji ale již mi to nepřekreslí abych je vyděl v šabloně. Proto sem se chtěl zeptat jak co nejednodušeji bych toto mohl řešit?

Zde přikládám presenter

/**
 * Uvodní statika v intranetu
 */
public function renderDefault()
{
    $price = 0;
    $max_price = false;
    $order_price = 0;
    $max_order_price = false;
    $cont = 0;
    $noContract_price = 0;
    $user_role = $this->getUser()->isInRole('admin') || $this->getUser()->isInRole('lead');

    $all_projects = $this->projectManager->getProjectsToMoth($this->getUser()->id,'price, client_id', $user_role);
    $order_projects = $this->projectManager->getProjectsAllContractsStatus($this->getUser()->id,'price, client_id', $user_role);
    $noContracts_projects = $this->projectManager->getProjectsNoContractWithUserID($this->getUser()->id,'price, client_id',  $user_role);
    $contracts = $this->projectManager->getContractsWithAllStatus('price,user_id');
    $setting = $this->settingManager->getSettings();
    $identity = $this->getUser()->getIdentity();
    $member = $this->userManager->getUser($identity->getData()['user_id']);

    if ($identity)
        $this->template->username = $identity->getData()['email'];

    foreach ($all_projects as $project){
        $price += $project['price'];
        $max_price =  max($all_projects);
    }
    foreach ($order_projects as $order_project){
        $order_price += $order_project['price'];
        $max_order_price =  max($order_projects);
    }
    foreach ($contracts as $contract){
        $cont += $contract['price'];
    }
    foreach ($noContracts_projects as $noCotract){
        $noContract_price += $noCotract['price'];
    }
    $this->template->price = $price;
    $this->template->max_price = $max_price;
    $this->template->order_price = $order_price;
    $this->template->contrac = $cont;
    $this->template->max_order_price = $max_order_price;
    $this->template->noContract_price = $noContract_price;
    $this->template->setting = $setting;
    $this->template->member = $member;
}

/**
 * @throws \Nette\Application\AbortException
 */
public function ActionChart(){
    $users = $this->userManager->getMembers();

    $data = [];
    foreach ($users as $row) {
        $order_projects = $this->projectManager->getProjectsGraph($row['user_id']);
        $data[] = [
            'user_id' => $row['name'],
            'score' => $order_projects
        ];
    }
    usort($data, function (array $a, array $b) {
        return $b['score'] <=> $a['score'];
    });
    return $this->sendJson($data);
}

public function handleUpdateDashboard(){
    $select = new DateTime($_POST['date']);
    $user_role = $this->getUser()->isInRole('admin') || $this->getUser()->isInRole('lead');
    $this->projectManager->getProjectsToMoth($this->getUser()->id,'price, client_id', $user_role, $select->format('Y-m'));
    if ($this->isAjax()){
        $this->redrawControl('cont');
    }else{
        $this->flashMessage('Nefunguje',self::MSG_ERROR);
    }
    $this->terminate();
}

a šablonu

{if !$user->isInRole('technik')}
    <div n:if="$user->isInRole('admin')" class="row">
        <div class="col-lg-2 col-md-2">
            <section class="widget text-white">
                <input id="event_date" type="text" class="form-control ajax" value="{="now"|date:'Y-m'}" onselect="$('#frmDate').submit()";>
            </section>
        </div>
    </div>
    <div n:snippet="cont" class="col-lg-4 col-md-3 ajax">
        <section class="widget widget-card bg-primary text-white">
            <div class="widget-body clearfix">
                <div class="row">
                    <div class="col-xs-3">
                                <span class="widget-icon">
                                    <i class="glyphicon glyphicon-book"></i>
                                </span>
                    </div>
                    <div class="col-xs-9">
                        <h6 class="no-margin">Celkem v nabídkách za tento měsíc</h6>
                        <p class="h2 no-margin fw-normal">{$price|number:0:',':'.'} Kč</p>
                    </div>
                </div>
                <div class="row">
                    <div class="col-xs-9">
                        <h6 class="no-margin">Největší nabídka v měsíci</h6>
                        <p class="value5">{if $max_price}{$max_price->client['name']} - {$max_price['price']|number:0:',':'.'} Kč {else} Žádná nabídka nalezena{/if}</p>
                    </div>
                </div>
            </div>
        </section>
    </div>
    <div class="col-lg-4 col-md-3">
        <section class="widget widget-card bg-success text-white">
            <div class="widget-body clearfix">
                <div class="row">
                    <div class="col-xs-3">
                                <span class="widget-icon">
                                    <i class="glyphicon glyphicon-glyph-briefcase"></i>
                                </span>
                    </div>
                    <div class="col-xs-9">
                        <h6 class="no-margin">Celkem ve smlouvě za tento měsíc</h6>
                        <p class="h2 no-margin fw-normal">{$order_price|number:0:',':'.'} Kč</p>
                    </div>
                </div>
                <div class="row">
                    <div class="col-xs-9">
                        <h6 class="no-margin">Největší smlouva v měsíci</h6>
                        <p class="value5">{if $max_order_price}{$max_order_price->client['name']} - {$max_order_price['price']|number:0:',':'.'} Kč {else} Žádná smlouva uzavřena{/if}</p>
                    </div>
                </div>
            </div>
        </section>
    </div>
    <div class="col-lg-4 col-md-2">
        <section class="widget widget-card bg-contractsuccess text-white">
            <div class="widget-body clearfix">
                <div class="row">
                    <div class="col-xs-3">
                                <span class="widget-icon">
                                    <i class="glyphicon glyphicon-glyph-briefcase"></i>
                                </span>
                    </div>
                    <div class="col-xs-6">
                        <h6 class="no-margin">Z toho uhrazené za tento měsíc</h6>
                        <p class="h2 no-margin fw-normal">{$noContract_price|number:0:',':'.'} Kč</p>
                    </div>
                </div>
            </div>
        </section>
    </div>
    <div class="col-lg-12">
        <section class="widget">
            <h5 class="no-margin">Průběžné výsledky -  {="now"|date:'j.n.Y'} - {$contrac|number:0:',':'.'} Kč</h5>
            <button n:if="$user->isInRole('admin') || $user->isInRole('lead')" id="save" class="btn btn-success">Stáhnout graf</button>
            <canvas id="mycanvas" style="height:10vw; width:60vw"></canvas>
        </section>
    </div>
{/if}

Předem díky všem za rady :) Takže abych to shrnul jsem ve fázi kdy mi metoda handleUpdateDashboard vrací to co potřebuji ale jak správně přejít k překreslení v šabloně.Už jsem se díval i na David Matějka – Snippety – proč a jak (ne)fungují ale nějak sem to úplně nepochopil :D

Díky

Editoval jAkErCZ (14. 4. 2020 16:18)

David Matějka
Moderator | 6445
+
0
-

Ty sice v tom handle volas metodu getProjectsToMoth pro ten mesic, ale s vysledkem nic nedelas, takze v renderDefault se ten request zpracuje jako bys tam ten datum neposlal

jAkErCZ
Člen | 322
+
0
-

David Matějka napsal(a):

Ty sice v tom handle volas metodu getProjectsToMoth pro ten mesic, ale s vysledkem nic nedelas, takze v renderDefault se ten request zpracuje jako bys tam ten datum neposlal

No tam to mám řešené takto

public function getProjectsToMoth($user_id, $select, $role ,$date = false){
    if($role){
        if ($date == false){
            $projects = $this->database->table(self::TABLE_NAME)->select($select)->where('MONTH(date) = MONTH(NOW()) AND YEAR(date) = YEAR(NOW())')->fetchAll();
        }else{
            $projects = $this->database->table(self::TABLE_NAME)->select($select)->where('date LIKE ?','%' . $date . '%')->fetchAll();
        }
    }else {
        $projects = $this->database->table(self::TABLE_NAME)->select($select)->where(self::COLUMN_ID_USER, $user_id)->where('MONTH(date) = MONTH(NOW()) AND YEAR(date) = YEAR(NOW())')->fetchAll();
    }
    bdump($projects);
    return $projects;
}

Že pokud datum neobsahuje tak to má default. A až si člověk vybere datum a rok pak to vrátí ty data které tomu odpovídají. Ale jak je správně předat aby se překreslily?

Takto to je asi špatně že?

 public function handleUpdateDashboard(){
    $select = new DateTime($_POST['date']);
    $user_role = $this->getUser()->isInRole('admin') || $this->getUser()->isInRole('lead');
    $all_projects = $this->projectManager->getProjectsToMoth($this->getUser()->id,'price, client_id', $user_role, $select->format('Y-m'));
    if ($this->isAjax()){
        bdump($all_projects);
        $this->redrawControl('cont');
    }else{
        $this->flashMessage('Nefunguje',self::MSG_ERROR);
    }
    $this->terminate();
}

bdump mi data vrací ale už nepřekreslí.

Editoval jAkErCZ (14. 4. 2020 16:50)

CZechBoY
Člen | 3608
+
0
-

V handle metode si posli data do sablony a melo by to snad fungovat.

jAkErCZ
Člen | 322
+
0
-

CZechBoY napsal(a):

V handle metode si posli data do sablony a melo by to snad fungovat.

Ok, myslíš nějak takto?

    public function handleUpdateDashboard(){
        $select = new DateTime($_POST['date']);
        $user_role = $this->getUser()->isInRole('admin') || $this->getUser()->isInRole('lead');
        $all_projects = $this->projectManager->getProjectsToMoth($this->getUser()->id,'price, client_id', $user_role, $select->format('Y-m'));
        if ($this->isAjax()){
$this->template->all_projects = $all_projects;
            bdump($all_projects);
            $this->redrawControl('cont');
        }else{
            $this->flashMessage('Nefunguje',self::MSG_ERROR);
        }
        $this->terminate();
    }

Jelikož v té metodě renderDefault mám nějaké funkce a ty si pak předávám do šablony…

Kamil Valenta
Člen | 822
+
+2
-

Proč ten request nenecháš doběhnout a ukončuješ ho v handlu terminate()?

jAkErCZ
Člen | 322
+
0
-

kamil_v napsal(a):

Proč ten request nenecháš doběhnout a ukončuješ ho v handlu terminate()?

Dobře, teď jsem to vyzkoušel můj výsledek takto:

public function handleUpdateDashboard(){
    $select = new DateTime($_POST['date']);
    $user_role = $this->getUser()->isInRole('admin') || $this->getUser()->isInRole('lead');
    $all_projects = $this->projectManager->getProjectsToMoth($this->getUser()->id,'price, client_id', $user_role, $select->format('Y-m'));
    if ($this->isAjax()){
        $this->template->all_projects = $all_projects;
        bdump($all_projects);
        $this->redrawControl('cont');
    }else{
        $this->flashMessage('Nefunguje',self::MSG_ERROR);
    }
}

My do dump metody vrací daný měsíc ale za boha se mi to nechce překreslit v šabloně.

Takže jak v render metodě kde pracuji také s getProjectsToMoth ale v defaultu tudíž to vrací aktuální měsíc dosadit data z handleUpdateDashboard které se mi v šabloně default překreslí.

David Matějka
Moderator | 6445
+
+1
-

handle se provadi pred render, takze napriklad muzes nastavit clenskou promennou pro ten render. pripadne si v renderDefault primo sahnout na tu hodnotu date

jAkErCZ
Člen | 322
+
0
-

David Matějka napsal(a):

handle se provadi pred render, takze napriklad muzes nastavit clenskou promennou pro ten render. pripadne si v renderDefault primo sahnout na tu hodnotu date

Super díky takové nakopnutí jsem potřeboval :)

Vyřešeno:

public function handleUpdateDashboard(){
      $select = new DateTime($_POST['date']);
      if ($this->isAjax()){
          $this->template->date = $select->format('Y-m');
          $this->redrawControl('cont');
      }else{
          $this->flashMessage('Nefunguje',self::MSG_ERROR);
      }
  }

A metoda renderDefault($date)

Děkuji za pomoc :)

dakur
Člen | 493
+
+1
-

@jAkErCZ Bezpečnější než $_POST['date'] je brát to přes $this->getParameter('date').

Anebo, pokud bys to chtěl ještě lépe, tak:

private DateTime $date;

public function actionDefault(string $date): void
{
  $this->date = new DateTime($date);
}

public function handleUpdateDashboard(): void
{
  if ($this->isAjax()) {
    $this->template->date = $this->date->format('Y-m');
  }
  // ...
}

public function renderDefault(string $date): void
{
  // již nepracuji s $date, ale s $this->date
}

Lepší je to v tom, že si na jednom místě (hned na začátku v action) převedeš generický „string“ na typově ošetřený DateTime a pak už pracuješ jen s ním.

Editoval dakur (15. 4. 2020 14:16)