# Next Actions

## コードフォーマットを実行する

複数人で開発する場合には、全体の品質を保つために、各々が好きなスタイルでコードを書くことを避けるべきです。

{% hint style="success" %}
コードフォーマットツールのデファクトスタンダードである [**Prettier**](https://prettier.io/) を利用し、各ファイルが統一されたフォーマットに修正されることを確認しましょう。
{% endhint %}

ルートディレクトリに `.prettierrc` ファイルを新規作成し、次のコードをコピペします。

{% tabs %}
{% tab title="JSON" %}
{% code title=".prettierrc" %}

```javascript
{
  "printWidth": 80,
  "tabWidth": 2,
  "useTabs": false,
  "semi": true,
  "singleQuote": true,
  "quoteProps": "as-needed",
  "jsxSingleQuote": false,
  "trailingComma": "none",
  "bracketSpacing": true,
  "jsxBracketSameLine": false,
  "arrowParens": "always",
  "requirePragma": false,
  "insertPragma": false,
  "proseWrap": "preserve",
  "htmlWhitespaceSensitivity": "css",
  "endOfLine": "lf",
  "overrides": [
    {
      "files": "*.html",
      "options": { "parser": "lwc" }
    }
  ]
}
```

{% endcode %}
{% endtab %}
{% endtabs %}

`package.json` の `scripts` に `prettier` コマンドを追加します。

{% tabs %}
{% tab title="JSON" %}
{% code title="package.json" %}

```javascript
...

"scripts": {
  "prettier": "prettier \"**/*.{css,html,js,json,md}\" --write --loglevel log",
  "start": "node index.js",
  "test": "node test.js"
},

...
```

{% endcode %}
{% endtab %}
{% endtabs %}

`prettier` をローカルにインストールし、実行します。

{% tabs %}
{% tab title="Console" %}

```bash
npm install --save-dev prettier

npm run prettier

```

{% endtab %}
{% endtabs %}

それぞれのファイルでコードがどのように修正されたのかを確認します。

![VS Code 画面](/files/-MWI7amgxaQrxuI-gxUZ)

{% hint style="info" %}
以後、コードを変更するたびに Prettier を実行することで均一的なフォーマットを維持することを習慣化しましょう。
{% endhint %}

## 静的コード解析を実行する

コードフォーマットを合わせたら、次はコードの書き方にこだわりましょう。せっかくコードを書くのであれば、先人の叡智が詰まった規約に準拠した書き方をお勧めします。潜在的なバグを事前に潰しておくことにも繋がります。

{% hint style="success" %}
JavaScript の静的コード解析ツールのデファクトスタンダードである [**ESLint**](https://eslint.org/) を利用し、コードが規約に違反していないかどうか確認しましょう。
{% endhint %}

ルートディレクトリに `.eslintrc.json` ファイルを新規作成し、次のコードをコピペします。

{% tabs %}
{% tab title="JSON" %}
{% code title=".eslintrc.json" %}

```javascript
{
  "env": {
    "node": true,
    "commonjs": true,
    "es2021": true
  },
  "extends": "eslint:recommended",
  "parserOptions": {
    "ecmaVersion": 12
  },
  "rules": {}
}

```

{% endcode %}
{% endtab %}
{% endtabs %}

`package.json` の `scripts` に `eslint` コマンドを追加します。

{% tabs %}
{% tab title="JSON" %}
{% code title="package.json" %}

```javascript
...

"scripts": {
  "eslint": "eslint *.js --format html --output-file .reports/eslint.html",
  "prettier": "prettier \"**/*.{css,html,js,json,md}\" --write --loglevel log",
  "start": "node index.js",
  "test": "node test.js"
},

...
```

{% endcode %}
{% endtab %}
{% endtabs %}

`eslint` をローカルにインストールし、実行します。

{% tabs %}
{% tab title="Console" %}

```bash
npm install --save-dev eslint

npm run eslint

```

{% endtab %}
{% endtabs %}

それぞれのファイルでコードがどのような警告が表示されるのかを確認します。

![VS Code 画面](/files/-MWIIIsy3x1lbDidWk7R)

また、`.reports` フォルダ内に生成されている `eslint.html` をブラウザで開くと、警告を一覧表示することができます。

![ESLint Report (HTML)](/files/-MWIIZw-4MSkeZ81cRn5)

コードを修正し、警告が消えたことを確認します。

![VS Code 画面](/files/-MWIM0Er-e4GTUrEcASN)

![ESLint Report (HTML)](/files/-MWIMIhV1NBls1CvNOqC)

{% hint style="info" %}
以後、コードを変更するたびに ESLint を実行することで警告の有無を確認し、コードを修正することを習慣化しましょう。なお、コードを修正せずに警告だけを消す方法もありますが、可能な限りコードを修正するようにしましょう。
{% endhint %}

## Lightning Design System を適用する

今回のチュートリアルで作成された画面はとてもシンプルですので、Salesforce の標準的なスタイルを適用してみましょう。

{% hint style="success" %}
もっと詳しく知りたい場合は、公式のチュートリアルを試してみてください。

<https://www.lightningdesignsystem.com/platforms/heroku/>
{% endhint %}

Salesforce Lightning Design System (SLDS) を npm 経由でダウンロードし、`public/assets/` 配下にコピーします。

{% tabs %}
{% tab title="Console" %}

```
npm install @salesforce-ux/design-system --save-dev

cp -r node_modules/@salesforce-ux/design-system/assets/ public/assets/

```

{% endtab %}
{% endtabs %}

SLDS を適用するために、`views/partials/header.ejs` の最下部にコードを追加します。

{% hint style="warning" %}
`views/pages/db.ejs` に追加すると、表示がずれてしまうので注意です。&#x20;
{% endhint %}

{% tabs %}
{% tab title="HTML" %}
{% code title="header.ejs" %}

```markup
<title>Node.js Getting Started on Heroku</title>
<link rel="stylesheet" type="text/css" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script type="text/javascript" src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
<link rel="stylesheet" type="text/css" href="/stylesheets/main.css" />
<link rel="stylesheet" type="text/css" href="/assets/styles/salesforce-lightning-design-system.css" />

```

{% endcode %}
{% endtab %}
{% endtabs %}

`views/pages/db.ejs` のコードを修正します。長いので、コピペしてください。

{% hint style="info" %}
今回利用するコンポーネントは Cards と Data Tables です。詳しくは公式サイトを参照してください。

* [Cards - With no footer](https://www.lightningdesignsystem.com/components/cards/#With-no-footer)
* [Data Tables - Actionable mode - Column sorting and row selection(s)](https://www.lightningdesignsystem.com/components/data-tables/#Actionable-mode-Column-sorting-and-row-selection\(s\))
  {% endhint %}

{% tabs %}
{% tab title="HTML" %}
{% code title="db.ejs" %}

```markup
<!DOCTYPE html>
<html>
<head>
  <%- include ("../partials/header.ejs") %>
</head>

<body>

<%- include ("../partials/nav.ejs") %>

<div class="container">
<!-- <h2>Database Results</h2> -->
<article class="slds-card">
  <div class="slds-card__header slds-grid">
    <header class="slds-media slds-media_center slds-has-flexi-truncate">
      <div class="slds-media__figure">
        <span class="slds-icon_container slds-icon-standard-account" title="account">
          <svg class="slds-icon slds-icon_small" aria-hidden="true">
            <use xlink:href="/assets/icons/standard-sprite/svg/symbols.svg#account"></use>
          </svg>
          <span class="slds-assistive-text">Database Results</span>
        </span>
      </div>
      <div class="slds-media__body">
        <h2 class="slds-card__header-title">
          <a href="#" class="slds-card__header-link slds-truncate" title="Database Results">
            <span>Database Results</span>
          </a>
        </h2>
      </div>
    </header>
  </div>
  <div class="slds-card__body slds-card__body_inner">
    <!-- <ul>
      <% results.forEach(function(r) { %>
          <li><%= r.id %> - <%= r.name %></li>
      <% }); %>
    </ul> -->
    <table aria-multiselectable="true" class="slds-table slds-table_bordered slds-table_fixed-layout slds-table_resizable-cols" role="grid">
      <thead>
        <tr class="slds-line-height_reset">
          <th class="slds-text-align_right" scope="col" style="width:3.25rem">
            <span id="column-group-header" class="slds-assistive-text">Choose a row</span>
            <div class="slds-th__action slds-th__action_form">
              <div class="slds-checkbox">
                <input type="checkbox" name="options" id="checkbox-unique-id-1465" value="checkbox-unique-id-1465" tabindex="0" aria-labelledby="check-select-all-label column-group-header" />
                <label class="slds-checkbox__label" for="checkbox-unique-id-1465" id="check-select-all-label">
                  <span class="slds-checkbox_faux"></span>
                  <span class="slds-form-element__label slds-assistive-text">Select All</span>
                </label>
              </div>
            </div>
          </th>
          <th aria-label="id" aria-sort="none" class="slds-is-resizable slds-is-sortable" scope="col">
            <a class="slds-th__action slds-text-link_reset" href="#" role="button" tabindex="0">
              <span class="slds-assistive-text">Sort by: </span>
              <div class="slds-grid slds-grid_vertical-align-center slds-has-flexi-truncate">
                <span class="slds-truncate" title="id">id</span>
                <span class="slds-icon_container slds-icon-utility-arrowdown">
                  <svg class="slds-icon slds-icon-text-default slds-is-sortable__icon " aria-hidden="true">
                    <use xlink:href="/assets/icons/utility-sprite/svg/symbols.svg#arrowdown"></use>
                  </svg>
                </span>
              </div>
            </a>
            <div class="slds-resizable">
              <input type="range" aria-label="id column width" class="slds-resizable__input slds-assistive-text" id="cell-resize-handle-2668" max="1000" min="20" tabindex="0" />
              <span class="slds-resizable__handle">
                <span class="slds-resizable__divider"></span>
              </span>
            </div>
          </th>
          <th aria-label="name" aria-sort="none" class="slds-is-resizable slds-is-sortable" scope="col">
            <a class="slds-th__action slds-text-link_reset" href="#" role="button" tabindex="0">
              <span class="slds-assistive-text">Sort by: </span>
              <div class="slds-grid slds-grid_vertical-align-center slds-has-flexi-truncate">
                <span class="slds-truncate" title="name">name</span>
                <span class="slds-icon_container slds-icon-utility-arrowdown">
                  <svg class="slds-icon slds-icon-text-default slds-is-sortable__icon " aria-hidden="true">
                    <use xlink:href="/assets/icons/utility-sprite/svg/symbols.svg#arrowdown"></use>
                  </svg>
                </span>
              </div>
            </a>
            <div class="slds-resizable">
              <input type="range" aria-label="name column width" class="slds-resizable__input slds-assistive-text" id="cell-resize-handle-2669" max="1000" min="20" tabindex="0" />
              <span class="slds-resizable__handle">
                <span class="slds-resizable__divider"></span>
              </span>
            </div>
          </th>
          <th class="" scope="col" style="width:3.25rem">
            <div class="slds-truncate slds-assistive-text" title="Actions">Actions</div>
          </th>
        </tr>
      </thead>
      <tbody>
        <% results.forEach(function(r) { %>
          <tr aria-selected="false" class="slds-hint-parent">
            <td class="slds-text-align_right" role="gridcell">
              <div class="slds-checkbox">
                <input type="checkbox" name="options" id="checkbox-<%= r.id %>" value="checkbox-<%= r.id %>" tabindex="0" aria-labelledby="check-button-label-01 column-group-header" />
                <label class="slds-checkbox__label" for="checkbox-<%= r.id %>" id="check-button-label-<%= r.id %>">
                <span class="slds-checkbox_faux"></span>
                <span class="slds-form-element__label slds-assistive-text">Select item <%= r.id %></span>
              </label>
            </div>
          </td>
          <th scope="row">
            <div class="slds-truncate" title="id">
              <a href="#" tabindex="0"><%= r.id %></a>
            </div>
          </th>
          <td role="gridcell">
            <div class="slds-truncate" title="name"><%= r.name %></div>
          </td>
          <td role="gridcell">
            <button class="slds-button slds-button_icon slds-button_icon-border-filled slds-button_icon-x-small" aria-haspopup="true" tabindex="0" title="More actions">
              <svg class="slds-button__icon slds-button__icon_hint slds-button__icon_small" aria-hidden="true">
                <use xlink:href="/assets/icons/utility-sprite/svg/symbols.svg#down"></use>
              </svg>
              <span class="slds-assistive-text">More actions</span>
            </button>
          </td>
        </tr>
        <% }); %>
      </tbody>
    </table>
  </div>
  <footer class="slds-card__footer"></footer>
</article>
</div>

</body>
</html>

```

{% endcode %}
{% endtab %}
{% endtabs %}

表示するデータを増やすために、Heroku Postgres にテストデータを複数件インサートします。

{% tabs %}
{% tab title="Console" %}

```
heroku pg:psql

insert into test_table values (2, 'hello world');
insert into test_table values (3, 'hello heroku');
insert into test_table values (4, 'hello salesforce');
insert into test_table values (5, 'hello ohana');

exit

```

{% endtab %}
{% endtabs %}

Heroku アプリをローカルで実行します。

{% tabs %}
{% tab title="Console" %}

```
heroku local web

```

{% endtab %}
{% endtabs %}

<http://localhost:5000/db> にアクセスして、画面のスタイルが変わっていることを確認しましょう。

#### 変更前

![変更前](/files/-MWIQrVzf0CIkeJs7STM)

#### 変更後

![変更後](/files/-MWImCX4rbBeU-wl-3lT)

確認が終わったら、Heroku にデプロイして終了です。

{% tabs %}
{% tab title="Console" %}

```
git add .
git commit -m "Lv.1 completed"
git push heroku main

```

{% endtab %}
{% endtabs %}

一通りの手順はわかりましたか？他の画面についても、色々試してみてください。


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://takahitomiyamoto.gitbook.io/heroku-basic/toc/level-1/next-actions.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
